Skip to content

Commit

Permalink
Add single static instance of SpecialPermission (#22726)
Browse files Browse the repository at this point in the history
This commit adds a SpecialPermission constant and uses that constant
opposed to introducing new instances everywhere.

Additionally, this commit introduces a single static method to check that
the current code has permission. This avoids all the duplicated access
blocks that exist currently.
  • Loading branch information
Tim-Brooks committed Jan 21, 2017
1 parent 3ad6d6e commit a4ac29c
Show file tree
Hide file tree
Showing 21 changed files with 64 additions and 167 deletions.
13 changes: 13 additions & 0 deletions core/src/main/java/org/elasticsearch/SpecialPermission.java
Expand Up @@ -57,6 +57,9 @@
* </code></pre>
*/
public final class SpecialPermission extends BasicPermission {

public static final SpecialPermission INSTANCE = new SpecialPermission();

/**
* Creates a new SpecialPermision object.
*/
Expand All @@ -76,4 +79,14 @@ public SpecialPermission() {
public SpecialPermission(String name, String actions) {
this();
}

/**
* Check that the current stack has {@link SpecialPermission} access according to the {@link SecurityManager}.
*/
public static void check() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(INSTANCE);
}
}
}
10 changes: 7 additions & 3 deletions core/src/test/java/org/elasticsearch/SpecialPermissionTests.java
Expand Up @@ -25,14 +25,18 @@

/** Very simple sanity checks for {@link SpecialPermission} */
public class SpecialPermissionTests extends ESTestCase {

public void testEquals() {
assertEquals(new SpecialPermission(), new SpecialPermission());
assertEquals(SpecialPermission.INSTANCE, new SpecialPermission());
assertFalse(new SpecialPermission().equals(new AllPermission()));
assertFalse(SpecialPermission.INSTANCE.equals(new AllPermission()));
}

public void testImplies() {
assertTrue(new SpecialPermission().implies(new SpecialPermission()));
assertTrue(SpecialPermission.INSTANCE.implies(new SpecialPermission()));
assertTrue(SpecialPermission.INSTANCE.implies(SpecialPermission.INSTANCE));
assertFalse(new SpecialPermission().implies(new AllPermission()));
assertFalse(SpecialPermission.INSTANCE.implies(new AllPermission()));
}
}
Expand Up @@ -78,9 +78,7 @@ public String getExtension() {
public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
// classloader created here
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new SpecialPermission());
}
SpecialPermission.check();
return AccessController.doPrivileged(new PrivilegedAction<Expression>() {
@Override
public Expression run() {
Expand Down
Expand Up @@ -127,9 +127,6 @@ public void close() {
// Nothing to do here
}

// permission checked before doing crazy reflection
static final SpecialPermission SPECIAL_PERMISSION = new SpecialPermission();

/**
* Used at query execution time by script service in order to execute a query template.
* */
Expand Down Expand Up @@ -158,10 +155,7 @@ public Object run() {
final BytesStreamOutput result = new BytesStreamOutput();
try (UTF8StreamWriter writer = utf8StreamWriter().setOutput(result)) {
// crazy reflection here
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SPECIAL_PERMISSION);
}
SpecialPermission.check();
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
((Mustache) template.compiled()).execute(writer, vars);
return null;
Expand Down
Expand Up @@ -149,11 +149,7 @@ public Object compile(String scriptName, final String scriptSource, final Map<St
}

// Check we ourselves are not being called by unprivileged code.
final SecurityManager sm = System.getSecurityManager();

if (sm != null) {
sm.checkPermission(new SpecialPermission());
}
SpecialPermission.check();

// Create our loader (which loads compiled code with no permissions).
final Loader loader = AccessController.doPrivileged(new PrivilegedAction<Loader>() {
Expand Down
Expand Up @@ -37,10 +37,7 @@ 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());
}
SpecialPermission.check();
try {
return AccessController.doPrivileged((PrivilegedExceptionAction<Integer>) () -> super.doReadMessages(buf));
} catch (PrivilegedActionException e) {
Expand Down
Expand Up @@ -37,10 +37,7 @@ 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());
}
SpecialPermission.check();
try {
return AccessController.doPrivileged((PrivilegedExceptionAction<Boolean>) () -> super.doConnect(remoteAddress, localAddress));
} catch (PrivilegedActionException e) {
Expand Down
Expand Up @@ -20,9 +20,7 @@
package org.elasticsearch.cloud.azure.classic.management;

import java.io.IOException;
import java.net.URISyntaxException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ServiceLoader;
Expand All @@ -31,7 +29,6 @@
import com.microsoft.windowsazure.core.Builder;
import com.microsoft.windowsazure.core.DefaultBuilder;
import com.microsoft.windowsazure.core.utils.KeyStoreType;
import com.microsoft.windowsazure.exception.ServiceException;
import com.microsoft.windowsazure.management.compute.ComputeManagementClient;
import com.microsoft.windowsazure.management.compute.ComputeManagementService;
import com.microsoft.windowsazure.management.compute.models.HostedServiceGetDetailedResponse;
Expand All @@ -43,9 +40,6 @@
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;

public class AzureComputeServiceImpl extends AbstractLifecycleComponent
implements AzureComputeService {
Expand Down Expand Up @@ -99,10 +93,7 @@ private static String getRequiredSetting(Settings settings, Setting<String> sett

@Override
public HostedServiceGetDetailedResponse getServiceDetails() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new SpecialPermission());
}
SpecialPermission.check();
try {
return AccessController.doPrivileged((PrivilegedExceptionAction<HostedServiceGetDetailedResponse>)
() -> client.getHostedServicesOperations().getDetailed(serviceName));
Expand Down
Expand Up @@ -35,28 +35,20 @@
*/
public final class SocketAccess {

private static final SpecialPermission SPECIAL_PERMISSION = new SpecialPermission();

private SocketAccess() {}

public static <T> T doPrivileged(PrivilegedAction<T> operation) {
checkSpecialPermission();
SpecialPermission.check();
return AccessController.doPrivileged(operation);
}

public static <T> T doPrivilegedIOException(PrivilegedExceptionAction<T> operation) throws IOException {
checkSpecialPermission();
SpecialPermission.check();
try {
return AccessController.doPrivileged(operation);
} catch (PrivilegedActionException e) {
throw (IOException) e.getCause();
}
}

private static void checkSpecialPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SPECIAL_PERMISSION);
}
}
}
Expand Up @@ -71,10 +71,7 @@ public class Ec2DiscoveryPlugin extends Plugin implements DiscoveryPlugin, Close
public static final String EC2 = "ec2";

static {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new SpecialPermission());
}
SpecialPermission.check();
// Initializing Jackson requires RuntimePermission accessDeclaredMembers
// The ClientConfiguration class requires RuntimePermission getClassLoader
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
Expand Down
Expand Up @@ -35,39 +35,30 @@
*/
public final class Access {

private static final SpecialPermission SPECIAL_PERMISSION = new SpecialPermission();

private Access() {}

public static <T> T doPrivileged(PrivilegedAction<T> operation) {
checkSpecialPermission();
SpecialPermission.check();
return AccessController.doPrivileged(operation);
}

public static void doPrivilegedVoid(DiscoveryRunnable action) {
checkSpecialPermission();
SpecialPermission.check();
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
action.execute();
return null;
});
}

public static <T> T doPrivilegedIOException(PrivilegedExceptionAction<T> operation) throws IOException {
checkSpecialPermission();
SpecialPermission.check();
try {
return AccessController.doPrivileged(operation);
} catch (PrivilegedActionException e) {
throw (IOException) e.getCause();
}
}

private static void checkSpecialPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SPECIAL_PERMISSION);
}
}

@FunctionalInterface
public interface DiscoveryRunnable {
void execute();
Expand Down
Expand Up @@ -82,18 +82,11 @@ final class TikaImpl {
// only package private for testing!
static String parse(final byte content[], final Metadata metadata, final int limit) throws TikaException, IOException {
// check that its not unprivileged code like a script
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new SpecialPermission());
}
SpecialPermission.check();

try {
return AccessController.doPrivileged(new PrivilegedExceptionAction<String>() {
@Override
public String run() throws TikaException, IOException {
return TIKA_INSTANCE.parseToString(new ByteArrayInputStream(content), metadata, limit);
}
}, RESTRICTED_CONTEXT);
return AccessController.doPrivileged((PrivilegedExceptionAction<String>)
() -> TIKA_INSTANCE.parseToString(new ByteArrayInputStream(content), metadata, limit), RESTRICTED_CONTEXT);
} catch (PrivilegedActionException e) {
// checked exception from tika: unbox it
Throwable cause = e.getCause();
Expand Down
Expand Up @@ -139,10 +139,7 @@ Set<Property> getProperties() {
}

private Map<String, Object> retrieveCityGeoData(InetAddress ipAddress) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new SpecialPermission());
}
SpecialPermission.check();
CityResponse response = AccessController.doPrivileged((PrivilegedAction<CityResponse>) () -> {
try {
return dbReader.city(ipAddress);
Expand Down Expand Up @@ -217,10 +214,7 @@ private Map<String, Object> retrieveCityGeoData(InetAddress ipAddress) {
}

private Map<String, Object> retrieveCountryGeoData(InetAddress ipAddress) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new SpecialPermission());
}
SpecialPermission.check();
CountryResponse response = AccessController.doPrivileged((PrivilegedAction<CountryResponse>) () -> {
try {
return dbReader.country(ipAddress);
Expand Down
Expand Up @@ -36,12 +36,10 @@
*/
public final class SocketAccess {

private static final SpecialPermission SPECIAL_PERMISSION = new SpecialPermission();

private SocketAccess() {}

public static <T> T doPrivilegedException(PrivilegedExceptionAction<T> operation) throws StorageException, URISyntaxException {
checkSpecialPermission();
SpecialPermission.check();
try {
return AccessController.doPrivileged(operation);
} catch (PrivilegedActionException e) {
Expand All @@ -50,7 +48,7 @@ public static <T> T doPrivilegedException(PrivilegedExceptionAction<T> operation
}

public static void doPrivilegedVoidException(StorageRunnable action) throws StorageException, URISyntaxException {
checkSpecialPermission();
SpecialPermission.check();
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
action.executeCouldThrow();
Expand All @@ -66,13 +64,6 @@ public static void doPrivilegedVoidException(StorageRunnable action) throws Stor
}
}

private static void checkSpecialPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SPECIAL_PERMISSION);
}
}

@FunctionalInterface
public interface StorageRunnable {
void executeCouldThrow() throws StorageException, URISyntaxException;
Expand Down
Expand Up @@ -35,12 +35,10 @@
*/
public final class SocketAccess {

private static final SpecialPermission SPECIAL_PERMISSION = new SpecialPermission();

private SocketAccess() {}

public static <T> T doPrivilegedIOException(PrivilegedExceptionAction<T> operation) throws IOException {
checkSpecialPermission();
SpecialPermission.check();
try {
return AccessController.doPrivileged(operation);
} catch (PrivilegedActionException e) {
Expand All @@ -49,7 +47,7 @@ public static <T> T doPrivilegedIOException(PrivilegedExceptionAction<T> operati
}

public static void doPrivilegedVoidIOException(StorageRunnable action) throws IOException {
checkSpecialPermission();
SpecialPermission.check();
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
action.executeCouldThrow();
Expand All @@ -60,13 +58,6 @@ public static void doPrivilegedVoidIOException(StorageRunnable action) throws IO
}
}

private static void checkSpecialPermission() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SPECIAL_PERMISSION);
}
}

@FunctionalInterface
public interface StorageRunnable {
void executeCouldThrow() throws IOException;
Expand Down
Expand Up @@ -21,7 +21,6 @@

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;

Expand All @@ -40,13 +39,10 @@
import com.google.api.services.storage.model.Objects;
import com.google.api.services.storage.model.StorageObject;
import org.elasticsearch.SpecialPermission;
import org.elasticsearch.common.inject.Module;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.env.Environment;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.plugins.RepositoryPlugin;
import org.elasticsearch.repositories.RepositoriesModule;
import org.elasticsearch.repositories.Repository;
import org.elasticsearch.repositories.gcs.GoogleCloudStorageRepository;
import org.elasticsearch.repositories.gcs.GoogleCloudStorageService;
Expand All @@ -64,10 +60,7 @@ public class GoogleCloudStoragePlugin extends Plugin implements RepositoryPlugin
* our plugin permissions don't allow core to "reach through" plugins to
* change the permission. Because that'd be silly.
*/
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new SpecialPermission());
}
SpecialPermission.check();
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
// ClassInfo put in cache all the fields of a given class
// that are annoted with @Key; at the same time it changes
Expand Down

0 comments on commit a4ac29c

Please sign in to comment.