mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 22:34:27 +02:00
8344112: Remove code to support security manager execution mode from DatagramChannel implementation
Reviewed-by: dfuchs
This commit is contained in:
parent
bd3fec3075
commit
7be77725ea
2 changed files with 38 additions and 202 deletions
|
@ -60,8 +60,6 @@ import java.nio.channels.NotYetConnectedException;
|
||||||
import java.nio.channels.SelectionKey;
|
import java.nio.channels.SelectionKey;
|
||||||
import java.nio.channels.spi.AbstractSelectableChannel;
|
import java.nio.channels.spi.AbstractSelectableChannel;
|
||||||
import java.nio.channels.spi.SelectorProvider;
|
import java.nio.channels.spi.SelectorProvider;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedExceptionAction;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -293,8 +291,7 @@ class DatagramChannelImpl
|
||||||
public SocketAddress getLocalAddress() throws IOException {
|
public SocketAddress getLocalAddress() throws IOException {
|
||||||
synchronized (stateLock) {
|
synchronized (stateLock) {
|
||||||
ensureOpen();
|
ensureOpen();
|
||||||
// Perform security check before returning address
|
return localAddress;
|
||||||
return Net.getRevealedLocalAddress(localAddress);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,24 +570,16 @@ class DatagramChannelImpl
|
||||||
SocketAddress remote = beginRead(blocking, false);
|
SocketAddress remote = beginRead(blocking, false);
|
||||||
configureSocketNonBlockingIfVirtualThread();
|
configureSocketNonBlockingIfVirtualThread();
|
||||||
boolean connected = (remote != null);
|
boolean connected = (remote != null);
|
||||||
@SuppressWarnings("removal")
|
int n = receive(dst, connected);
|
||||||
SecurityManager sm = System.getSecurityManager();
|
if (blocking) {
|
||||||
if (connected || (sm == null)) {
|
while (IOStatus.okayToRetry(n) && isOpen()) {
|
||||||
// connected or no security manager
|
park(Net.POLLIN);
|
||||||
int n = receive(dst, connected);
|
n = receive(dst, connected);
|
||||||
if (blocking) {
|
|
||||||
while (IOStatus.okayToRetry(n) && isOpen()) {
|
|
||||||
park(Net.POLLIN);
|
|
||||||
n = receive(dst, connected);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (n > 0 || (n == 0 && isOpen())) {
|
}
|
||||||
// sender address is in socket address buffer
|
if (n > 0 || (n == 0 && isOpen())) {
|
||||||
sender = sourceSocketAddress();
|
// sender address is in socket address buffer
|
||||||
}
|
sender = sourceSocketAddress();
|
||||||
} else {
|
|
||||||
// security manager and unconnected
|
|
||||||
sender = untrustedReceive(dst);
|
|
||||||
}
|
}
|
||||||
return sender;
|
return sender;
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -601,49 +590,6 @@ class DatagramChannelImpl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Receives a datagram into an untrusted buffer. When there is a security
|
|
||||||
* manager set, and the socket is not connected, datagrams have to be received
|
|
||||||
* into a buffer that is not accessible to the user. The datagram is copied
|
|
||||||
* into the user's buffer when the sender address is accepted by the security
|
|
||||||
* manager.
|
|
||||||
*/
|
|
||||||
private SocketAddress untrustedReceive(ByteBuffer dst) throws IOException {
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
assert readLock.isHeldByCurrentThread()
|
|
||||||
&& sm != null && remoteAddress == null;
|
|
||||||
|
|
||||||
boolean blocking = isBlocking();
|
|
||||||
for (;;) {
|
|
||||||
int n;
|
|
||||||
ByteBuffer bb = Util.getTemporaryDirectBuffer(dst.remaining());
|
|
||||||
try {
|
|
||||||
n = receive(bb, false);
|
|
||||||
if (n >= 0) {
|
|
||||||
// sender address is in socket address buffer
|
|
||||||
InetSocketAddress isa = sourceSocketAddress();
|
|
||||||
try {
|
|
||||||
sm.checkAccept(isa.getAddress().getHostAddress(), isa.getPort());
|
|
||||||
bb.flip();
|
|
||||||
dst.put(bb);
|
|
||||||
return isa;
|
|
||||||
} catch (SecurityException se) {
|
|
||||||
// ignore datagram
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
Util.releaseTemporaryDirectBuffer(bb);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blocking && IOStatus.okayToRetry(n) && isOpen()) {
|
|
||||||
park(Net.POLLIN);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receives a datagram.
|
* Receives a datagram.
|
||||||
*
|
*
|
||||||
|
@ -675,58 +621,30 @@ class DatagramChannelImpl
|
||||||
bufLength = DatagramPackets.getBufLength(p);
|
bufLength = DatagramPackets.getBufLength(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
long startNanos = System.nanoTime();
|
boolean completed = false;
|
||||||
long remainingNanos = nanos;
|
|
||||||
SocketAddress sender = null;
|
|
||||||
try {
|
try {
|
||||||
SocketAddress remote = beginRead(true, false);
|
SocketAddress remote = beginRead(true, false);
|
||||||
boolean connected = (remote != null);
|
boolean connected = (remote != null);
|
||||||
do {
|
ByteBuffer dst = tryBlockingReceive(connected, bufLength, nanos);
|
||||||
ByteBuffer dst = tryBlockingReceive(connected, bufLength, remainingNanos);
|
if (dst != null) {
|
||||||
|
|
||||||
// if datagram received then get sender and copy to DatagramPacket
|
// if datagram received then get sender and copy to DatagramPacket
|
||||||
if (dst != null) {
|
try {
|
||||||
try {
|
SocketAddress sender = sourceSocketAddress();
|
||||||
// sender address is in socket address buffer
|
synchronized (p) {
|
||||||
sender = sourceSocketAddress();
|
// copy bytes to the DatagramPacket, and set length and sender.
|
||||||
|
// Need to re-read p.bufLength in case DatagramPacket changed
|
||||||
// check sender when security manager set and not connected
|
int len = Math.min(dst.limit(), DatagramPackets.getBufLength(p));
|
||||||
@SuppressWarnings("removal")
|
dst.get(p.getData(), p.getOffset(), len);
|
||||||
SecurityManager sm = System.getSecurityManager();
|
DatagramPackets.setLength(p, len);
|
||||||
if (sm != null && !connected) {
|
p.setSocketAddress(sender);
|
||||||
InetSocketAddress isa = (InetSocketAddress) sender;
|
|
||||||
try {
|
|
||||||
sm.checkAccept(isa.getAddress().getHostAddress(), isa.getPort());
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
sender = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sender != null) {
|
|
||||||
// copy bytes to the DatagramPacket, and set length and sender
|
|
||||||
synchronized (p) {
|
|
||||||
// re-read p.bufLength in case DatagramPacket changed
|
|
||||||
int len = Math.min(dst.limit(), DatagramPackets.getBufLength(p));
|
|
||||||
dst.get(p.getData(), p.getOffset(), len);
|
|
||||||
DatagramPackets.setLength(p, len);
|
|
||||||
p.setSocketAddress(sender);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// need to retry, adjusting timeout if needed
|
|
||||||
if (nanos > 0) {
|
|
||||||
remainingNanos = nanos - (System.nanoTime() - startNanos);
|
|
||||||
if (remainingNanos <= 0) {
|
|
||||||
throw new SocketTimeoutException("Receive timed out");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
Util.offerFirstTemporaryDirectBuffer(dst);
|
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
Util.offerFirstTemporaryDirectBuffer(dst);
|
||||||
}
|
}
|
||||||
} while (sender == null && isOpen());
|
completed = true;
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
endRead(true, (sender != null));
|
endRead(true, completed);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
readLock.unlock();
|
readLock.unlock();
|
||||||
|
@ -884,16 +802,7 @@ class DatagramChannelImpl
|
||||||
completed = (n > 0);
|
completed = (n > 0);
|
||||||
} else {
|
} else {
|
||||||
// not connected
|
// not connected
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
InetAddress ia = isa.getAddress();
|
InetAddress ia = isa.getAddress();
|
||||||
if (sm != null) {
|
|
||||||
if (ia.isMulticastAddress()) {
|
|
||||||
sm.checkMulticast(ia);
|
|
||||||
} else {
|
|
||||||
sm.checkConnect(ia.getHostAddress(), isa.getPort());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ia.isLinkLocalAddress())
|
if (ia.isLinkLocalAddress())
|
||||||
isa = IPAddressUtil.toScopedAddress(isa);
|
isa = IPAddressUtil.toScopedAddress(isa);
|
||||||
if (isa.getPort() == 0)
|
if (isa.getPort() == 0)
|
||||||
|
@ -1344,10 +1253,6 @@ class DatagramChannelImpl
|
||||||
} else {
|
} else {
|
||||||
isa = Net.checkAddress(local, family);
|
isa = Net.checkAddress(local, family);
|
||||||
}
|
}
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null)
|
|
||||||
sm.checkListen(isa.getPort());
|
|
||||||
|
|
||||||
Net.bind(family, fd, isa.getAddress(), isa.getPort());
|
Net.bind(family, fd, isa.getAddress(), isa.getPort());
|
||||||
localAddress = Net.localAddress(fd);
|
localAddress = Net.localAddress(fd);
|
||||||
|
@ -1373,17 +1278,6 @@ class DatagramChannelImpl
|
||||||
*/
|
*/
|
||||||
DatagramChannel connect(SocketAddress sa, boolean check) throws IOException {
|
DatagramChannel connect(SocketAddress sa, boolean check) throws IOException {
|
||||||
InetSocketAddress isa = Net.checkAddress(sa, family);
|
InetSocketAddress isa = Net.checkAddress(sa, family);
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
InetAddress ia = isa.getAddress();
|
|
||||||
if (ia.isMulticastAddress()) {
|
|
||||||
sm.checkMulticast(ia);
|
|
||||||
} else {
|
|
||||||
sm.checkConnect(ia.getHostAddress(), isa.getPort());
|
|
||||||
sm.checkAccept(ia.getHostAddress(), isa.getPort());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
readLock.lock();
|
readLock.lock();
|
||||||
try {
|
try {
|
||||||
|
@ -1589,17 +1483,13 @@ class DatagramChannelImpl
|
||||||
/**
|
/**
|
||||||
* Defines static methods to access AbstractSelectableChannel non-public members.
|
* Defines static methods to access AbstractSelectableChannel non-public members.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
private static class AbstractSelectableChannels {
|
private static class AbstractSelectableChannels {
|
||||||
private static final Method FOREACH;
|
private static final Method FOREACH;
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
PrivilegedExceptionAction<Method> pae = () -> {
|
Method m = AbstractSelectableChannel.class.getDeclaredMethod("forEach", Consumer.class);
|
||||||
Method m = AbstractSelectableChannel.class.getDeclaredMethod("forEach", Consumer.class);
|
m.setAccessible(true);
|
||||||
m.setAccessible(true);
|
FOREACH = m;
|
||||||
return m;
|
|
||||||
};
|
|
||||||
FOREACH = AccessController.doPrivileged(pae);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new InternalError(e);
|
throw new InternalError(e);
|
||||||
}
|
}
|
||||||
|
@ -1646,11 +1536,6 @@ class DatagramChannelImpl
|
||||||
throw new IllegalArgumentException("Source address is different type to group");
|
throw new IllegalArgumentException("Source address is different type to group");
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null)
|
|
||||||
sm.checkMulticast(group);
|
|
||||||
|
|
||||||
synchronized (stateLock) {
|
synchronized (stateLock) {
|
||||||
ensureOpen();
|
ensureOpen();
|
||||||
|
|
||||||
|
@ -2051,10 +1936,7 @@ class DatagramChannelImpl
|
||||||
private static final VarHandle BUF_LENGTH;
|
private static final VarHandle BUF_LENGTH;
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
PrivilegedExceptionAction<MethodHandles.Lookup> pa = () ->
|
MethodHandles.Lookup l = MethodHandles.privateLookupIn(DatagramPacket.class, MethodHandles.lookup());
|
||||||
MethodHandles.privateLookupIn(DatagramPacket.class, MethodHandles.lookup());
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
MethodHandles.Lookup l = AccessController.doPrivileged(pa);
|
|
||||||
LENGTH = l.findVarHandle(DatagramPacket.class, "length", int.class);
|
LENGTH = l.findVarHandle(DatagramPacket.class, "length", int.class);
|
||||||
BUF_LENGTH = l.findVarHandle(DatagramPacket.class, "bufLength", int.class);
|
BUF_LENGTH = l.findVarHandle(DatagramPacket.class, "bufLength", int.class);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -48,9 +48,6 @@ import java.nio.channels.ClosedChannelException;
|
||||||
import java.nio.channels.ClosedByInterruptException;
|
import java.nio.channels.ClosedByInterruptException;
|
||||||
import java.nio.channels.DatagramChannel;
|
import java.nio.channels.DatagramChannel;
|
||||||
import java.nio.channels.MembershipKey;
|
import java.nio.channels.MembershipKey;
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.security.PrivilegedExceptionAction;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
@ -167,24 +164,11 @@ public class DatagramSocketAdaptor
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SocketAddress getLocalSocketAddress() {
|
public SocketAddress getLocalSocketAddress() {
|
||||||
InetSocketAddress local = dc.localAddress();
|
if (isClosed()) {
|
||||||
if (local == null || isClosed())
|
|
||||||
return null;
|
return null;
|
||||||
|
} else {
|
||||||
InetAddress addr = local.getAddress();
|
return dc.localAddress();
|
||||||
if (addr.isAnyLocalAddress())
|
|
||||||
return local;
|
|
||||||
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
try {
|
|
||||||
sm.checkConnect(addr.getHostAddress(), -1);
|
|
||||||
} catch (SecurityException x) {
|
|
||||||
return new InetSocketAddress(local.getPort());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return local;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -223,17 +207,7 @@ public class DatagramSocketAdaptor
|
||||||
InetSocketAddress local = dc.localAddress();
|
InetSocketAddress local = dc.localAddress();
|
||||||
if (local == null)
|
if (local == null)
|
||||||
local = new InetSocketAddress(0);
|
local = new InetSocketAddress(0);
|
||||||
InetAddress result = local.getAddress();
|
return local.getAddress();
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
try {
|
|
||||||
sm.checkConnect(result.getHostAddress(), -1);
|
|
||||||
} catch (SecurityException x) {
|
|
||||||
return new InetSocketAddress(0).getAddress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -484,11 +458,6 @@ public class DatagramSocketAdaptor
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
MembershipKey key = dc.findMembership(group, ni);
|
MembershipKey key = dc.findMembership(group, ni);
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
// already a member but need to check permission anyway
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null)
|
|
||||||
sm.checkMulticast(group);
|
|
||||||
throw new SocketException("Already a member of group");
|
throw new SocketException("Already a member of group");
|
||||||
}
|
}
|
||||||
dc.join(group, ni); // checks permission
|
dc.join(group, ni); // checks permission
|
||||||
|
@ -501,10 +470,6 @@ public class DatagramSocketAdaptor
|
||||||
NetworkInterface ni = (netIf != null) ? netIf : defaultNetworkInterface();
|
NetworkInterface ni = (netIf != null) ? netIf : defaultNetworkInterface();
|
||||||
if (isClosed())
|
if (isClosed())
|
||||||
throw new SocketException("Socket is closed");
|
throw new SocketException("Socket is closed");
|
||||||
@SuppressWarnings("removal")
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null)
|
|
||||||
sm.checkMulticast(group);
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
MembershipKey key = dc.findMembership(group, ni);
|
MembershipKey key = dc.findMembership(group, ni);
|
||||||
if (key == null)
|
if (key == null)
|
||||||
|
@ -541,12 +506,7 @@ public class DatagramSocketAdaptor
|
||||||
return outgoingInetAddress;
|
return outgoingInetAddress;
|
||||||
} else {
|
} else {
|
||||||
// network interface has changed so update cached values
|
// network interface has changed so update cached values
|
||||||
PrivilegedAction<InetAddress> pa;
|
InetAddress ia = ni.inetAddresses().findFirst().orElse(null);
|
||||||
pa = () -> ni.inetAddresses().findFirst().orElse(null);
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
InetAddress ia = AccessController.doPrivileged(pa);
|
|
||||||
if (ia == null)
|
|
||||||
throw new SocketException("Network interface has no IP address");
|
|
||||||
outgoingNetworkInterface = ni;
|
outgoingNetworkInterface = ni;
|
||||||
outgoingInetAddress = ia;
|
outgoingInetAddress = ia;
|
||||||
return ia;
|
return ia;
|
||||||
|
@ -660,10 +620,7 @@ public class DatagramSocketAdaptor
|
||||||
static final MethodHandle CONSTRUCTOR;
|
static final MethodHandle CONSTRUCTOR;
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
PrivilegedExceptionAction<Lookup> pa = () ->
|
Lookup l = MethodHandles.privateLookupIn(NetworkInterface.class, MethodHandles.lookup());
|
||||||
MethodHandles.privateLookupIn(NetworkInterface.class, MethodHandles.lookup());
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
MethodHandles.Lookup l = AccessController.doPrivileged(pa);
|
|
||||||
MethodType methodType = MethodType.methodType(NetworkInterface.class);
|
MethodType methodType = MethodType.methodType(NetworkInterface.class);
|
||||||
GET_DEFAULT = l.findStatic(NetworkInterface.class, "getDefault", methodType);
|
GET_DEFAULT = l.findStatic(NetworkInterface.class, "getDefault", methodType);
|
||||||
methodType = MethodType.methodType(void.class, String.class, int.class, InetAddress[].class);
|
methodType = MethodType.methodType(void.class, String.class, int.class, InetAddress[].class);
|
||||||
|
@ -703,10 +660,7 @@ public class DatagramSocketAdaptor
|
||||||
private static final SocketAddress NO_DELEGATE;
|
private static final SocketAddress NO_DELEGATE;
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
PrivilegedExceptionAction<Lookup> pa = () ->
|
Lookup l = MethodHandles.privateLookupIn(DatagramSocket.class, MethodHandles.lookup());
|
||||||
MethodHandles.privateLookupIn(DatagramSocket.class, MethodHandles.lookup());
|
|
||||||
@SuppressWarnings("removal")
|
|
||||||
MethodHandles.Lookup l = AccessController.doPrivileged(pa);
|
|
||||||
var handle = l.findStaticVarHandle(DatagramSocket.class, "NO_DELEGATE", SocketAddress.class);
|
var handle = l.findStaticVarHandle(DatagramSocket.class, "NO_DELEGATE", SocketAddress.class);
|
||||||
NO_DELEGATE = (SocketAddress) handle.get();
|
NO_DELEGATE = (SocketAddress) handle.get();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue