8216355: missing NULL checks in libnet in interface iteration and potential resource leak in getMacAddress

Reviewed-by: clanger, rwestberg
This commit is contained in:
Matthias Baesken 2019-01-09 14:46:40 +01:00
parent e13cc6d3a6
commit 4fb0c5f31b
2 changed files with 60 additions and 44 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -142,17 +142,18 @@ lookupIfLocalhost(JNIEnv *env, const char *hostname, jboolean includeV6)
*/
struct ifaddrs *iter = ifa;
while (iter) {
int family = iter->ifa_addr->sa_family;
if (iter->ifa_name[0] != '\0' && iter->ifa_addr)
{
jboolean isLoopback = iter->ifa_flags & IFF_LOOPBACK;
if (family == AF_INET) {
addrs4++;
if (isLoopback) numV4Loopbacks++;
} else if (family == AF_INET6 && includeV6) {
addrs6++;
if (isLoopback) numV6Loopbacks++;
} // else we don't care, e.g. AF_LINK
if (iter->ifa_addr != NULL) {
int family = iter->ifa_addr->sa_family;
if (iter->ifa_name[0] != '\0') {
jboolean isLoopback = iter->ifa_flags & IFF_LOOPBACK;
if (family == AF_INET) {
addrs4++;
if (isLoopback) numV4Loopbacks++;
} else if (family == AF_INET6 && includeV6) {
addrs6++;
if (isLoopback) numV6Loopbacks++;
} // else we don't care, e.g. AF_LINK
}
}
iter = iter->ifa_next;
}
@ -180,28 +181,30 @@ lookupIfLocalhost(JNIEnv *env, const char *hostname, jboolean includeV6)
// Now loop around the ifaddrs
iter = ifa;
while (iter != NULL) {
jboolean isLoopback = iter->ifa_flags & IFF_LOOPBACK;
int family = iter->ifa_addr->sa_family;
if (iter->ifa_addr != NULL) {
jboolean isLoopback = iter->ifa_flags & IFF_LOOPBACK;
int family = iter->ifa_addr->sa_family;
if (iter->ifa_name[0] != '\0' && iter->ifa_addr &&
(family == AF_INET || (family == AF_INET6 && includeV6)) &&
(!isLoopback || includeLoopback))
{
int port;
int index = (family == AF_INET) ? i++ : j++;
jobject o = NET_SockaddrToInetAddress(env,
(SOCKETADDRESS *)iter->ifa_addr, &port);
if (!o) {
freeifaddrs(ifa);
if (!(*env)->ExceptionCheck(env))
JNU_ThrowOutOfMemoryError(env, "Object allocation failed");
return NULL;
if (iter->ifa_name[0] != '\0' &&
(family == AF_INET || (family == AF_INET6 && includeV6)) &&
(!isLoopback || includeLoopback))
{
int port;
int index = (family == AF_INET) ? i++ : j++;
jobject o = NET_SockaddrToInetAddress(env,
(SOCKETADDRESS *)iter->ifa_addr, &port);
if (!o) {
freeifaddrs(ifa);
if (!(*env)->ExceptionCheck(env))
JNU_ThrowOutOfMemoryError(env, "Object allocation failed");
return NULL;
}
setInetAddress_hostName(env, o, name);
if ((*env)->ExceptionCheck(env))
goto done;
(*env)->SetObjectArrayElement(env, result, index, o);
(*env)->DeleteLocalRef(env, o);
}
setInetAddress_hostName(env, o, name);
if ((*env)->ExceptionCheck(env))
goto done;
(*env)->SetObjectArrayElement(env, result, index, o);
(*env)->DeleteLocalRef(env, o);
}
iter = iter->ifa_next;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -1015,7 +1015,11 @@ static netif *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs,
*/
static short translateIPv4AddressToPrefix(struct sockaddr_in *addr) {
short prefix = 0;
unsigned int mask = ntohl(addr->sin_addr.s_addr);
unsigned int mask;
if (addr == NULL) {
return 0;
}
mask = ntohl(addr->sin_addr.s_addr);
while (mask) {
mask <<= 1;
prefix++;
@ -1028,7 +1032,11 @@ static short translateIPv4AddressToPrefix(struct sockaddr_in *addr) {
*/
static short translateIPv6AddressToPrefix(struct sockaddr_in6 *addr) {
short prefix = 0;
u_char *addrBytes = (u_char *)&(addr->sin6_addr);
u_char *addrBytes;
if (addr == NULL) {
return 0;
}
addrBytes = (u_char *)&(addr->sin6_addr);
unsigned int byte, bit;
for (byte = 0; byte < sizeof(struct in6_addr); byte++, prefix += 8) {
@ -1541,20 +1549,23 @@ static int getMacAddress
if (getkerninfo(KINFO_NDD, nddp, &size, 0) < 0) {
perror("getkerninfo 2");
free(nddp);
return -1;
}
end = (void *)nddp + size;
while ((void *)nddp < end) {
if (!strcmp(nddp->ndd_alias, ifname) ||
!strcmp(nddp->ndd_name, ifname)) {
!strcmp(nddp->ndd_name, ifname)) {
bcopy(nddp->ndd_addr, buf, 6);
free(nddp);
return 6;
} else {
nddp++;
}
}
free(nddp);
return -1;
}
@ -2092,14 +2103,16 @@ static int getMacAddress
// cycle through the interfaces
for (i = 0, ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next, i++) {
saddr = ifa->ifa_addr;
// link layer contains the MAC address
if (saddr->sa_family == AF_LINK && !strcmp(ifname, ifa->ifa_name)) {
struct sockaddr_dl *sadl = (struct sockaddr_dl *) saddr;
// check the address has the correct length
if (sadl->sdl_alen == ETHER_ADDR_LEN) {
memcpy(buf, (sadl->sdl_data + sadl->sdl_nlen), ETHER_ADDR_LEN);
freeifaddrs(ifa0);
return ETHER_ADDR_LEN;
if (saddr != NULL) {
// link layer contains the MAC address
if (saddr->sa_family == AF_LINK && !strcmp(ifname, ifa->ifa_name)) {
struct sockaddr_dl *sadl = (struct sockaddr_dl *) saddr;
// check the address has the correct length
if (sadl->sdl_alen == ETHER_ADDR_LEN) {
memcpy(buf, (sadl->sdl_data + sadl->sdl_nlen), ETHER_ADDR_LEN);
freeifaddrs(ifa0);
return ETHER_ADDR_LEN;
}
}
}
}