diff options
author | jhb <jhb@FreeBSD.org> | 2012-01-04 13:26:56 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2012-01-04 13:26:56 +0000 |
commit | bae1448c5ef15914b698932090561fc24f630018 (patch) | |
tree | 1f5dc4bb4da5332489b4493b912760fa1312cbf9 /sys/netinet | |
parent | 90b391fc12fb48e929ba33df621f29468b15a3b2 (diff) | |
download | FreeBSD-src-bae1448c5ef15914b698932090561fc24f630018.zip FreeBSD-src-bae1448c5ef15914b698932090561fc24f630018.tar.gz |
In the handling of the SIOC[DG]LIFADDR icotls in in_lifaddr_ioctl(), add
missing interface address list locking and grab a reference on the
matching interface address after dropping the lock while it is used to
avoid a potential use after free.
Reviewed by: bz
MFC after: 1 week
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/in.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 741f7ac..fcaeef8 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -784,6 +784,7 @@ in_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data, } } + IF_ADDR_LOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { if (ifa->ifa_addr->sa_family != AF_INET) continue; @@ -794,6 +795,9 @@ in_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data, if (candidate.s_addr == match.s_addr) break; } + if (ifa != NULL) + ifa_ref(ifa); + IF_ADDR_UNLOCK(ifp); if (ifa == NULL) return (EADDRNOTAVAIL); ia = (struct in_ifaddr *)ifa; @@ -812,6 +816,7 @@ in_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data, in_mask2len(&ia->ia_sockmask.sin_addr); iflr->flags = 0; /*XXX*/ + ifa_free(ifa); return (0); } else { @@ -830,6 +835,7 @@ in_lifaddr_ioctl(struct socket *so, u_long cmd, caddr_t data, } bcopy(&ia->ia_sockmask, &ifra.ifra_dstaddr, ia->ia_sockmask.sin_len); + ifa_free(ifa); return (in_control(so, SIOCDIFADDR, (caddr_t)&ifra, ifp, td)); |