1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-05-31 15:01:17 +03:00
* resolv/res_hconf.c (_res_hconf_reorder_addrs): Fix locking when
	initializing interface list.
This commit is contained in:
Ulrich Drepper 2007-11-23 03:03:59 +00:00
parent 8588312396
commit 5c3a3dba22
2 changed files with 49 additions and 37 deletions

View File

@ -1,5 +1,9 @@
2007-11-22 Ulrich Drepper <drepper@redhat.com> 2007-11-22 Ulrich Drepper <drepper@redhat.com>
[BZ #5375]
* resolv/res_hconf.c (_res_hconf_reorder_addrs): Fix locking when
initializing interface list.
[BZ #5378] [BZ #5378]
* nis/nss_compat/compat-initgroups.c (getgrent_next_nss): Don't * nis/nss_compat/compat-initgroups.c (getgrent_next_nss): Don't
use result of nss_getgrgid_r if nothing was found. For other use result of nss_getgrgid_r if nothing was found. For other

View File

@ -377,9 +377,6 @@ static struct netaddr
} u; } u;
} *ifaddrs); } *ifaddrs);
/* We need to protect the dynamic buffer handling. */
__libc_lock_define_initialized (static, lock);
/* Reorder addresses returned in a hostent such that the first address /* Reorder addresses returned in a hostent such that the first address
is an address on the local subnet, if there is such an address. is an address on the local subnet, if there is such an address.
Otherwise, nothing is changed. Otherwise, nothing is changed.
@ -393,6 +390,8 @@ _res_hconf_reorder_addrs (struct hostent *hp)
int i, j; int i, j;
/* Number of interfaces. */ /* Number of interfaces. */
static int num_ifs = -1; static int num_ifs = -1;
/* We need to protect the dynamic buffer handling. */
__libc_lock_define_initialized (static, lock);
/* Only reorder if we're supposed to. */ /* Only reorder if we're supposed to. */
if ((_res_hconf.flags & HCONF_FLAG_REORDER) == 0) if ((_res_hconf.flags & HCONF_FLAG_REORDER) == 0)
@ -411,8 +410,6 @@ _res_hconf_reorder_addrs (struct hostent *hp)
/* Initialize interface table. */ /* Initialize interface table. */
num_ifs = 0;
/* The SIOCGIFNETMASK ioctl will only work on an AF_INET socket. */ /* The SIOCGIFNETMASK ioctl will only work on an AF_INET socket. */
sd = __socket (AF_INET, SOCK_DGRAM, 0); sd = __socket (AF_INET, SOCK_DGRAM, 0);
if (sd < 0) if (sd < 0)
@ -421,45 +418,56 @@ _res_hconf_reorder_addrs (struct hostent *hp)
/* Get lock. */ /* Get lock. */
__libc_lock_lock (lock); __libc_lock_lock (lock);
/* Get a list of interfaces. */ /* Recheck, somebody else might have done the work by done. */
__ifreq (&ifr, &num, sd); if (num_ifs <= 0)
if (!ifr)
goto cleanup;
ifaddrs = malloc (num * sizeof (ifaddrs[0]));
if (!ifaddrs)
goto cleanup1;
/* Copy usable interfaces in ifaddrs structure. */
for (cur_ifr = ifr, i = 0; i < num; cur_ifr = __if_nextreq (cur_ifr), ++i)
{ {
if (cur_ifr->ifr_addr.sa_family != AF_INET) int new_num_ifs = 0;
continue;
ifaddrs[num_ifs].addrtype = AF_INET; /* Get a list of interfaces. */
ifaddrs[num_ifs].u.ipv4.addr = __ifreq (&ifr, &num, sd);
((struct sockaddr_in *) &cur_ifr->ifr_addr)->sin_addr.s_addr; if (!ifr)
goto cleanup;
if (__ioctl (sd, SIOCGIFNETMASK, cur_ifr) < 0) ifaddrs = malloc (num * sizeof (ifaddrs[0]));
continue; if (!ifaddrs)
goto cleanup1;
ifaddrs[num_ifs].u.ipv4.mask = /* Copy usable interfaces in ifaddrs structure. */
((struct sockaddr_in *) &cur_ifr->ifr_netmask)->sin_addr.s_addr; for (cur_ifr = ifr, i = 0; i < num;
cur_ifr = __if_nextreq (cur_ifr), ++i)
{
if (cur_ifr->ifr_addr.sa_family != AF_INET)
continue;
/* Now we're committed to this entry. */ ifaddrs[new_num_ifs].addrtype = AF_INET;
++num_ifs; ifaddrs[new_num_ifs].u.ipv4.addr =
((struct sockaddr_in *) &cur_ifr->ifr_addr)->sin_addr.s_addr;
if (__ioctl (sd, SIOCGIFNETMASK, cur_ifr) < 0)
continue;
ifaddrs[new_num_ifs].u.ipv4.mask =
((struct sockaddr_in *) &cur_ifr->ifr_netmask)->sin_addr.s_addr;
/* Now we're committed to this entry. */
++new_num_ifs;
}
/* Just keep enough memory to hold all the interfaces we want. */
ifaddrs = realloc (ifaddrs, new_num_ifs * sizeof (ifaddrs[0]));
assert (ifaddrs != NULL);
cleanup1:
__if_freereq (ifr, num);
cleanup:
/* Release lock, preserve error value, and close socket. */
save = errno;
num_ifs = new_num_ifs;
__libc_lock_unlock (lock);
} }
/* Just keep enough memory to hold all the interfaces we want. */
ifaddrs = realloc (ifaddrs, num_ifs * sizeof (ifaddrs[0]));
assert (ifaddrs != NULL);
cleanup1:
__if_freereq (ifr, num);
cleanup:
/* Release lock, preserve error value, and close socket. */
save = errno;
__libc_lock_unlock (lock);
__close (sd); __close (sd);
} }