diff options
author | glebius <glebius@FreeBSD.org> | 2013-12-29 22:20:06 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2013-12-29 22:20:06 +0000 |
commit | 5bc18c5e57d34348235997040ef215a071cde899 (patch) | |
tree | 55ee59d799f2a6efa15d29ae06130e7d86a925e3 /sys/netinet | |
parent | 0d338d1a7e159e9f425f9be2b5e5b8ffe9ce2433 (diff) | |
download | FreeBSD-src-5bc18c5e57d34348235997040ef215a071cde899.zip FreeBSD-src-5bc18c5e57d34348235997040ef215a071cde899.tar.gz |
Fix couple of bugs from r257692 related to scan of address list on
an interface:
- in in_control() skip over not AF_INET addresses.
- in in_aifaddr_ioctl() and in_difaddr_ioctl() do correct check
of address family, w/o accessing memory beyond struct ifaddr.
Sponsored by: Nginx, Inc.
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/in.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 4331e82..8b7adaf 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -247,6 +247,8 @@ in_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, */ IF_ADDR_RLOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { + if (ifa->ifa_addr->sa_family != AF_INET) + continue; ia = (struct in_ifaddr *)ifa; if (cmd == SIOCGIFADDR || addr->sin_addr.s_addr == INADDR_ANY) break; @@ -338,11 +340,12 @@ in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td) ia = NULL; IF_ADDR_RLOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - struct in_ifaddr *it = ifatoia(ifa); + struct in_ifaddr *it; - if (it->ia_addr.sin_family != AF_INET) + if (ifa->ifa_addr->sa_family != AF_INET) continue; + it = (struct in_ifaddr *)ifa; iaIsFirst = false; if (it->ia_addr.sin_addr.s_addr == addr->sin_addr.s_addr && prison_check_ip4(td->td_ucred, &addr->sin_addr) == 0) @@ -530,11 +533,12 @@ in_difaddr_ioctl(caddr_t data, struct ifnet *ifp, struct thread *td) ia = NULL; IF_ADDR_WLOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - struct in_ifaddr *it = ifatoia(ifa); + struct in_ifaddr *it; - if (it->ia_addr.sin_family != AF_INET) + if (ifa->ifa_addr->sa_family != AF_INET) continue; + it = (struct in_ifaddr *)ifa; if (deleteAny && ia == NULL && (td == NULL || prison_check_ip4(td->td_ucred, &it->ia_addr.sin_addr) == 0)) ia = it; |