JDK-7078386 : NetworkInterface.getNetworkInterfaces() may return corrupted results on linux
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 6u26,7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2011-08-12
  • Updated: 2017-09-14
  • Resolved: 2012-06-07
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.
JDK 7 JDK 8
7u40Fixed 8 b21Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
OpenJDK Runtime Environment (IcedTea6 1.8.7) (6b18-1.8.7-2~squeeze1)
OpenJDK Client VM (build 14.0-b16, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Linux l-at9676 2.6.32-5-686 #1 SMP Mon Jun 13 04:13:06 UTC 2011 i686 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
calling NetworkInterface.getNetworkInterfaces() on linux returns corrupted results if some interface's index is over 255 (which is sometimes the case for virtual interfaces).

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. call NetworkInterface.getNetworkInterfaces() on a machine where some IPv6 enabled interface's index is over 255 (larger than 2 hex-digits)

to check : call "cat /proc/net/if_inet6" in a shell. If any of the number in the second column is over 2 hex-digits, the bug will occur. Example:

00000000000000000000000000000001 01 80 10 80       lo
fe80000000000000f8b164fffe2eaa8e 17f 40 20 80 veth0sACuM
fe80000000000000021517fffee3ae55 04 40 20 80     eth0

2. browse the resulting enumeration : in contains corrupted NetworkInterface objects which doen't correspond to any interface on the machine. Calling methods such as isUp() or isVirtual() on these objects will throw a SocketException

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
a list of existing NetworkInterface object
ACTUAL -
a list containing some existing NetworkInterface mixed with corrupted, non existing NetworkInterface objects

REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER SUBMITTED WORKAROUND :
the bug is caused by an incorrect format string in the C fscanf function, in /openjdk/jdk/src/solaris/native/java/net/NetworkInterface.c , [line 1108 in openjdk-7-fcs-src-b147-27_jun_2011.zip]

the format string is
"%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n"
ans shoud be
"%4s%4s%4s%4s%4s%4s%4s%4s %03x %02x %02x %02x %20s\n"
to be able to parse entries withe a second colum larger than 2 hex-digits.

modifying this line solved the problem for me.

Comments
EVALUATION Changeset: b1814b3ea6d3 Author: michaelm Date: 2011-12-21 10:06 +0000 URL: http://hg.openjdk.java.net/jdk8/tl/jdk/rev/b1814b3ea6d3 7078386: NetworkInterface.getNetworkInterfaces() may return corrupted results on linux Reviewed-by: michaelm, alanb, chegar Contributed-by: brandon.passanisi at oracle.com ! src/solaris/native/java/net/NetworkInterface.c
05-01-2012

SUGGESTED FIX --- a/src/solaris/native/java/net/NetworkInterface.c Wed Dec 21 17:09:39 2011 +0900 +++ b/src/solaris/native/java/net/NetworkInterface.c Wed Dec 21 10:06:32 2011 +0000 @@ -1109,7 +1109,7 @@ static netif *enumIPv6Interfaces(JNIEnv uint8_t ipv6addr[16]; if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) { - while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n", + while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n", addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7], &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
05-01-2012

EVALUATION The bug is caused by an incorrect format string used in the fscanf call within enumIPv6Interfaces of jdk/src/solaris/native/java/net/NetworkInterface.c, which specifies a two-digit hex number for the network interface index value. It has been shown that network interface index values can be more than 255, thus requiring the need to obtain more than two digits. I eventually searched through the following linux kernel source file: linux-source-2.6.32/net/ipv6/addrconf.c ... and it appears the interface index value is being written and an integer within the function inet6_fill_ifinfo in the following block of code starting on line 3785: if (dev->ifindex != dev->iflink) NLA_PUT_U32(skb, IFLA_LINK, dev->iflink); iflink is defined in linux-source-2.6.32/include/linux/netdevice.h as an int on line 742: /* Interface index. Unique device identifier */ int ifindex; int iflink; Because of this and because an integer is 32 bits, it appears that updating the format string to use %08x for the interface index value seems most correct.
16-12-2011