-
Bug
-
Resolution: Fixed
-
P3
-
6u2
-
b21
-
generic
-
solaris_10
-
Verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2152507 | 6u4 | Chris Hegarty | P4 | Closed | Fixed | b04 |
JDK-2152772 | 5.0u14 | Sean Coffey | P3 | Closed | Fixed | b02 |
FULL PRODUCT VERSION :
java version "1.6.0_01"
Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)
This issue is also reproducible with Java SE 5, and Open JDK 7 b18.
ADDITIONAL OS VERSION INFORMATION :
Solaris 10, but should be reproducible on any unix system.
EXTRA RELEVANT SYSTEM CONFIGURATION :
MUST run as root. You must be root to have priviliges to create raw sockets over which
to send the ICMP ECHO. If you are not root then this problem cannot be reproduced.
A DESCRIPTION OF THE PROBLEM :
Even with the fix for 6595834 the return value of InetAddress.isReachable() may
represent the results of another thread's call to isReachable. The reason for this
is that the change for 6595834 uses a random 16 bit value for the sequence number. If
you have one thread blocked in an isReachable call (to an unreachable host) with a
long timeout, another thread in a loop calling isReachable on a reachable host, it is
possible that the sequence number may repeat itself and that the thread in the loop may
eventually use a sequence number the same as the one used by the blocked isReachable
call. This will result in the isReachable call on the unreachable host returning true.
REPRODUCIBILITY :
This bug can be reproduced always.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
---------- BEGIN SOURCE ----------
import java.net.*;
import java.io.IOException;
class LoopIsReachable {
static volatile int count;
static volatile boolean found = false;
static byte[] ipv4LoopbackAddr = new byte[] {(byte)127, (byte)0, (byte)0, (byte)1};
static byte[] unReachableAddr = new byte[] {(byte)1, (byte)1, (byte)1, (byte)1};
public static void main(String args[]) {
Thread thread = new Thread(new UnReachableRunnable());
thread.start();
try {
InetAddress ia = InetAddress.getByAddress(ipv4LoopbackAddr);
while (!found) {
ia.isReachable(60 * 1000);
count++;
}
} catch(Exception e) {
e.printStackTrace();
}
}
static class UnReachableRunnable implements Runnable {
public void run() {
try {
InetAddress ia = InetAddress.getByAddress(unReachableAddr);
if(ia.isReachable(60 * 1000) == true) {
System.out.println(ia + " is reachable! It should NOT" +
" be reachable.");
found = true;
} else {
System.out.println(ia + " is NOT reachable, OK");
}
} catch(IOException e) {
e.printStackTrace();
}
System.out.println("It took " + count + " iterations to find the" +
" unreachable address");
}
}
}
---------- END SOURCE ----------
java version "1.6.0_01"
Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)
This issue is also reproducible with Java SE 5, and Open JDK 7 b18.
ADDITIONAL OS VERSION INFORMATION :
Solaris 10, but should be reproducible on any unix system.
EXTRA RELEVANT SYSTEM CONFIGURATION :
MUST run as root. You must be root to have priviliges to create raw sockets over which
to send the ICMP ECHO. If you are not root then this problem cannot be reproduced.
A DESCRIPTION OF THE PROBLEM :
Even with the fix for 6595834 the return value of InetAddress.isReachable() may
represent the results of another thread's call to isReachable. The reason for this
is that the change for 6595834 uses a random 16 bit value for the sequence number. If
you have one thread blocked in an isReachable call (to an unreachable host) with a
long timeout, another thread in a loop calling isReachable on a reachable host, it is
possible that the sequence number may repeat itself and that the thread in the loop may
eventually use a sequence number the same as the one used by the blocked isReachable
call. This will result in the isReachable call on the unreachable host returning true.
REPRODUCIBILITY :
This bug can be reproduced always.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
---------- BEGIN SOURCE ----------
import java.net.*;
import java.io.IOException;
class LoopIsReachable {
static volatile int count;
static volatile boolean found = false;
static byte[] ipv4LoopbackAddr = new byte[] {(byte)127, (byte)0, (byte)0, (byte)1};
static byte[] unReachableAddr = new byte[] {(byte)1, (byte)1, (byte)1, (byte)1};
public static void main(String args[]) {
Thread thread = new Thread(new UnReachableRunnable());
thread.start();
try {
InetAddress ia = InetAddress.getByAddress(ipv4LoopbackAddr);
while (!found) {
ia.isReachable(60 * 1000);
count++;
}
} catch(Exception e) {
e.printStackTrace();
}
}
static class UnReachableRunnable implements Runnable {
public void run() {
try {
InetAddress ia = InetAddress.getByAddress(unReachableAddr);
if(ia.isReachable(60 * 1000) == true) {
System.out.println(ia + " is reachable! It should NOT" +
" be reachable.");
found = true;
} else {
System.out.println(ia + " is NOT reachable, OK");
}
} catch(IOException e) {
e.printStackTrace();
}
System.out.println("It took " + count + " iterations to find the" +
" unreachable address");
}
}
}
---------- END SOURCE ----------
- backported by
-
JDK-2152772 InetAddress.isReachable implementation not completely thread safe
- Closed
-
JDK-2152507 InetAddress.isReachable implementation not completely thread safe
- Closed
- relates to
-
JDK-6595834 InetAddress.isReachable is not thread safe when using ICMP ECHO.
- Closed