Skip to content

Commit

Permalink
Ensure that azure stream has socket privileges (#28773)
Browse files Browse the repository at this point in the history
This is related to #28662. It wraps the azure repository inputstream in
an inputstream that ensures `read` calls have socket permissions. This
is because the azure inputstream internally makes service calls.
  • Loading branch information
Tim-Brooks committed Feb 21, 2018
1 parent 114938b commit db4ed5f
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ public final class SocketAccess {

private SocketAccess() {}

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

public static <T> T doPrivilegedException(PrivilegedExceptionAction<T> operation) throws StorageException, URISyntaxException {
SpecialPermission.check();
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import com.microsoft.azure.storage.LocationMode;
import com.microsoft.azure.storage.StorageException;
import org.elasticsearch.cloud.azure.blobstore.util.SocketAccess;
import org.elasticsearch.common.blobstore.BlobMetaData;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
Expand Down Expand Up @@ -82,4 +83,23 @@ void moveBlob(String account, LocationMode mode, String container, String source

void writeBlob(String account, LocationMode mode, String container, String blobName, InputStream inputStream, long blobSize) throws
URISyntaxException, StorageException;

static InputStream giveSocketPermissionsToStream(InputStream stream) {
return new InputStream() {
@Override
public int read() throws IOException {
return SocketAccess.doPrivilegedIOException(stream::read);
}

@Override
public int read(byte[] b) throws IOException {
return SocketAccess.doPrivilegedIOException(() -> stream.read(b));
}

@Override
public int read(byte[] b, int off, int len) throws IOException {
return SocketAccess.doPrivilegedIOException(() -> stream.read(b, off, len));
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.microsoft.azure.storage.RetryExponentialRetry;
import com.microsoft.azure.storage.RetryPolicy;
import com.microsoft.azure.storage.StorageException;
import com.microsoft.azure.storage.blob.BlobInputStream;
import com.microsoft.azure.storage.blob.BlobListingDetails;
import com.microsoft.azure.storage.blob.BlobProperties;
import com.microsoft.azure.storage.blob.CloudBlobClient;
Expand Down Expand Up @@ -292,7 +293,9 @@ public InputStream getInputStream(String account, LocationMode mode, String cont
logger.trace("reading container [{}], blob [{}]", container, blob);
CloudBlobClient client = this.getSelectedClient(account, mode);
CloudBlockBlob blockBlobReference = client.getContainerReference(container).getBlockBlobReference(blob);
return SocketAccess.doPrivilegedException(() -> blockBlobReference.openInputStream(null, null, generateOperationContext(account)));
BlobInputStream stream = SocketAccess.doPrivilegedException(() ->
blockBlobReference.openInputStream(null, null, generateOperationContext(account)));
return AzureStorageService.giveSocketPermissionsToStream(stream);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketPermission;
import java.net.URISyntaxException;
import java.nio.file.NoSuchFileException;
import java.security.AccessController;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
Expand Down Expand Up @@ -81,7 +83,7 @@ public InputStream getInputStream(String account, LocationMode mode, String cont
if (!blobExists(account, mode, container, blob)) {
throw new NoSuchFileException("missing blob [" + blob + "]");
}
return new ByteArrayInputStream(blobs.get(blob).toByteArray());
return AzureStorageService.giveSocketPermissionsToStream(new PermissionRequiringInputStream(blobs.get(blob).toByteArray()));
}

@Override
Expand Down Expand Up @@ -169,4 +171,29 @@ public static boolean endsWithIgnoreCase(String str, String suffix) {
String lcPrefix = suffix.toLowerCase(Locale.ROOT);
return lcStr.equals(lcPrefix);
}

private static class PermissionRequiringInputStream extends ByteArrayInputStream {

private PermissionRequiringInputStream(byte[] buf) {
super(buf);
}

@Override
public synchronized int read() {
AccessController.checkPermission(new SocketPermission("*", "connect"));
return super.read();
}

@Override
public int read(byte[] b) throws IOException {
AccessController.checkPermission(new SocketPermission("*", "connect"));
return super.read(b);
}

@Override
public synchronized int read(byte[] b, int off, int len) {
AccessController.checkPermission(new SocketPermission("*", "connect"));
return super.read(b, off, len);
}
}
}

0 comments on commit db4ed5f

Please sign in to comment.