mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-22 10:50:07 +00:00
Update.
* sysdeps/unix/sysv/linux/ifaddrs.c (getifaddrs): Check lengths before copying. This might leave holes in the list. Adjust pointers if necessary. (netlink_receive): Allocate only one block. (free_netlink_handle): Adjust appropriately. (getifaddrs): Lots of cleanups.
This commit is contained in:
parent
5bdd77cb60
commit
31dfab9e17
@ -1,5 +1,12 @@
|
|||||||
2003-04-16 Ulrich Drepper <drepper@redhat.com>
|
2003-04-16 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/ifaddrs.c (getifaddrs): Check lengths
|
||||||
|
before copying. This might leave holes in the list. Adjust
|
||||||
|
pointers if necessary.
|
||||||
|
(netlink_receive): Allocate only one block.
|
||||||
|
(free_netlink_handle): Adjust appropriately.
|
||||||
|
(getifaddrs): Lots of cleanups.
|
||||||
|
|
||||||
* string/test-strncpy.c (do_one_test): Mark start and stop as
|
* string/test-strncpy.c (do_one_test): Mark start and stop as
|
||||||
possibly unused.
|
possibly unused.
|
||||||
|
|
||||||
|
@ -252,7 +252,8 @@ netlink_open (struct netlink_handle *h)
|
|||||||
Since we get at first all RTM_NEWLINK entries, it can never happen
|
Since we get at first all RTM_NEWLINK entries, it can never happen
|
||||||
that a RTM_NEWADDR index is not known to this map. */
|
that a RTM_NEWADDR index is not known to this map. */
|
||||||
static int
|
static int
|
||||||
map_newlink (int index, int *map, int max)
|
internal_function
|
||||||
|
map_newlink (int index, struct ifaddrs_storage *ifas, int *map, int max)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -261,6 +262,8 @@ map_newlink (int index, int *map, int max)
|
|||||||
if (map[i] == -1)
|
if (map[i] == -1)
|
||||||
{
|
{
|
||||||
map[i] = index;
|
map[i] = index;
|
||||||
|
if (i > 0)
|
||||||
|
ifas[i - 1].ifa.ifa_next = &ifas[i].ifa;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
else if (map[i] == index)
|
else if (map[i] == index)
|
||||||
@ -389,9 +392,6 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
if ((newlink + newaddr) == 0)
|
if ((newlink + newaddr) == 0)
|
||||||
goto exit_free;
|
goto exit_free;
|
||||||
|
|
||||||
/* Table for mapping kernel index to entry in our list. */
|
|
||||||
map_newlink_data = alloca (newlink * sizeof (int));
|
|
||||||
|
|
||||||
/* Allocate memory for all entries we have and initialize next
|
/* Allocate memory for all entries we have and initialize next
|
||||||
pointer. */
|
pointer. */
|
||||||
ifas = (struct ifaddrs_storage *) calloc (1,
|
ifas = (struct ifaddrs_storage *) calloc (1,
|
||||||
@ -404,11 +404,10 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
goto exit_free;
|
goto exit_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < newlink + newaddr - 1; i++)
|
/* Table for mapping kernel index to entry in our list. */
|
||||||
{
|
map_newlink_data = alloca (newlink * sizeof (int));
|
||||||
ifas[i].ifa.ifa_next = &ifas[i + 1].ifa;
|
memset (map_newlink_data, '\xff', newlink * sizeof (int));
|
||||||
map_newlink_data[i] = -1;
|
|
||||||
}
|
|
||||||
ifa_data_ptr = (char *) &ifas[newlink + newaddr];
|
ifa_data_ptr = (char *) &ifas[newlink + newaddr];
|
||||||
newaddr_idx = 0; /* Counter for newaddr index. */
|
newaddr_idx = 0; /* Counter for newaddr index. */
|
||||||
|
|
||||||
@ -447,7 +446,7 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
/* Interfaces are stored in the first "newlink" entries
|
/* Interfaces are stored in the first "newlink" entries
|
||||||
of our list, starting in the order as we got from the
|
of our list, starting in the order as we got from the
|
||||||
kernel. */
|
kernel. */
|
||||||
ifa_index = map_newlink (ifim->ifi_index - 1,
|
ifa_index = map_newlink (ifim->ifi_index - 1, ifas,
|
||||||
map_newlink_data, newlink);
|
map_newlink_data, newlink);
|
||||||
ifas[ifa_index].ifa.ifa_flags = ifim->ifi_flags;
|
ifas[ifa_index].ifa.ifa_flags = ifim->ifi_flags;
|
||||||
|
|
||||||
@ -459,36 +458,44 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
switch (rta->rta_type)
|
switch (rta->rta_type)
|
||||||
{
|
{
|
||||||
case IFLA_ADDRESS:
|
case IFLA_ADDRESS:
|
||||||
|
if (rta_payload <= sizeof (ifas[ifa_index].addr))
|
||||||
|
{
|
||||||
ifas[ifa_index].addr.sl.sll_family = AF_PACKET;
|
ifas[ifa_index].addr.sl.sll_family = AF_PACKET;
|
||||||
memcpy (ifas[ifa_index].addr.sl.sll_addr,
|
memcpy (ifas[ifa_index].addr.sl.sll_addr,
|
||||||
(char *) rta_data, rta_payload);
|
(char *) rta_data, rta_payload);
|
||||||
ifas[ifa_index].addr.sl.sll_halen = rta_payload;
|
ifas[ifa_index].addr.sl.sll_halen = rta_payload;
|
||||||
ifas[ifa_index].addr.sl.sll_ifindex = ifim->ifi_index;
|
ifas[ifa_index].addr.sl.sll_ifindex
|
||||||
|
= ifim->ifi_index;
|
||||||
ifas[ifa_index].addr.sl.sll_hatype = ifim->ifi_type;
|
ifas[ifa_index].addr.sl.sll_hatype = ifim->ifi_type;
|
||||||
|
|
||||||
ifas[ifa_index].ifa.ifa_addr = &ifas[ifa_index].addr.sa;
|
ifas[ifa_index].ifa.ifa_addr
|
||||||
|
= &ifas[ifa_index].addr.sa;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IFLA_BROADCAST:
|
case IFLA_BROADCAST:
|
||||||
|
if (rta_payload <= sizeof (ifas[ifa_index].broadaddr))
|
||||||
|
{
|
||||||
ifas[ifa_index].broadaddr.sl.sll_family = AF_PACKET;
|
ifas[ifa_index].broadaddr.sl.sll_family = AF_PACKET;
|
||||||
memcpy (ifas[ifa_index].broadaddr.sl.sll_addr,
|
memcpy (ifas[ifa_index].broadaddr.sl.sll_addr,
|
||||||
(char *) rta_data, rta_payload);
|
(char *) rta_data, rta_payload);
|
||||||
ifas[ifa_index].broadaddr.sl.sll_halen = rta_payload;
|
ifas[ifa_index].broadaddr.sl.sll_halen = rta_payload;
|
||||||
ifas[ifa_index].broadaddr.sl.sll_ifindex
|
ifas[ifa_index].broadaddr.sl.sll_ifindex
|
||||||
= ifim->ifi_index;
|
= ifim->ifi_index;
|
||||||
ifas[ifa_index].broadaddr.sl.sll_hatype = ifim->ifi_type;
|
ifas[ifa_index].broadaddr.sl.sll_hatype
|
||||||
|
= ifim->ifi_type;
|
||||||
|
|
||||||
ifas[ifa_index].ifa.ifa_broadaddr
|
ifas[ifa_index].ifa.ifa_broadaddr
|
||||||
= &ifas[ifa_index].broadaddr.sa;
|
= &ifas[ifa_index].broadaddr.sa;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IFLA_IFNAME: /* Name of Interface */
|
case IFLA_IFNAME: /* Name of Interface */
|
||||||
if ((rta_payload + 1) <= sizeof (ifas[ifa_index].name))
|
if ((rta_payload + 1) <= sizeof (ifas[ifa_index].name))
|
||||||
{
|
{
|
||||||
ifas[ifa_index].ifa.ifa_name = ifas[ifa_index].name;
|
ifas[ifa_index].ifa.ifa_name = ifas[ifa_index].name;
|
||||||
strncpy (ifas[ifa_index].name, rta_data,
|
*(char *) __mempcpy (ifas[ifa_index].name, rta_data,
|
||||||
rta_payload);
|
rta_payload) = '\0';
|
||||||
ifas[ifa_index].name[rta_payload] = '\0';
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -521,13 +528,15 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
size_t rtasize = IFA_PAYLOAD (nlh);
|
size_t rtasize = IFA_PAYLOAD (nlh);
|
||||||
|
|
||||||
/* New Addresses are stored in the order we got them from
|
/* New Addresses are stored in the order we got them from
|
||||||
the kernel after interfaces. Theoretically it is possible
|
the kernel after the interfaces. Theoretically it is possible
|
||||||
that we have holes in the interface part of the list,
|
that we have holes in the interface part of the list,
|
||||||
but we always have already the interface for this address. */
|
but we always have already the interface for this address. */
|
||||||
ifa_index = newlink + newaddr_idx;
|
ifa_index = newlink + newaddr_idx;
|
||||||
ifas[ifa_index].ifa.ifa_flags
|
ifas[ifa_index].ifa.ifa_flags
|
||||||
= ifas[map_newlink (ifam->ifa_index - 1,
|
= ifas[map_newlink (ifam->ifa_index - 1, ifas,
|
||||||
map_newlink_data, newlink)].ifa.ifa_flags;
|
map_newlink_data, newlink)].ifa.ifa_flags;
|
||||||
|
if (ifa_index > 0)
|
||||||
|
ifas[ifa_index - 1].ifa.ifa_next = &ifas[ifa_index].ifa;
|
||||||
++newaddr_idx;
|
++newaddr_idx;
|
||||||
|
|
||||||
while (RTA_OK (rta, rtasize))
|
while (RTA_OK (rta, rtasize))
|
||||||
@ -565,20 +574,27 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
switch (ifam->ifa_family)
|
switch (ifam->ifa_family)
|
||||||
{
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
|
/* Size must match that of an address for IPv4. */
|
||||||
|
if (rta_payload == 4)
|
||||||
memcpy (&((struct sockaddr_in *) sa)->sin_addr,
|
memcpy (&((struct sockaddr_in *) sa)->sin_addr,
|
||||||
rta_data, rta_payload);
|
rta_data, rta_payload);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
|
/* Size must match that of an address for IPv6. */
|
||||||
|
if (rta_payload == 16)
|
||||||
|
{
|
||||||
memcpy (&((struct sockaddr_in6 *) sa)->sin6_addr,
|
memcpy (&((struct sockaddr_in6 *) sa)->sin6_addr,
|
||||||
rta_data, rta_payload);
|
rta_data, rta_payload);
|
||||||
if (IN6_IS_ADDR_LINKLOCAL (rta_data) ||
|
if (IN6_IS_ADDR_LINKLOCAL (rta_data)
|
||||||
IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
|
|| IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
|
||||||
((struct sockaddr_in6 *) sa)->sin6_scope_id =
|
((struct sockaddr_in6 *) sa)->sin6_scope_id
|
||||||
ifam->ifa_scope;
|
= ifam->ifa_scope;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (rta_payload <= sizeof (ifas[ifa_index].addr))
|
||||||
memcpy (sa->sa_data, rta_data, rta_payload);
|
memcpy (sa->sa_data, rta_data, rta_payload);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -605,20 +621,27 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
switch (ifam->ifa_family)
|
switch (ifam->ifa_family)
|
||||||
{
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
|
/* Size must match that of an address for IPv4. */
|
||||||
|
if (rta_payload == 4)
|
||||||
memcpy (&ifas[ifa_index].addr.s4.sin_addr,
|
memcpy (&ifas[ifa_index].addr.s4.sin_addr,
|
||||||
rta_data, rta_payload);
|
rta_data, rta_payload);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
|
/* Size must match that of an address for IPv6. */
|
||||||
|
if (rta_payload == 16)
|
||||||
|
{
|
||||||
memcpy (&ifas[ifa_index].addr.s6.sin6_addr,
|
memcpy (&ifas[ifa_index].addr.s6.sin6_addr,
|
||||||
rta_data, rta_payload);
|
rta_data, rta_payload);
|
||||||
if (IN6_IS_ADDR_LINKLOCAL (rta_data) ||
|
if (IN6_IS_ADDR_LINKLOCAL (rta_data) ||
|
||||||
IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
|
IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
|
||||||
ifas[ifa_index].addr.s6.sin6_scope_id =
|
ifas[ifa_index].addr.s6.sin6_scope_id =
|
||||||
ifam->ifa_scope;
|
ifam->ifa_scope;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (rta_payload <= sizeof (ifas[ifa_index].addr))
|
||||||
memcpy (ifas[ifa_index].addr.sa.sa_data,
|
memcpy (ifas[ifa_index].addr.sa.sa_data,
|
||||||
rta_data, rta_payload);
|
rta_data, rta_payload);
|
||||||
break;
|
break;
|
||||||
@ -639,20 +662,27 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
switch (ifam->ifa_family)
|
switch (ifam->ifa_family)
|
||||||
{
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
|
/* Size must match that of an address for IPv4. */
|
||||||
|
if (rta_payload == 4)
|
||||||
memcpy (&ifas[ifa_index].broadaddr.s4.sin_addr,
|
memcpy (&ifas[ifa_index].broadaddr.s4.sin_addr,
|
||||||
rta_data, rta_payload);
|
rta_data, rta_payload);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
|
/* Size must match that of an address for IPv6. */
|
||||||
|
if (rta_payload == 16)
|
||||||
|
{
|
||||||
memcpy (&ifas[ifa_index].broadaddr.s6.sin6_addr,
|
memcpy (&ifas[ifa_index].broadaddr.s6.sin6_addr,
|
||||||
rta_data, rta_payload);
|
rta_data, rta_payload);
|
||||||
if (IN6_IS_ADDR_LINKLOCAL (rta_data)
|
if (IN6_IS_ADDR_LINKLOCAL (rta_data)
|
||||||
|| IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
|
|| IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
|
||||||
ifas[ifa_index].broadaddr.s6.sin6_scope_id
|
ifas[ifa_index].broadaddr.s6.sin6_scope_id
|
||||||
= ifam->ifa_scope;
|
= ifam->ifa_scope;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if (rta_payload <= sizeof (ifas[ifa_index].addr))
|
||||||
memcpy (&ifas[ifa_index].broadaddr.sa.sa_data,
|
memcpy (&ifas[ifa_index].broadaddr.sa.sa_data,
|
||||||
rta_data, rta_payload);
|
rta_data, rta_payload);
|
||||||
break;
|
break;
|
||||||
@ -663,9 +693,8 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
if (rta_payload + 1 <= sizeof (ifas[ifa_index].name))
|
if (rta_payload + 1 <= sizeof (ifas[ifa_index].name))
|
||||||
{
|
{
|
||||||
ifas[ifa_index].ifa.ifa_name = ifas[ifa_index].name;
|
ifas[ifa_index].ifa.ifa_name = ifas[ifa_index].name;
|
||||||
strncpy (ifas[ifa_index].name, rta_data,
|
*(char *) __mempcpy (ifas[ifa_index].name, rta_data,
|
||||||
rta_payload);
|
rta_payload) = '\0';
|
||||||
ifas[ifa_index].name[rta_payload] = '\0';
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
abort ();
|
abort ();
|
||||||
@ -686,7 +715,7 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
address, use the name from the interface entry. */
|
address, use the name from the interface entry. */
|
||||||
if (ifas[ifa_index].ifa.ifa_name == NULL)
|
if (ifas[ifa_index].ifa.ifa_name == NULL)
|
||||||
ifas[ifa_index].ifa.ifa_name
|
ifas[ifa_index].ifa.ifa_name
|
||||||
= ifas[map_newlink (ifam->ifa_index - 1,
|
= ifas[map_newlink (ifam->ifa_index - 1, ifas,
|
||||||
map_newlink_data, newlink)].ifa.ifa_name;
|
map_newlink_data, newlink)].ifa.ifa_name;
|
||||||
|
|
||||||
/* Calculate the netmask. */
|
/* Calculate the netmask. */
|
||||||
@ -738,6 +767,24 @@ getifaddrs (struct ifaddrs **ifap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert (ifa_data_ptr <= (char *) &ifas[newlink + newaddr] + ifa_data_size);
|
||||||
|
|
||||||
|
if (newaddr_idx > 0)
|
||||||
|
{
|
||||||
|
for (i = 0; i < newlink; ++i)
|
||||||
|
if (map_newlink_data[i] == -1)
|
||||||
|
{
|
||||||
|
/* We have fewer links then we anticipated. Adjust the
|
||||||
|
forward pointer to the first address entry. */
|
||||||
|
ifas[i - 1].ifa.ifa_next = &ifas[newlink].ifa;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0 && newlink > 0)
|
||||||
|
/* No valid link, but we allocated memory. We have to
|
||||||
|
populate the first entry. */
|
||||||
|
memmove (ifas, &ifas[newlink], sizeof (struct ifaddrs_storage));
|
||||||
|
}
|
||||||
|
|
||||||
if (ifap != NULL)
|
if (ifap != NULL)
|
||||||
*ifap = &ifas[0].ifa;
|
*ifap = &ifas[0].ifa;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user