Index: sys/netinet/in.c =================================================================== --- sys/netinet/in.c +++ sys/netinet/in.c @@ -242,21 +242,37 @@ return (EADDRNOTAVAIL); /* - * For SIOCGIFADDR, pick the first address. For the rest of - * ioctls, try to find specified address. + * Find address for this interface, if it exists. If an + * address was specified, find that one instead of the + * first one on the interface, if possible. */ 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) + if (addr->sin_addr.s_addr == INADDR_ANY) break; if (ia->ia_addr.sin_addr.s_addr == addr->sin_addr.s_addr) break; } - - if (ifa == NULL) { + /* + * Historical behavior: return the first address that the + * calling thread have access to, if we didn't have any + * match. + */ + if (ia == NULL) { + TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { + if (ifa->ifa_addr->sa_family != AF_INET) + continue; + if (prison_check_ip4(td->td_ucred, + &(((struct in_ifaddr *)ifa)->ia_addr.sin_addr)) != 0) + continue; + ia = (struct in_ifaddr *)ifa; + break; + } + } + if (ia == NULL) { IF_ADDR_RUNLOCK(ifp); return (EADDRNOTAVAIL); }