Subject: Re: possible kernel NAT-T bug
To: None <tech-net@netbsd.org>
From: Christos Zoulas <christos@astron.com>
List: tech-net
Date: 12/06/2005 13:46:09
In article <20051206090124.GX18416@NetBSD.org>,
Emmanuel Dreyfus  <manu@netbsd.org> wrote:
>Hi
>
>When the kernel receive an ESP over UDP packet, here is the code path:
>udp_input() -> udp4_realinput() - udp4_espinudp()
>
>Each function sends struct mbuf *m to the next one. But in udp4_espinudp(), 
>we have:
>
>        if (m->m_len < minlen) {
>                if ((m = m_pullup(m, minlen)) == NULL) {
>                        printf("udp4_espinudp: m_pullup failed\n");
>                        return 0;
>                }
>        }
>
>Two problems can arise
>1) m_pullup relocates trhe mbuf, which changes m address. When returning in 
>udp4_realinput(), the local value of m will be invalid, thus leading to a 
>panic.
>
>2) m_pullup fails and sets m to NULL. udp4_realinput() idea of m is still non
>NULL and it will try to deallocate it, thus getting a panic.
>
>I'm not sure of the right fix. If I have udp4_realinput() giving a 
>struct mbuf ** to udp4_espinudp(), it will see the change, but udp_input()
>will not. 
>
>If I duplicate the mbuf, I get a performance hit.
>
>What is the proper fix? 

Can't the two internal functions return an mbuf instead of int?

christos