On Thursday 20 January 2011, Mike Belopuhov wrote:
> On Thu, Jan 20, 2011 at 10:31 +0200, Gregory Edigarov wrote:
> > --- interrupt ---
> > end trace frame: 0x0, count: 245
> > 0x8:
> > End of stack trace.
> > pppoe0: received unexpected PADO
> > pppoe0: chap failure
> > pppoe: GENERIC ERROR: RP-PPPoE: Child pppd process terminated
> > pppoe0: received unexpected PADO
> > pppoe0: chap failure
> > pppoe: GENERIC ERROR: RP-PPPoE: Child pppd process terminated
> > pppoe0: received unexpected PADO
> > pppoe0: chap failure
> > pppoe: GENERIC ERROR: RP-PPPoE: Child pppd process terminated
> > pppoe0: received unexpected PADO
> > splassert: assertwaitok: want -1 have 1
> > Starting stack trace...
> > assertwaitok() at assertwaitok+0x1c
> > pool_get() at pool_get+0x95
> > ifa_item_insert() at ifa_item_insert+0x35
> > ifa_add() at ifa_add+0x43
> > in_ifinit() at in_ifinit+0x16f
> > sppp_set_ip_addrs() at sppp_set_ip_addrs+0x107
> > sppp_ipcp_tlu() at sppp_ipcp_tlu+0x4e
> > sppp_input() at sppp_input+0x594
> > pppoeintr() at pppoeintr+0x41d
> > netintr() at netintr+0x97
> > softintr_dispatch() at softintr_dispatch+0x5d
> > Xsoftnet() at Xsoftnet+0x28
> > --- interrupt ---
> > end trace frame: 0x0, count: 245
> > 0x8:
> > End of stack trace.
>
> seems like this is the only plausible way to fix it:
>
> Index: net/if.c
> ===================================================================
> RCS file: /home/cvs/src/sys/net/if.c,v
> retrieving revision 1.231
> diff -u -p -r1.231 if.c
> --- net/if.c 29 Nov 2010 19:38:59 -0000 1.231
> +++ net/if.c 20 Jan 2011 11:11:53 -0000
> @@ -2213,7 +2213,7 @@ ifa_item_insert(struct sockaddr *sa, str
> {
> struct ifaddr_item *ifai, *p;
>
> - ifai = pool_get(&ifaddr_item_pl, PR_WAITOK);
> + ifai = pool_get(&ifaddr_item_pl, PR_NOWAIT);
> ifai->ifai_addr = sa;
> ifai->ifai_ifa = ifa;
> ifai->ifai_rdomain = ifp->if_rdomain;
pool_get() with PR_NOWAIT... and then not checking the return value? That's
got null pointer dereference written all over it... :)
However, the bigger problem is what can you then do if the pool_get() fails?
This then results in the interface address not being allocated and in most
cases there is no way to propagate/handle the error. The solution here is to
add the interface address from process context and not from interrupt
context.
--
"Stop assuming that systems are secure unless demonstrated insecure;
start assuming that systems are insecure unless designed securely."
- Bruce Schneier