summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2012-01-04 13:26:56 +0000
committerjhb <jhb@FreeBSD.org>2012-01-04 13:26:56 +0000
commitbae1448c5ef15914b698932090561fc24f630018 (patch)
tree1f5dc4bb4da5332489b4493b912760fa1312cbf9 /sys/netinet
parent90b391fc12fb48e929ba33df621f29468b15a3b2 (diff)
downloadFreeBSD-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.c6
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));
OpenPOWER on IntegriCloud