8344112: Remove code to support security manager execution mode from DatagramChannel implementation

Reviewed-by: dfuchs
This commit is contained in:
Alan Bateman 2024-11-13 16:50:54 +00:00
parent bd3fec3075
commit 7be77725ea
2 changed files with 38 additions and 202 deletions

View file

@ -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) {

View file

@ -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) {