8216355: missing NULL checks in libnet in interface iteration and potential resource leak in getMacAddress
authormbaesken
Wed, 09 Jan 2019 14:46:40 +0100
changeset 53252 e832101ff63c
parent 53251 2e1fd6414c4b
child 53253 d87633b62f1f
8216355: missing NULL checks in libnet in interface iteration and potential resource leak in getMacAddress Reviewed-by: clanger, rwestberg
src/java.base/unix/native/libnet/Inet6AddressImpl.c
src/java.base/unix/native/libnet/NetworkInterface.c
--- a/src/java.base/unix/native/libnet/Inet6AddressImpl.c	Thu Jan 10 21:52:33 2019 +0100
+++ b/src/java.base/unix/native/libnet/Inet6AddressImpl.c	Wed Jan 09 14:46:40 2019 +0100
@@ -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 @@
      */
     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 @@
     // 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;
     }
--- a/src/java.base/unix/native/libnet/NetworkInterface.c	Thu Jan 10 21:52:33 2019 +0100
+++ b/src/java.base/unix/native/libnet/NetworkInterface.c	Wed Jan 09 14:46:40 2019 +0100
@@ -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 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 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 @@
 
     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 @@
         // 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;
+                    }
                 }
             }
         }