From owner-svn-src-all@freebsd.org Mon Aug 3 06:52:43 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9F9B199CDFF; Mon, 3 Aug 2015 06:52:43 +0000 (UTC) (envelope-from ermal.luci@gmail.com) Received: from mail-yk0-x22b.google.com (mail-yk0-x22b.google.com [IPv6:2607:f8b0:4002:c07::22b]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 6B9F3D26; Mon, 3 Aug 2015 06:52:43 +0000 (UTC) (envelope-from ermal.luci@gmail.com) Received: by ykdu72 with SMTP id u72so103246074ykd.2; Sun, 02 Aug 2015 23:52:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; bh=yb3ibPIAx9kyT58AeOYJcrxuykd3yFAF5eNUE7pv2vA=; b=P/p2vbAA/pWSKA6a/oGJJePiGpC2cDniwE92XtrZPueISO3/C9t9i0nLV7ZYcSNp0i N78Pem5x8E926iOjlbAB/b+jIu54BJczpMYnadhU1zlfQaZqhOEnxPSr8Qp3yDCDyuAk ybzp7OebRNH9HxgSO7i2Bc1tkdleXHjsW0DZ7z638p/cxG8vrI/tQ64IBtGhKvIoHrij h3InuUyzeatbCdM7ecpUFIQeWWFUHck6uMVeUOOAjd7Whb07inCh+pme1wpFL4hiqwdq 4WQaapVeCrUxgKyXwGh6uph40cQop2nNDYXPk0Kqkj3iaVe2J3MmTcqPgqDBcOLfbsVb +Vug== MIME-Version: 1.0 X-Received: by 10.129.45.68 with SMTP id t65mr19133849ywt.152.1438584762390; Sun, 02 Aug 2015 23:52:42 -0700 (PDT) Sender: ermal.luci@gmail.com Received: by 10.129.83.139 with HTTP; Sun, 2 Aug 2015 23:52:42 -0700 (PDT) In-Reply-To: <20150802184021.GB59626@raichu> References: <201507291804.t6TI42iH065403@repo.freebsd.org> <20150802184021.GB59626@raichu> Date: Mon, 3 Aug 2015 08:52:42 +0200 X-Google-Sender-Auth: S4oAVOtBo0MjtJpT9dYOYvQ-tIg Message-ID: Subject: Re: svn commit: r286028 - head/sys/netinet From: =?UTF-8?Q?Ermal_Lu=C3=A7i?= To: Mark Johnston Cc: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.20 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 03 Aug 2015 06:52:43 -0000 On Sun, Aug 2, 2015 at 8:40 PM, Mark Johnston wrote: > On Wed, Jul 29, 2015 at 06:04:02PM +0000, Ermal Lu=C3=A7i wrote: > > Author: eri > > Date: Wed Jul 29 18:04:01 2015 > > New Revision: 286028 > > URL: https://svnweb.freebsd.org/changeset/base/286028 > > > > Log: > > ip_output normalization and fixes > > > > ip_output has a big chunk of code used to handle special cases with > pfil consumers which also forces a reloop on it. > > Gather all this code together to make it readable and properly handle > the reloop cases. > > > > Some of the issues identified: > > > > M_IP_NEXTHOP is not handled properly in existing code. > > route reference leaking is possible with in FIB number change > > route flags checking is not consistent in the function > > > > Differential Revision: https://reviews.freebsd.org/D3022 > > Reviewed by: gnn > > Approved by: gnn(mentor) > > MFC after: 4 weeks > > > > Modified: > > head/sys/netinet/ip_output.c > > > > Modified: head/sys/netinet/ip_output.c > > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D > > --- head/sys/netinet/ip_output.c Wed Jul 29 17:59:13 2015 > (r286027) > > +++ head/sys/netinet/ip_output.c Wed Jul 29 18:04:01 2015 > (r286028) > > @@ -106,6 +106,94 @@ static void ip_mloopback > > extern int in_mcast_loop; > > extern struct protosw inetsw[]; > > > > +static inline int > > +ip_output_pfil(struct mbuf *m, struct ifnet *ifp, struct inpcb *inp, > > + struct sockaddr_in *dst, int *fibnum, int *error) > > +{ > > + struct m_tag *fwd_tag =3D NULL; > > + struct in_addr odst; > > + struct ip *ip; > > + > > + ip =3D mtod(m, struct ip *); > > + > > + /* Run through list of hooks for output packets. */ > > + odst.s_addr =3D ip->ip_dst.s_addr; > > + *error =3D pfil_run_hooks(&V_inet_pfil_hook, &m, ifp, PFIL_OUT, i= np); > > + if ((*error) !=3D 0 || m =3D=3D NULL) > > + return 1; /* Finished */ > > + > > This can result in a use-after-free in ip_output() if a pfil hook > consumes the first mbuf in the chain. This happens for example when ipfw > nat is in use: m_megapullup() copies the input packet into a single > cluster, which is returned above. However, ip_output() will continue to > reference the original mbuf chain. > > The patch below fixes the problem for me. > > Good catch just push it in. Ok for me. > Thanks, > -Mark > > diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c > index 0790777..086a8c9 100644 > --- a/sys/netinet/ip_output.c > +++ b/sys/netinet/ip_output.c > @@ -107,18 +107,21 @@ extern int in_mcast_loop; > extern struct protosw inetsw[]; > > static inline int > -ip_output_pfil(struct mbuf *m, struct ifnet *ifp, struct inpcb *inp, > - struct sockaddr_in *dst, int *fibnum, int *error) > +ip_output_pfil(struct mbuf **mp, struct ifnet *ifp, struct inpcb *inp, > + struct sockaddr_in *dst, int *fibnum, int *error) > { > struct m_tag *fwd_tag =3D NULL; > + struct mbuf *m; > struct in_addr odst; > struct ip *ip; > > + m =3D *mp; > ip =3D mtod(m, struct ip *); > > /* Run through list of hooks for output packets. */ > odst.s_addr =3D ip->ip_dst.s_addr; > - *error =3D pfil_run_hooks(&V_inet_pfil_hook, &m, ifp, PFIL_OUT, i= np); > + *error =3D pfil_run_hooks(&V_inet_pfil_hook, mp, ifp, PFIL_OUT, i= np); > + m =3D *mp; > if ((*error) !=3D 0 || m =3D=3D NULL) > return 1; /* Finished */ > > @@ -552,7 +555,7 @@ sendit: > > /* Jump over all PFIL processing if hooks are not active. */ > if (PFIL_HOOKED(&V_inet_pfil_hook)) { > - switch (ip_output_pfil(m, ifp, inp, dst, &fibnum, &error)= ) > { > + switch (ip_output_pfil(&m, ifp, inp, dst, &fibnum, > &error)) { > case 1: /* Finished */ > goto done; > > --=20 Ermal