mirror of https://gerrit.osmocom.org/libosmocore
socket: Fix stack-buffer-overflow in osmo_sock_local_ip()
On IPv6 sockets, getsockname() and inet_ntop() would act upon a structure struct sockaddr_in. First getsockname() would succeed but truncate the address, and later on inet_ntop would read out of the scope of the structure. Change-Id: If781d56680758a97643b1b38e78d3431ea649020
This commit is contained in:
parent
308ab792a3
commit
81e7a6c859
23
src/socket.c
23
src/socket.c
|
@ -1413,7 +1413,9 @@ int osmo_sock_local_ip(char *local_ip, const char *remote_ip)
|
|||
int rc;
|
||||
struct addrinfo addrinfo_hint;
|
||||
struct addrinfo *addrinfo = NULL;
|
||||
struct sockaddr_in local_addr;
|
||||
struct sockaddr_storage local_addr;
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr_in6 *sin6;
|
||||
socklen_t local_addr_len;
|
||||
uint16_t family;
|
||||
|
||||
|
@ -1442,12 +1444,21 @@ int osmo_sock_local_ip(char *local_ip, const char *remote_ip)
|
|||
close(sfd);
|
||||
if (rc < 0)
|
||||
return -EINVAL;
|
||||
if (local_addr.sin_family == AF_INET)
|
||||
inet_ntop(AF_INET, &local_addr.sin_addr, local_ip, INET_ADDRSTRLEN);
|
||||
else if (local_addr.sin_family == AF_INET6)
|
||||
inet_ntop(AF_INET6, &local_addr.sin_addr, local_ip, INET6_ADDRSTRLEN);
|
||||
else
|
||||
|
||||
switch (local_addr.ss_family) {
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in*)&local_addr;
|
||||
if (!inet_ntop(AF_INET, &sin->sin_addr, local_ip, INET_ADDRSTRLEN))
|
||||
return -EINVAL;
|
||||
break;
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6*)&local_addr;
|
||||
if (!inet_ntop(AF_INET6, &sin6->sin6_addr, local_ip, INET_ADDRSTRLEN))
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue