Skip to content

Commit

Permalink
Wrap netty accept/connect ops with doPrivileged
Browse files Browse the repository at this point in the history
This is related to elastic#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.
  • Loading branch information
Tim-Brooks committed Jan 11, 2017
1 parent 389ffc9 commit 8dfafd2
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
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;
Expand Down Expand Up @@ -80,6 +78,8 @@
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;
Expand Down Expand Up @@ -301,11 +301,11 @@ protected void doStart() {
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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@
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;
Expand Down Expand Up @@ -67,6 +63,10 @@
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;
Expand Down Expand Up @@ -195,10 +195,10 @@ private Bootstrap createBootstrap() {
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());
Expand Down Expand Up @@ -284,10 +284,10 @@ private void createServerBootstrap(String name, Settings settings) {

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));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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 java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.List;

public class PrivilegedNioServerSocketChannel extends NioServerSocketChannel {

@Override
protected int doReadMessages(List<Object> buf) throws Exception {
try {
return AccessController.doPrivileged((PrivilegedExceptionAction<Integer>) () -> super.doReadMessages(buf));
} catch (PrivilegedActionException e) {
throw (Exception) e.getCause();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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 java.net.SocketAddress;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

public class PrivilegedNioSocketChannel extends NioSocketChannel {

@Override
protected boolean doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
try {
return AccessController.doPrivileged((PrivilegedExceptionAction<Boolean>) () -> super.doConnect(remoteAddress, localAddress));
} catch (PrivilegedActionException e) {
throw (Exception) e.getCause();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* 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 java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.List;

public class PrivilegedOioServerSocketChannel extends OioServerSocketChannel {

@Override
protected int doReadMessages(List<Object> buf) throws Exception {
try {
return AccessController.doPrivileged((PrivilegedExceptionAction<Integer>) () -> super.doReadMessages(buf));
} catch (PrivilegedActionException e) {
throw (Exception) e.getCause();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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 java.net.SocketAddress;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

public class PrivilegedOioSocketChannel extends OioSocketChannel {

@Override
protected void doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
super.doConnect(remoteAddress, localAddress);
return null;
});
} catch (PrivilegedActionException e) {
throw (Exception) e.getCause();
}
super.doConnect(remoteAddress, localAddress);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
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;
Expand All @@ -44,6 +43,7 @@
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;
Expand Down Expand Up @@ -82,7 +82,7 @@ static Collection<String> returnOpaqueIds(Collection<FullHttpResponse> responses
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 {
Expand Down

0 comments on commit 8dfafd2

Please sign in to comment.