Skip to content

Commit 59411c8

Browse files
committed
Instrumentation of NIO file channels
1 parent 19fe0a4 commit 59411c8

File tree

5 files changed

+126
-0
lines changed

5 files changed

+126
-0
lines changed

libs/entitlement/bridge/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// At build and run time, the bridge is patched into the java.base module.
1212
module org.elasticsearch.entitlement.bridge {
1313
requires java.net.http;
14+
requires jdk.net;
1415

1516
exports org.elasticsearch.entitlement.bridge;
1617
}

libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99

1010
package org.elasticsearch.entitlement.bridge;
1111

12+
import jdk.nio.Channels;
13+
1214
import java.io.File;
15+
import java.io.FileDescriptor;
1316
import java.io.FileFilter;
1417
import java.io.FilenameFilter;
1518
import java.io.InputStream;
@@ -587,6 +590,36 @@ public interface EntitlementChecker {
587590
void check$java_util_Scanner$(Class<?> callerClass, File source, Charset charset);
588591

589592
// nio
593+
// channels
594+
void check$java_nio_channels_FileChannel$(Class<?> callerClass);
595+
596+
void check$java_nio_channels_FileChannel$$open(
597+
Class<?> callerClass,
598+
Path path,
599+
Set<? extends OpenOption> options,
600+
FileAttribute<?>... attrs
601+
);
602+
603+
void check$java_nio_channels_FileChannel$$open(Class<?> callerClass, Path path, OpenOption... options);
604+
605+
void check$java_nio_channels_AsynchronousFileChannel$(Class<?> callerClass);
606+
607+
void check$java_nio_channels_AsynchronousFileChannel$$open(
608+
Class<?> callerClass,
609+
Path path,
610+
Set<? extends OpenOption> options,
611+
FileAttribute<?>... attrs
612+
);
613+
614+
void check$java_nio_channels_AsynchronousFileChannel$$open(Class<?> callerClass, Path path, OpenOption... options);
615+
616+
void check$jdk_nio_Channels$$readWriteSelectableChannel(
617+
Class<?> callerClass,
618+
FileDescriptor fd,
619+
Channels.SelectableChannelCloser closer
620+
);
621+
622+
// files
590623
void check$java_nio_file_Files$$getOwner(Class<?> callerClass, Path path, LinkOption... options);
591624

592625
void check$java_nio_file_Files$$probeContentType(Class<?> callerClass, Path path);

libs/entitlement/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
requires org.elasticsearch.base;
1515
requires jdk.attach;
1616
requires java.net.http;
17+
requires jdk.net;
1718

1819
requires static org.elasticsearch.entitlement.bridge; // At runtime, this will be in java.base
1920

libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99

1010
package org.elasticsearch.entitlement.runtime.api;
1111

12+
import jdk.nio.Channels;
13+
1214
import org.elasticsearch.core.SuppressForbidden;
1315
import org.elasticsearch.entitlement.bridge.EntitlementChecker;
1416
import org.elasticsearch.entitlement.runtime.policy.PolicyManager;
1517

1618
import java.io.File;
19+
import java.io.FileDescriptor;
1720
import java.io.FileFilter;
1821
import java.io.FilenameFilter;
1922
import java.io.IOException;
@@ -74,6 +77,7 @@
7477
import java.nio.file.attribute.UserPrincipal;
7578
import java.nio.file.spi.FileSystemProvider;
7679
import java.security.cert.CertStoreParameters;
80+
import java.util.Arrays;
7781
import java.util.List;
7882
import java.util.Locale;
7983
import java.util.Map;
@@ -1140,6 +1144,71 @@ public void checkSelectorProviderInheritedChannel(Class<?> callerClass, Selector
11401144

11411145
// nio
11421146

1147+
@Override
1148+
public void check$java_nio_channels_FileChannel$(Class<?> callerClass) {
1149+
policyManager.checkChangeFilesHandling(callerClass);
1150+
}
1151+
1152+
@Override
1153+
public void check$java_nio_channels_FileChannel$$open(
1154+
Class<?> callerClass,
1155+
Path path,
1156+
Set<? extends OpenOption> options,
1157+
FileAttribute<?>... attrs
1158+
) {
1159+
if (isOpenForWrite(options)) {
1160+
policyManager.checkFileWrite(callerClass, path);
1161+
} else {
1162+
policyManager.checkFileRead(callerClass, path);
1163+
}
1164+
}
1165+
1166+
@Override
1167+
public void check$java_nio_channels_FileChannel$$open(Class<?> callerClass, Path path, OpenOption... options) {
1168+
if (isOpenForWrite(options)) {
1169+
policyManager.checkFileWrite(callerClass, path);
1170+
} else {
1171+
policyManager.checkFileRead(callerClass, path);
1172+
}
1173+
}
1174+
1175+
@Override
1176+
public void check$java_nio_channels_AsynchronousFileChannel$(Class<?> callerClass) {
1177+
policyManager.checkChangeFilesHandling(callerClass);
1178+
}
1179+
1180+
@Override
1181+
public void check$java_nio_channels_AsynchronousFileChannel$$open(
1182+
Class<?> callerClass,
1183+
Path path,
1184+
Set<? extends OpenOption> options,
1185+
FileAttribute<?>... attrs
1186+
) {
1187+
if (isOpenForWrite(options)) {
1188+
policyManager.checkFileWrite(callerClass, path);
1189+
} else {
1190+
policyManager.checkFileRead(callerClass, path);
1191+
}
1192+
}
1193+
1194+
@Override
1195+
public void check$java_nio_channels_AsynchronousFileChannel$$open(Class<?> callerClass, Path path, OpenOption... options) {
1196+
if (isOpenForWrite(options)) {
1197+
policyManager.checkFileWrite(callerClass, path);
1198+
} else {
1199+
policyManager.checkFileRead(callerClass, path);
1200+
}
1201+
}
1202+
1203+
@Override
1204+
public void check$jdk_nio_Channels$$readWriteSelectableChannel(
1205+
Class<?> callerClass,
1206+
FileDescriptor fd,
1207+
Channels.SelectableChannelCloser closer
1208+
) {
1209+
policyManager.checkFileDescriptorWrite(callerClass);
1210+
}
1211+
11431212
@Override
11441213
public void check$java_nio_file_Files$$getOwner(Class<?> callerClass, Path path, LinkOption... options) {
11451214
policyManager.checkFileRead(callerClass, path);
@@ -1190,6 +1259,17 @@ private static boolean isOpenForWrite(Set<? extends OpenOption> options) {
11901259
|| options.contains(StandardOpenOption.DELETE_ON_CLOSE);
11911260
}
11921261

1262+
private static boolean isOpenForWrite(OpenOption... options) {
1263+
return Arrays.stream(options)
1264+
.anyMatch(
1265+
o -> o.equals(StandardOpenOption.WRITE)
1266+
|| o.equals(StandardOpenOption.APPEND)
1267+
|| o.equals(StandardOpenOption.CREATE)
1268+
|| o.equals(StandardOpenOption.CREATE_NEW)
1269+
|| o.equals(StandardOpenOption.DELETE_ON_CLOSE)
1270+
);
1271+
}
1272+
11931273
@Override
11941274
public void checkNewFileChannel(
11951275
Class<?> callerClass,

libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/PolicyManager.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,13 @@ public void checkChangeNetworkHandling(Class<?> callerClass) {
254254
checkChangeJVMGlobalState(callerClass);
255255
}
256256

257+
/**
258+
* Check for operations that can modify the way file operations are handled
259+
*/
260+
public void checkChangeFilesHandling(Class<?> callerClass) {
261+
checkChangeJVMGlobalState(callerClass);
262+
}
263+
257264
@SuppressForbidden(reason = "Explicitly checking File apis")
258265
public void checkFileRead(Class<?> callerClass, File file) {
259266
checkFileRead(callerClass, file.toPath());
@@ -304,6 +311,10 @@ public void checkFileWrite(Class<?> callerClass, Path path) {
304311
}
305312
}
306313

314+
public void checkFileDescriptorWrite(Class<?> callerClass) {
315+
neverEntitled(callerClass, () -> "write file descriptor");
316+
}
317+
307318
/**
308319
* Invoked when we try to get an arbitrary {@code FileAttributeView} class. Such a class can modify attributes, like owner etc.;
309320
* we could think about introducing checks for each of the operations, but for now we over-approximate this and simply deny when it is

0 commit comments

Comments
 (0)