Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
8240533: Inconsistent Exceptions are thrown by DatagramSocket and Dat…
…agramChannel when sending a DatagramPacket to port 0 Fix adds checks for port == 0 to the send and connect methods in DatagramSocket and DatagramChannelImpl Reviewed-by: alanb, chegar, dfuchs, lancea
- Loading branch information
Showing
with
560 additions
and 0 deletions.
- +6 −0 src/java.base/share/classes/java/net/DatagramSocket.java
- +5 −0 src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java
- +133 −0 test/jdk/java/net/DatagramSocket/ConnectPortZero.java
- +146 −0 test/jdk/java/net/DatagramSocket/SendPortZero.java
- +133 −0 test/jdk/java/nio/channels/DatagramChannel/ConnectPortZero.java
- +137 −0 test/jdk/java/nio/channels/DatagramChannel/SendPortZero.java
@@ -0,0 +1,133 @@ | ||
/* | ||
* Copyright (c) 2020, 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 | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
|
||
import org.testng.annotations.AfterTest; | ||
import org.testng.annotations.BeforeTest; | ||
import org.testng.annotations.DataProvider; | ||
import org.testng.annotations.Test; | ||
|
||
import java.io.IOException; | ||
import java.io.UncheckedIOException; | ||
import java.net.DatagramSocket; | ||
import java.net.InetAddress; | ||
import java.net.InetSocketAddress; | ||
import java.net.MulticastSocket; | ||
import java.net.SocketException; | ||
import java.net.SocketPermission; | ||
import java.nio.channels.DatagramChannel; | ||
import java.security.AccessControlException; | ||
import java.security.Permission; | ||
import java.security.PermissionCollection; | ||
import java.security.Permissions; | ||
import java.security.Policy; | ||
import java.security.ProtectionDomain; | ||
|
||
import static org.testng.Assert.assertEquals; | ||
import static org.testng.Assert.assertThrows; | ||
import static org.testng.Assert.expectThrows; | ||
|
||
/* | ||
* @test | ||
* @bug 8240533 | ||
* @summary Check that DatagramSocket, MulticastSocket and DatagramSocketAdaptor | ||
* throw expected Exception when connecting to port 0 | ||
* @run testng/othervm ConnectPortZero | ||
*/ | ||
|
||
public class ConnectPortZero{ | ||
private InetAddress loopbackAddr, wildcardAddr; | ||
private DatagramSocket datagramSocket, datagramSocketAdaptor; | ||
private MulticastSocket multicastSocket; | ||
|
||
private static final Class<SocketException> SE = SocketException.class; | ||
private static final Class<UncheckedIOException> UCIOE = | ||
UncheckedIOException.class; | ||
private static final Class<AccessControlException> ACE = | ||
AccessControlException.class; | ||
|
||
@BeforeTest | ||
public void setUp() throws IOException { | ||
loopbackAddr = InetAddress.getLoopbackAddress(); | ||
wildcardAddr = new InetSocketAddress(0).getAddress(); | ||
|
||
datagramSocket = new DatagramSocket(); | ||
multicastSocket = new MulticastSocket(); | ||
datagramSocketAdaptor = DatagramChannel.open().socket(); | ||
} | ||
|
||
@DataProvider(name = "data") | ||
public Object[][] variants() { | ||
return new Object[][]{ | ||
{ datagramSocket, loopbackAddr }, | ||
{ datagramSocketAdaptor, loopbackAddr }, | ||
{ multicastSocket, loopbackAddr }, | ||
{ datagramSocket, wildcardAddr }, | ||
{ datagramSocketAdaptor, wildcardAddr }, | ||
{ multicastSocket, wildcardAddr } | ||
}; | ||
} | ||
|
||
@Test(dataProvider = "data") | ||
public void testConnect(DatagramSocket ds, InetAddress addr) { | ||
Throwable t = expectThrows(UCIOE, () -> ds.connect(addr, 0)); | ||
assertEquals(t.getCause().getClass(), SE); | ||
|
||
assertThrows(SE, () -> ds | ||
.connect(new InetSocketAddress(addr, 0))); | ||
} | ||
|
||
|
||
// Check that 0 port check doesn't override security manager check | ||
@Test(dataProvider = "data") | ||
public void testConnectWithSecurityManager(DatagramSocket ds, | ||
InetAddress addr) { | ||
Policy defaultPolicy = Policy.getPolicy(); | ||
try { | ||
Policy.setPolicy(new NoSendPolicy()); | ||
System.setSecurityManager(new SecurityManager()); | ||
|
||
assertThrows(ACE, () -> ds.connect(addr, 0)); | ||
assertThrows(ACE, () -> | ||
ds.connect(new InetSocketAddress(addr, 0))); | ||
} finally { | ||
System.setSecurityManager(null); | ||
Policy.setPolicy(defaultPolicy); | ||
} | ||
} | ||
|
||
static class NoSendPolicy extends Policy { | ||
final PermissionCollection perms = new Permissions(); | ||
{ perms.add(new SocketPermission("*:0", "connect")); } | ||
|
||
public boolean implies(ProtectionDomain domain, Permission perm) { | ||
return !perms.implies(perm); | ||
} | ||
} | ||
|
||
@AfterTest | ||
public void tearDown() { | ||
datagramSocket.close(); | ||
multicastSocket.close(); | ||
datagramSocketAdaptor.close(); | ||
} | ||
} |
@@ -0,0 +1,146 @@ | ||
/* | ||
* Copyright (c) 2020, 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 | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
|
||
import org.testng.annotations.AfterTest; | ||
import org.testng.annotations.BeforeTest; | ||
import org.testng.annotations.DataProvider; | ||
import org.testng.annotations.Test; | ||
|
||
import java.io.IOException; | ||
import java.net.DatagramPacket; | ||
import java.net.DatagramSocket; | ||
import java.net.InetAddress; | ||
import java.net.MulticastSocket; | ||
import java.net.SocketException; | ||
import java.net.SocketPermission; | ||
import java.nio.channels.DatagramChannel; | ||
import java.security.AccessControlException; | ||
import java.security.Permission; | ||
import java.security.PermissionCollection; | ||
import java.security.Permissions; | ||
import java.security.Policy; | ||
import java.security.ProtectionDomain; | ||
|
||
import static org.testng.Assert.assertThrows; | ||
|
||
/* | ||
* @test | ||
* @bug 8236105 8240533 | ||
* @summary Check that DatagramSocket and MulticastSocket throw expected | ||
* Exception when sending a DatagramPacket with port 0 | ||
* @run testng/othervm SendPortZero | ||
*/ | ||
|
||
public class SendPortZero { | ||
private InetAddress loopbackAddr, wildcardAddr; | ||
private DatagramSocket datagramSocket, datagramSocketAdaptor; | ||
private MulticastSocket multicastSocket; | ||
private DatagramPacket loopbackZeroPkt, wildcardZeroPkt, wildcardValidPkt; | ||
|
||
private static final Class<SocketException> SE = SocketException.class; | ||
private static final Class<AccessControlException> ACE = | ||
AccessControlException.class; | ||
|
||
@BeforeTest | ||
public void setUp() throws IOException { | ||
datagramSocket = new DatagramSocket(); | ||
multicastSocket = new MulticastSocket(); | ||
datagramSocketAdaptor = DatagramChannel.open().socket(); | ||
|
||
byte[] buf = "test".getBytes(); | ||
|
||
// Addresses | ||
loopbackAddr = InetAddress.getLoopbackAddress(); | ||
//wildcardAddr = new InetSocketAddress(0).getAddress(); | ||
|
||
// Packets | ||
// loopback w/port 0 | ||
loopbackZeroPkt = new DatagramPacket(buf, 0, buf.length); | ||
loopbackZeroPkt.setAddress(loopbackAddr); | ||
loopbackZeroPkt.setPort(0); | ||
|
||
/* | ||
//Commented until JDK-8236852 is fixed | ||
// wildcard w/port 0 | ||
wildcardZeroPkt = new DatagramPacket(buf, 0, buf.length); | ||
wildcardZeroPkt.setAddress(wildcardAddr); | ||
wildcardZeroPkt.setPort(0); | ||
//Commented until JDK-8236807 is fixed | ||
// wildcard addr w/valid port | ||
wildcardValidPkt = new DatagramPacket(buf, 0, buf.length); | ||
var addr = socket.getAddress(); | ||
wildcardValidPkt.setAddress(addr); | ||
wildcardValidPkt.setPort(socket.getLocalPort()); | ||
*/ | ||
} | ||
|
||
@DataProvider(name = "data") | ||
public Object[][] variants() { | ||
return new Object[][]{ | ||
{ datagramSocket, loopbackZeroPkt }, | ||
{ datagramSocketAdaptor, loopbackZeroPkt }, | ||
{ multicastSocket, loopbackZeroPkt } | ||
}; | ||
} | ||
|
||
@Test(dataProvider = "data") | ||
public void testSend(DatagramSocket ds, DatagramPacket pkt) { | ||
assertThrows(SE, () -> ds.send(pkt)); | ||
} | ||
|
||
// Check that 0 port check doesn't override security manager check | ||
@Test(dataProvider = "data") | ||
public void testSendWithSecurityManager(DatagramSocket ds, | ||
DatagramPacket pkt) { | ||
Policy defaultPolicy = Policy.getPolicy(); | ||
try { | ||
Policy.setPolicy(new NoSendPolicy()); | ||
System.setSecurityManager(new SecurityManager()); | ||
|
||
assertThrows(ACE, () -> ds.send(pkt)); | ||
} finally { | ||
System.setSecurityManager(null); | ||
Policy.setPolicy(defaultPolicy); | ||
} | ||
} | ||
|
||
static class NoSendPolicy extends Policy { | ||
final PermissionCollection perms = new Permissions(); | ||
{ perms.add( | ||
new SocketPermission("*:0", "connect")); } | ||
|
||
public boolean implies(ProtectionDomain domain, Permission perm) { | ||
return !perms.implies(perm); | ||
} | ||
} | ||
|
||
@AfterTest | ||
public void tearDown() { | ||
datagramSocket.close(); | ||
multicastSocket.close(); | ||
datagramSocketAdaptor.close(); | ||
} | ||
} |
Oops, something went wrong.