Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Jan 2012 17:35:30 +0000
From:      "Bjoern A. Zeeb" <bz@freebsd.org>
To:        John Baldwin <jhb@freebsd.org>
Cc:        net@freebsd.org
Subject:   Re: [PATCH] Use of unreferenced ifa in in6
Message-ID:  <F6ADC1D1-6C6B-4F62-A38C-853CBF127A83@freebsd.org>
In-Reply-To: <201112231508.52861.jhb@freebsd.org>
References:  <201112231508.52861.jhb@freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

On 23. Dec 2011, at 20:08 , John Baldwin wrote:

> The code to handle the SIOCGLIFADDR and SIOCDLIFADDR ioctls in=20
> in6_lifaddr_ioctl() does not grab a reference to an ifnet address =
structure=20
> that it uses after dropping the IF_ADDR_LOCK().  Based on other code =
that uses=20
> a similar pattern of finding an ifa while under the lock and then =
using it=20
> after dropping the lock, I believe it should be acquiring a reference =
on the=20
> ifa and then dropping that reference when it is done using the ifa.  =
This=20
> (untested) patch should fix this I believe:

I almost assume it's been tested by now.  =46rom reading it looks right.

/bz

> Index: in6.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
> --- in6.c	(revision 228777)
> +++ in6.c	(working copy)
> @@ -1767,6 +1767,8 @@ in6_lifaddr_ioctl(struct socket *so, u_long cmd, =
c
> 			if (IN6_ARE_ADDR_EQUAL(&candidate, &match))
> 				break;
> 		}
> +		if (ifa !=3D NULL)
> +			ifa_ref(ifa);
> 		IF_ADDR_UNLOCK(ifp);
> 		if (!ifa)
> 			return EADDRNOTAVAIL;
> @@ -1779,16 +1781,20 @@ in6_lifaddr_ioctl(struct socket *so, u_long =
cmd, c
> 			bcopy(&ia->ia_addr, &iflr->addr, =
ia->ia_addr.sin6_len);
> 			error =3D sa6_recoverscope(
> 			    (struct sockaddr_in6 *)&iflr->addr);
> -			if (error !=3D 0)
> +			if (error !=3D 0) {
> +				ifa_free(ifa);
> 				return (error);
> +			}
>=20
> 			if ((ifp->if_flags & IFF_POINTOPOINT) !=3D 0) {
> 				bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
> 				    ia->ia_dstaddr.sin6_len);
> 				error =3D sa6_recoverscope(
> 				    (struct sockaddr_in6 =
*)&iflr->dstaddr);
> -				if (error !=3D 0)
> +				if (error !=3D 0) {
> +					ifa_free(ifa);
> 					return (error);
> +				}
> 			} else
> 				bzero(&iflr->dstaddr, =
sizeof(iflr->dstaddr));
>=20
> @@ -1796,6 +1802,7 @@ in6_lifaddr_ioctl(struct socket *so, u_long cmd, =
c
> 			    in6_mask2len(&ia->ia_prefixmask.sin6_addr, =
NULL);
>=20
> 			iflr->flags =3D ia->ia6_flags;	/* XXX */
> +			ifa_free(ifa);
>=20
> 			return 0;
> 		} else {
> @@ -1819,6 +1826,7 @@ in6_lifaddr_ioctl(struct socket *so, u_long cmd, =
c
> 			    ia->ia_prefixmask.sin6_len);
>=20
> 			ifra.ifra_flags =3D ia->ia6_flags;
> +			ifa_free(ifa);
> 			return in6_control(so, SIOCDIFADDR_IN6, =
(caddr_t)&ifra,
> 			    ifp, td);
> 		}
>=20
>=20
> --=20
> John Baldwin

--=20
Bjoern A. Zeeb                                 You have to have visions!
   It does not matter how good you are. It matters what good you do!




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?F6ADC1D1-6C6B-4F62-A38C-853CBF127A83>