diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2015-11-20 11:53:37 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2015-11-20 11:53:37 +0000 |
commit | 8dc236f4e4dc42ddbbb6007780e7ebef5f6b24e5 (patch) | |
tree | 1c6be07c6e173c9f2508c6e01e2fa8d684687615 /sys/net/if_spppsubr.c | |
parent | 787fde904cedea37c6595e451ebcb83a66cccff3 (diff) |
avoid a use after enqueue, which is like a use after free.
once you enqueue an mbuf, you no longer own it. therefore you cant
read the length out of it. this reads the length first, then tries
to enq it.
also, call if_start instead of a bare call to the underlying start
routine.
ok mpi@ sthen@
Diffstat (limited to 'sys/net/if_spppsubr.c')
-rw-r--r-- | sys/net/if_spppsubr.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/sys/net/if_spppsubr.c b/sys/net/if_spppsubr.c index 48a1d181ac1..00076fff3d3 100644 --- a/sys/net/if_spppsubr.c +++ b/sys/net/if_spppsubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_spppsubr.c,v 1.146 2015/11/11 01:49:17 dlg Exp $ */ +/* $OpenBSD: if_spppsubr.c,v 1.147 2015/11/20 11:53:36 dlg Exp $ */ /* * Synchronous PPP link level subroutines. * @@ -997,14 +997,15 @@ sppp_cp_send(struct sppp *sp, u_short proto, u_char type, sppp_print_bytes ((u_char*) (lh+1), len); addlog(">\n"); } + + len = m->m_pkthdr.len + sp->pp_framebytes; if (mq_enqueue(&sp->pp_cpq, m) != 0) { - ++ifp->if_oerrors; - m = NULL; + ifp->if_oerrors++; + return; } - if (!(ifp->if_flags & IFF_OACTIVE)) - (*ifp->if_start) (ifp); - if (m != NULL) - ifp->if_obytes += m->m_pkthdr.len + sp->pp_framebytes; + + ifp->if_obytes += len; + if_start(ifp); } /* @@ -4101,14 +4102,15 @@ sppp_auth_send(const struct cp *cp, struct sppp *sp, sppp_print_bytes((u_char*) (lh+1), len); addlog(">\n"); } + + len = m->m_pkthdr.len + sp->pp_framebytes; if (mq_enqueue(&sp->pp_cpq, m) != 0) { - ++ifp->if_oerrors; - m = NULL; + ifp->if_oerrors++; + return; } - if (! (ifp->if_flags & IFF_OACTIVE)) - (*ifp->if_start) (ifp); - if (m != NULL) - ifp->if_obytes += m->m_pkthdr.len + sp->pp_framebytes; + + ifp->if_obytes += len; + if_start(ifp); } /* |