Wrap netty accept/connect ops with doPrivileged (#22572)
This is related to #22116. netty channels require socket `connect` and `accept` privileges. Netty does not currently wrap these operations with `doPrivileged` blocks. These changes extend the netty channels and wrap calls to the relevant super methods in doPrivileged blocks.
This commit is contained in:
parent
cd236c4de4
commit
f4270f9914
|
@ -33,8 +33,6 @@ import io.netty.channel.FixedRecvByteBufAllocator;
|
|||
import io.netty.channel.RecvByteBufAllocator;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.oio.OioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.channel.socket.oio.OioServerSocketChannel;
|
||||
import io.netty.handler.codec.ByteToMessageDecoder;
|
||||
import io.netty.handler.codec.http.HttpContentCompressor;
|
||||
import io.netty.handler.codec.http.HttpContentDecompressor;
|
||||
|
@ -80,6 +78,8 @@ import org.elasticsearch.threadpool.ThreadPool;
|
|||
import org.elasticsearch.transport.BindTransportException;
|
||||
import org.elasticsearch.transport.netty4.Netty4OpenChannelsHandler;
|
||||
import org.elasticsearch.transport.netty4.Netty4Utils;
|
||||
import org.elasticsearch.transport.netty4.channel.PrivilegedNioServerSocketChannel;
|
||||
import org.elasticsearch.transport.netty4.channel.PrivilegedOioServerSocketChannel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
|
@ -301,11 +301,11 @@ public class Netty4HttpServerTransport extends AbstractLifecycleComponent implem
|
|||
if (blockingServer) {
|
||||
serverBootstrap.group(new OioEventLoopGroup(workerCount, daemonThreadFactory(settings,
|
||||
HTTP_SERVER_WORKER_THREAD_NAME_PREFIX)));
|
||||
serverBootstrap.channel(OioServerSocketChannel.class);
|
||||
serverBootstrap.channel(PrivilegedOioServerSocketChannel.class);
|
||||
} else {
|
||||
serverBootstrap.group(new NioEventLoopGroup(workerCount, daemonThreadFactory(settings,
|
||||
HTTP_SERVER_WORKER_THREAD_NAME_PREFIX)));
|
||||
serverBootstrap.channel(NioServerSocketChannel.class);
|
||||
serverBootstrap.channel(PrivilegedNioServerSocketChannel.class);
|
||||
}
|
||||
|
||||
serverBootstrap.childHandler(configureServerChannelHandler());
|
||||
|
|
|
@ -33,10 +33,6 @@ import io.netty.channel.FixedRecvByteBufAllocator;
|
|||
import io.netty.channel.RecvByteBufAllocator;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.oio.OioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.channel.socket.oio.OioServerSocketChannel;
|
||||
import io.netty.channel.socket.oio.OioSocketChannel;
|
||||
import io.netty.util.concurrent.Future;
|
||||
import org.apache.logging.log4j.message.ParameterizedMessage;
|
||||
import org.apache.logging.log4j.util.Supplier;
|
||||
|
@ -67,6 +63,10 @@ import org.elasticsearch.transport.TcpTransport;
|
|||
import org.elasticsearch.transport.TransportRequestOptions;
|
||||
import org.elasticsearch.transport.TransportServiceAdapter;
|
||||
import org.elasticsearch.transport.TransportSettings;
|
||||
import org.elasticsearch.transport.netty4.channel.PrivilegedNioServerSocketChannel;
|
||||
import org.elasticsearch.transport.netty4.channel.PrivilegedNioSocketChannel;
|
||||
import org.elasticsearch.transport.netty4.channel.PrivilegedOioServerSocketChannel;
|
||||
import org.elasticsearch.transport.netty4.channel.PrivilegedOioSocketChannel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
|
@ -195,10 +195,10 @@ public class Netty4Transport extends TcpTransport<Channel> {
|
|||
final Bootstrap bootstrap = new Bootstrap();
|
||||
if (TCP_BLOCKING_CLIENT.get(settings)) {
|
||||
bootstrap.group(new OioEventLoopGroup(1, daemonThreadFactory(settings, TRANSPORT_CLIENT_WORKER_THREAD_NAME_PREFIX)));
|
||||
bootstrap.channel(OioSocketChannel.class);
|
||||
bootstrap.channel(PrivilegedOioSocketChannel.class);
|
||||
} else {
|
||||
bootstrap.group(new NioEventLoopGroup(workerCount, daemonThreadFactory(settings, TRANSPORT_CLIENT_BOSS_THREAD_NAME_PREFIX)));
|
||||
bootstrap.channel(NioSocketChannel.class);
|
||||
bootstrap.channel(PrivilegedNioSocketChannel.class);
|
||||
}
|
||||
|
||||
bootstrap.handler(getClientChannelInitializer());
|
||||
|
@ -284,10 +284,10 @@ public class Netty4Transport extends TcpTransport<Channel> {
|
|||
|
||||
if (TCP_BLOCKING_SERVER.get(settings)) {
|
||||
serverBootstrap.group(new OioEventLoopGroup(workerCount, workerFactory));
|
||||
serverBootstrap.channel(OioServerSocketChannel.class);
|
||||
serverBootstrap.channel(PrivilegedOioServerSocketChannel.class);
|
||||
} else {
|
||||
serverBootstrap.group(new NioEventLoopGroup(workerCount, workerFactory));
|
||||
serverBootstrap.channel(NioServerSocketChannel.class);
|
||||
serverBootstrap.channel(PrivilegedNioServerSocketChannel.class);
|
||||
}
|
||||
|
||||
serverBootstrap.childHandler(getServerChannelInitializer(name, settings));
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.transport.netty4.channel;
|
||||
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import org.elasticsearch.SpecialPermission;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wraps netty calls to {@link java.nio.channels.ServerSocketChannel#accept()} in
|
||||
* {@link AccessController#doPrivileged(PrivilegedAction)} blocks. This is necessary to limit
|
||||
* {@link java.net.SocketPermission} to the transport module.
|
||||
*/
|
||||
public class PrivilegedNioServerSocketChannel extends NioServerSocketChannel {
|
||||
|
||||
@Override
|
||||
protected int doReadMessages(List<Object> buf) throws Exception {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new SpecialPermission());
|
||||
}
|
||||
try {
|
||||
return AccessController.doPrivileged((PrivilegedExceptionAction<Integer>) () -> super.doReadMessages(buf));
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw (Exception) e.getCause();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.transport.netty4.channel;
|
||||
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import org.elasticsearch.SpecialPermission;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
/**
|
||||
* Wraps netty calls to {@link java.nio.channels.SocketChannel#connect(SocketAddress)} in
|
||||
* {@link AccessController#doPrivileged(PrivilegedAction)} blocks. This is necessary to limit
|
||||
* {@link java.net.SocketPermission} to the transport module.
|
||||
*/
|
||||
public class PrivilegedNioSocketChannel extends NioSocketChannel {
|
||||
|
||||
@Override
|
||||
protected boolean doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new SpecialPermission());
|
||||
}
|
||||
try {
|
||||
return AccessController.doPrivileged((PrivilegedExceptionAction<Boolean>) () -> super.doConnect(remoteAddress, localAddress));
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw (Exception) e.getCause();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.transport.netty4.channel;
|
||||
|
||||
import io.netty.channel.socket.oio.OioServerSocketChannel;
|
||||
import org.elasticsearch.SpecialPermission;
|
||||
|
||||
import java.net.ServerSocket;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wraps netty calls to {@link ServerSocket#accept()} in {@link AccessController#doPrivileged(PrivilegedAction)} blocks.
|
||||
* This is necessary to limit {@link java.net.SocketPermission} to the transport module.
|
||||
*/
|
||||
public class PrivilegedOioServerSocketChannel extends OioServerSocketChannel {
|
||||
|
||||
@Override
|
||||
protected int doReadMessages(List<Object> buf) throws Exception {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new SpecialPermission());
|
||||
}
|
||||
try {
|
||||
return AccessController.doPrivileged((PrivilegedExceptionAction<Integer>) () -> super.doReadMessages(buf));
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw (Exception) e.getCause();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.transport.netty4.channel;
|
||||
|
||||
import io.netty.channel.socket.oio.OioSocketChannel;
|
||||
import org.elasticsearch.SpecialPermission;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
|
||||
/**
|
||||
* Wraps netty calls to {@link java.net.Socket#connect(SocketAddress)} in
|
||||
* {@link AccessController#doPrivileged(PrivilegedAction)} blocks. This is necessary to limit
|
||||
* {@link java.net.SocketPermission} to the transport module.
|
||||
*/
|
||||
public class PrivilegedOioSocketChannel extends OioSocketChannel {
|
||||
|
||||
@Override
|
||||
protected void doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new SpecialPermission());
|
||||
}
|
||||
try {
|
||||
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
|
||||
super.doConnect(remoteAddress, localAddress);
|
||||
return null;
|
||||
});
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw (Exception) e.getCause();
|
||||
}
|
||||
super.doConnect(remoteAddress, localAddress);
|
||||
}
|
||||
}
|
|
@ -28,7 +28,6 @@ import io.netty.channel.ChannelInitializer;
|
|||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpRequest;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
|
@ -44,6 +43,7 @@ import io.netty.handler.codec.http.HttpVersion;
|
|||
import org.elasticsearch.common.collect.Tuple;
|
||||
import org.elasticsearch.common.unit.ByteSizeUnit;
|
||||
import org.elasticsearch.common.unit.ByteSizeValue;
|
||||
import org.elasticsearch.transport.netty4.channel.PrivilegedNioSocketChannel;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.net.SocketAddress;
|
||||
|
@ -82,7 +82,7 @@ class Netty4HttpClient implements Closeable {
|
|||
private final Bootstrap clientBootstrap;
|
||||
|
||||
Netty4HttpClient() {
|
||||
clientBootstrap = new Bootstrap().channel(NioSocketChannel.class).group(new NioEventLoopGroup());
|
||||
clientBootstrap = new Bootstrap().channel(PrivilegedNioSocketChannel.class).group(new NioEventLoopGroup());
|
||||
}
|
||||
|
||||
public Collection<FullHttpResponse> get(SocketAddress remoteAddress, String... uris) throws InterruptedException {
|
||||
|
|
Loading…
Reference in New Issue