JDK-8023649 : java.net.NetworkInterface.getInterfaceAddresses() call flow clean up
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 7u3,10
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_7
  • Submitted: 2013-04-04
  • Updated: 2024-05-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version  " 1.7.0_03 " 
Java(TM) SE Runtime Environment (build 1.7.0_03-b05)
Java HotSpot(TM) Client VM (build 22.1-b02, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
This is similar (if not a dup) to bug 7112820, however; I could not determine a way to re-open that one.

We have an application which is doing the following:

final Enumeration<NetworkInterface> inetEnum = NetworkInterface
.getNetworkInterfaces();
 while (inetEnum.hasMoreElements()) {
  final NetworkInterface niFace = inetEnum.nextElement();
  if (niFace.isUp()) {
   final Enumeration<InetAddress> ipAddys = niFace.getInetAddresses();
...

I get a NPE in my application when calling niFace.getInetAddresses().

Stack trace:

  <exception>
    <message>java.lang.NullPointerException</message>
    <frame>
      <class>java.net.NetworkInterface</class>
      <method>getInterfaceAddresses</method>
      <line>160</line>
    </frame>
    <frame>
      <class>com.wbemsolutions.utilities.NetworkUtils</class>
      <method>getActiveIPs</method>
      <line>31</line>
    </frame>
  </exception>


The line of code is this one:

sec.checkConnect(bindings[j].getAddress().getHostAddress(), -1);

In my case the 'binding' object contains a null at index 0

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Not getting a NPE

REPRODUCIBILITY :
This bug can be reproduced always.
Comments
I don't see how this could happen in the IPv6 code. However, it should be reproducible with the IPv4 code. The createNetworkInterface method creates an array of bindings of length equal to the number of addresses: https://github.com/openjdk/jdk8u-dev/blob/216b8cbf51f8f5f020a57dabb763c27b36899c12/jdk/src/windows/native/java/net/NetworkInterface.c#L577 The bindings are populated with every address from the list *EXCEPT* addresses with mask = -1: https://github.com/openjdk/jdk8u-dev/blob/216b8cbf51f8f5f020a57dabb763c27b36899c12/jdk/src/windows/native/java/net/NetworkInterface.c#L601 Some network addresses receive mask = -1; these include PPP, SLIP, and other address types not explicitly listed: https://github.com/openjdk/jdk8u-dev/blob/216b8cbf51f8f5f020a57dabb763c27b36899c12/jdk/src/windows/native/java/net/NetworkInterface.c#L469 So, in order to reproduce this issue one would need a PPP interface and preferIPv4Stack=true. The code in question was removed in JDK-8302659.
21-05-2024

in theory createNetworkInterface may not execute the block below for each IPv4 address, in which case there's a bindings array with null references. 589 if (addrs->mask != -1) { 590 ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID); 591 if (ibObj == NULL) { 592 free_netaddr(netaddrP); 593 return NULL; 594 } 595 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj); 596 ia2Obj = (*env)->NewObject(env, ia4_class, ia4_ctrID); 597 if (ia2Obj == NULL) { 598 free_netaddr(netaddrP); 599 return NULL; 600 } 601 setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.sa4.sin_addr.s_addr)); 602 (*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj); 603 (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask); 604 (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj); 605 } so a defensive conditional null check in NetworkInterface::getInterfaceAddresses would seem to be appropriate.
07-09-2017

having looked through the various call flows for NetworkInterface::getNetworkInterfaces, NetworkInterface::getInterfaceAddresses and ::getInetAddresses the native funtcions createNetworInterface, createNetworInterfaceXP and so on it seems improbable for a host with any configured network interface to return a null binding if we wished to be clinical and defensive about it then a null can be added to NetworInterface::getInterfaceAddresses. Various attempts to reproduce have proved unsuccessful. Thus, this is currently considered not an issue. However, while wandering through the code in this context, a number of potential issue surface, which should be attended to for consistency. A number of these would be expected in parfait reports, but that does not seem to be the case. Various parts of the createNetworkInterface call flow fail to release native memory for address arrays or linked list tail next pointers not explicitly set to null. As such, will leave issue open and re-purposed to address these potential banana skins.
07-09-2017

as per https://bugs.openjdk.java.net/browse/JDK-8175325 a NetworkInterface::getInterfaceAddresses could throw an NPE, but that was through a MulticastSocket.getNetworkInterface().getInterfaceAddresses() call flow. The binding hadn't be instantiated because the NetworkInterface was created by the NetworkInterface(String name, int index, InetAddress[] addrs) constructor. for NetworkInterface::getInterfaceAddresses to throw an NPE this leads to createNetworkInterface and createNetworkInterface_XP there's a while loop that processes the set of enumeracted addresses, and within that is a block for AF_INET4 and for AF_INET6, there is the possibility in both versions for anomalous behaviour to ensue i.e. it's possible for a null to be added to an address array For the bindings address array, that doesn't look likely. Nonetheless there is a little bit of tidy up and integrity checking that could be done in the calls of each of these native functions will check whether these are worthwhile ... so leaving open for the moment We're caught in a moment And I won't let it go I am falling deeper, losing my control ....
04-09-2017

poked around at this again ... an interface that is UP and doesn't have an IP address configured is likely to be a misconfiguration, unless someone on a DHCP client has cleared the lease and released the IP address and did not subsequently renew the IP address. There was also problems where IPv6 was available but not enabled, thus ipv6_available() was returning TRUE when it should have returned FALSE. This was rectified for jdk8 as per https://bugs.openjdk.java.net/browse/JDK-8021372 This could alter the call flow when a NetworkInterface is being created. would really need the details of ipconfig /all as previously requested
24-03-2014

Unfortunately the code paths are not very clear here, java.net.InterfaceAddress.address is set by native code. If it were possible that this value was null, or unset, then I could see that a NPE would be possible. But I agree, this is certainly related to the specific network configuration on the submitters machine, and without any insight into this it is difficult to determine for sure if there is a real issue here.
02-09-2013

I have executed a verification test, based on the code extract above, against 7u25 and it is OK i.e. no NullPointerException. I'm not sure that the exception trace above will arise for NetworkInterface.getInetAddresses. Closer inspection of the trace tells us that the method is getInterfaceAddresses. The test code extract is misleading. Therefore, executed a getInterfaceAddresses test, and this was fine also. public static void jbs8023649VerificationTest2() throws Exception { Enumeration<NetworkInterface> netInterfaces = NetworkInterface .getNetworkInterfaces(); NetworkInterface netIf = null; List<InterfaceAddress> ifAddrs = null; InetAddress inetAddress = null; while (netInterfaces.hasMoreElements()) { netIf = netInterfaces.nextElement(); if (netIf.isUp()) { ifAddrs = netIf.getInterfaceAddresses(); for(InterfaceAddress ifAddr: ifAddrs) { System.out.println("InterfaceAddress is " +ifAddr); inetAddress = ifAddr.getAddress(); System.out.println("InetAddress == " + inetAddress); } } } } As such this appears not be an issue. Could the submitter supply the output from ipconfig /all before we close this issue, so that we can double we're not missing anything?
02-09-2013

Accepting this bug for now. It may be possible to reproduce with an interface that has no addresses assigned to it.
02-09-2013