[PATCH] Use of unreferenced ifa in in6
Bjoern A. Zeeb
bz at freebsd.org
Tue Jan 3 17:35:36 UTC 2012
On 23. Dec 2011, at 20:08 , John Baldwin wrote:
> The code to handle the SIOCGLIFADDR and SIOCDLIFADDR ioctls in
> in6_lifaddr_ioctl() does not grab a reference to an ifnet address structure
> that it uses after dropping the IF_ADDR_LOCK(). Based on other code that uses
> a similar pattern of finding an ifa while under the lock and then using it
> after dropping the lock, I believe it should be acquiring a reference on the
> ifa and then dropping that reference when it is done using the ifa. This
> (untested) patch should fix this I believe:
I almost assume it's been tested by now. From reading it looks right.
/bz
> Index: in6.c
> ===================================================================
> --- 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 != 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 = sa6_recoverscope(
> (struct sockaddr_in6 *)&iflr->addr);
> - if (error != 0)
> + if (error != 0) {
> + ifa_free(ifa);
> return (error);
> + }
>
> if ((ifp->if_flags & IFF_POINTOPOINT) != 0) {
> bcopy(&ia->ia_dstaddr, &iflr->dstaddr,
> ia->ia_dstaddr.sin6_len);
> error = sa6_recoverscope(
> (struct sockaddr_in6 *)&iflr->dstaddr);
> - if (error != 0)
> + if (error != 0) {
> + ifa_free(ifa);
> return (error);
> + }
> } else
> bzero(&iflr->dstaddr, sizeof(iflr->dstaddr));
>
> @@ -1796,6 +1802,7 @@ in6_lifaddr_ioctl(struct socket *so, u_long cmd, c
> in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL);
>
> iflr->flags = ia->ia6_flags; /* XXX */
> + ifa_free(ifa);
>
> return 0;
> } else {
> @@ -1819,6 +1826,7 @@ in6_lifaddr_ioctl(struct socket *so, u_long cmd, c
> ia->ia_prefixmask.sin6_len);
>
> ifra.ifra_flags = ia->ia6_flags;
> + ifa_free(ifa);
> return in6_control(so, SIOCDIFADDR_IN6, (caddr_t)&ifra,
> ifp, td);
> }
>
>
> --
> John Baldwin
--
Bjoern A. Zeeb You have to have visions!
It does not matter how good you are. It matters what good you do!
More information about the freebsd-net
mailing list