Skip to content

Commit 42f23c0

Browse files
committed
Add entitlement checks for java.io stream classes (elastic#122406)
(cherry picked from commit 8eb89cf) # Conflicts: # libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java # libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java
1 parent 46387fb commit 42f23c0

File tree

8 files changed

+291
-0
lines changed

8 files changed

+291
-0
lines changed

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
package org.elasticsearch.entitlement.bridge;
1111

1212
import java.io.File;
13+
import java.io.FileDescriptor;
1314
import java.io.InputStream;
1415
import java.io.PrintStream;
1516
import java.io.PrintWriter;
@@ -480,14 +481,54 @@ public interface EntitlementChecker {
480481

481482
void check$java_io_File$setWritable(Class<?> callerClass, File file, boolean writable, boolean ownerOnly);
482483

484+
void check$java_io_FileInputStream$(Class<?> callerClass, File file);
485+
486+
void check$java_io_FileInputStream$(Class<?> callerClass, FileDescriptor fd);
487+
488+
void check$java_io_FileInputStream$(Class<?> callerClass, String name);
489+
483490
void check$java_io_FileOutputStream$(Class<?> callerClass, File file);
484491

485492
void check$java_io_FileOutputStream$(Class<?> callerClass, File file, boolean append);
486493

494+
void check$java_io_FileOutputStream$(Class<?> callerClass, FileDescriptor fd);
495+
487496
void check$java_io_FileOutputStream$(Class<?> callerClass, String name);
488497

489498
void check$java_io_FileOutputStream$(Class<?> callerClass, String name, boolean append);
490499

500+
void check$java_io_FileReader$(Class<?> callerClass, File file);
501+
502+
void check$java_io_FileReader$(Class<?> callerClass, File file, Charset charset);
503+
504+
void check$java_io_FileReader$(Class<?> callerClass, FileDescriptor fd);
505+
506+
void check$java_io_FileReader$(Class<?> callerClass, String name);
507+
508+
void check$java_io_FileReader$(Class<?> callerClass, String name, Charset charset);
509+
510+
void check$java_io_FileWriter$(Class<?> callerClass, File file);
511+
512+
void check$java_io_FileWriter$(Class<?> callerClass, File file, boolean append);
513+
514+
void check$java_io_FileWriter$(Class<?> callerClass, File file, Charset charset);
515+
516+
void check$java_io_FileWriter$(Class<?> callerClass, File file, Charset charset, boolean append);
517+
518+
void check$java_io_FileWriter$(Class<?> callerClass, FileDescriptor fd);
519+
520+
void check$java_io_FileWriter$(Class<?> callerClass, String name);
521+
522+
void check$java_io_FileWriter$(Class<?> callerClass, String name, boolean append);
523+
524+
void check$java_io_FileWriter$(Class<?> callerClass, String name, Charset charset);
525+
526+
void check$java_io_FileWriter$(Class<?> callerClass, String name, Charset charset, boolean append);
527+
528+
void check$java_io_RandomAccessFile$(Class<?> callerClass, String name, String mode);
529+
530+
void check$java_io_RandomAccessFile$(Class<?> callerClass, File file, String mode);
531+
491532
void check$java_util_Scanner$(Class<?> callerClass, File source);
492533

493534
void check$java_util_Scanner$(Class<?> callerClass, File source, String charsetName);

libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/FileCheckActions.java

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,22 @@
1313
import org.elasticsearch.entitlement.qa.entitled.EntitledActions;
1414

1515
import java.io.File;
16+
import java.io.FileDescriptor;
17+
import java.io.FileInputStream;
1618
import java.io.FileNotFoundException;
1719
import java.io.FileOutputStream;
20+
import java.io.FileReader;
21+
import java.io.FileWriter;
1822
import java.io.IOException;
23+
import java.io.RandomAccessFile;
1924
import java.nio.charset.StandardCharsets;
2025
import java.nio.file.Files;
2126
import java.nio.file.Path;
2227
import java.nio.file.Paths;
2328
import java.nio.file.attribute.UserPrincipal;
2429
import java.util.Scanner;
2530

31+
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.ALWAYS_DENIED;
2632
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.PLUGINS;
2733

2834
@SuppressForbidden(reason = "Explicitly checking APIs that are forbidden")
@@ -146,6 +152,21 @@ static void createScannerFileWithCharsetName() throws FileNotFoundException {
146152
new Scanner(readFile().toFile(), "UTF-8");
147153
}
148154

155+
@EntitlementTest(expectedAccess = PLUGINS)
156+
static void createFileInputStreamFile() throws IOException {
157+
new FileInputStream(readFile().toFile()).close();
158+
}
159+
160+
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
161+
static void createFileInputStreamFileDescriptor() throws IOException {
162+
new FileInputStream(FileDescriptor.in).close();
163+
}
164+
165+
@EntitlementTest(expectedAccess = PLUGINS)
166+
static void createFileInputStreamString() throws IOException {
167+
new FileInputStream(readFile().toString()).close();
168+
}
169+
149170
@EntitlementTest(expectedAccess = PLUGINS)
150171
static void createFileOutputStreamString() throws IOException {
151172
new FileOutputStream(readWriteFile().toString()).close();
@@ -166,6 +187,96 @@ static void createFileOutputStreamFileWithAppend() throws IOException {
166187
new FileOutputStream(readWriteFile().toFile(), false).close();
167188
}
168189

190+
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
191+
static void createFileOutputStreamFileDescriptor() throws IOException {
192+
new FileOutputStream(FileDescriptor.out).close();
193+
}
194+
195+
@EntitlementTest(expectedAccess = PLUGINS)
196+
static void createFileReaderFile() throws IOException {
197+
new FileReader(readFile().toFile()).close();
198+
}
199+
200+
@EntitlementTest(expectedAccess = PLUGINS)
201+
static void createFileReaderFileCharset() throws IOException {
202+
new FileReader(readFile().toFile(), StandardCharsets.UTF_8).close();
203+
}
204+
205+
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
206+
static void createFileReaderFileDescriptor() throws IOException {
207+
new FileReader(FileDescriptor.in).close();
208+
}
209+
210+
@EntitlementTest(expectedAccess = PLUGINS)
211+
static void createFileReaderString() throws IOException {
212+
new FileReader(readFile().toString()).close();
213+
}
214+
215+
@EntitlementTest(expectedAccess = PLUGINS)
216+
static void createFileReaderStringCharset() throws IOException {
217+
new FileReader(readFile().toString(), StandardCharsets.UTF_8).close();
218+
}
219+
220+
@EntitlementTest(expectedAccess = PLUGINS)
221+
static void createFileWriterFile() throws IOException {
222+
new FileWriter(readWriteFile().toFile()).close();
223+
}
224+
225+
@EntitlementTest(expectedAccess = PLUGINS)
226+
static void createFileWriterFileWithAppend() throws IOException {
227+
new FileWriter(readWriteFile().toFile(), false).close();
228+
}
229+
230+
@EntitlementTest(expectedAccess = PLUGINS)
231+
static void createFileWriterFileCharsetWithAppend() throws IOException {
232+
new FileWriter(readWriteFile().toFile(), StandardCharsets.UTF_8, false).close();
233+
}
234+
235+
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
236+
static void createFileWriterFileDescriptor() throws IOException {
237+
new FileWriter(FileDescriptor.out).close();
238+
}
239+
240+
@EntitlementTest(expectedAccess = PLUGINS)
241+
static void createFileWriterString() throws IOException {
242+
new FileWriter(readWriteFile().toString()).close();
243+
}
244+
245+
@EntitlementTest(expectedAccess = PLUGINS)
246+
static void createFileWriterStringWithAppend() throws IOException {
247+
new FileWriter(readWriteFile().toString(), false).close();
248+
}
249+
250+
@EntitlementTest(expectedAccess = PLUGINS)
251+
static void createFileWriterStringCharset() throws IOException {
252+
new FileWriter(readWriteFile().toString(), StandardCharsets.UTF_8).close();
253+
}
254+
255+
@EntitlementTest(expectedAccess = PLUGINS)
256+
static void createFileWriterStringCharsetWithAppend() throws IOException {
257+
new FileWriter(readWriteFile().toString(), StandardCharsets.UTF_8, false).close();
258+
}
259+
260+
@EntitlementTest(expectedAccess = PLUGINS)
261+
static void createRandomAccessFileStringRead() throws IOException {
262+
new RandomAccessFile(readFile().toString(), "r").close();
263+
}
264+
265+
@EntitlementTest(expectedAccess = PLUGINS)
266+
static void createRandomAccessFileStringReadWrite() throws IOException {
267+
new RandomAccessFile(readWriteFile().toString(), "rw").close();
268+
}
269+
270+
@EntitlementTest(expectedAccess = PLUGINS)
271+
static void createRandomAccessFileRead() throws IOException {
272+
new RandomAccessFile(readFile().toFile(), "r").close();
273+
}
274+
275+
@EntitlementTest(expectedAccess = PLUGINS)
276+
static void createRandomAccessFileReadWrite() throws IOException {
277+
new RandomAccessFile(readWriteFile().toFile(), "rw").close();
278+
}
279+
169280
@EntitlementTest(expectedAccess = PLUGINS)
170281
static void filesGetOwner() throws IOException {
171282
Files.getOwner(readFile());

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

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.elasticsearch.entitlement.runtime.policy.PolicyManager;
1515

1616
import java.io.File;
17+
import java.io.FileDescriptor;
1718
import java.io.IOException;
1819
import java.io.InputStream;
1920
import java.io.PrintStream;
@@ -944,6 +945,21 @@ public void checkSelectorProviderInheritedChannel(Class<?> callerClass, Selector
944945
policyManager.checkFileWrite(callerClass, file);
945946
}
946947

948+
@Override
949+
public void check$java_io_FileInputStream$(Class<?> callerClass, File file) {
950+
policyManager.checkFileRead(callerClass, file);
951+
}
952+
953+
@Override
954+
public void check$java_io_FileInputStream$(Class<?> callerClass, FileDescriptor fd) {
955+
policyManager.checkFileDescriptorRead(callerClass);
956+
}
957+
958+
@Override
959+
public void check$java_io_FileInputStream$(Class<?> callerClass, String name) {
960+
policyManager.checkFileRead(callerClass, new File(name));
961+
}
962+
947963
@Override
948964
public void check$java_io_FileOutputStream$(Class<?> callerClass, String name) {
949965
policyManager.checkFileWrite(callerClass, new File(name));
@@ -964,6 +980,99 @@ public void checkSelectorProviderInheritedChannel(Class<?> callerClass, Selector
964980
policyManager.checkFileWrite(callerClass, file);
965981
}
966982

983+
@Override
984+
public void check$java_io_FileOutputStream$(Class<?> callerClass, FileDescriptor fd) {
985+
policyManager.checkFileDescriptorWrite(callerClass);
986+
}
987+
988+
@Override
989+
public void check$java_io_FileReader$(Class<?> callerClass, File file) {
990+
policyManager.checkFileRead(callerClass, file);
991+
}
992+
993+
@Override
994+
public void check$java_io_FileReader$(Class<?> callerClass, File file, Charset charset) {
995+
policyManager.checkFileRead(callerClass, file);
996+
}
997+
998+
@Override
999+
public void check$java_io_FileReader$(Class<?> callerClass, FileDescriptor fd) {
1000+
policyManager.checkFileDescriptorRead(callerClass);
1001+
}
1002+
1003+
@Override
1004+
public void check$java_io_FileReader$(Class<?> callerClass, String name) {
1005+
policyManager.checkFileRead(callerClass, new File(name));
1006+
}
1007+
1008+
@Override
1009+
public void check$java_io_FileReader$(Class<?> callerClass, String name, Charset charset) {
1010+
policyManager.checkFileRead(callerClass, new File(name));
1011+
}
1012+
1013+
@Override
1014+
public void check$java_io_FileWriter$(Class<?> callerClass, File file) {
1015+
policyManager.checkFileWrite(callerClass, file);
1016+
}
1017+
1018+
@Override
1019+
public void check$java_io_FileWriter$(Class<?> callerClass, File file, boolean append) {
1020+
policyManager.checkFileWrite(callerClass, file);
1021+
}
1022+
1023+
@Override
1024+
public void check$java_io_FileWriter$(Class<?> callerClass, File file, Charset charset) {
1025+
policyManager.checkFileWrite(callerClass, file);
1026+
}
1027+
1028+
@Override
1029+
public void check$java_io_FileWriter$(Class<?> callerClass, File file, Charset charset, boolean append) {
1030+
policyManager.checkFileWrite(callerClass, file);
1031+
}
1032+
1033+
@Override
1034+
public void check$java_io_FileWriter$(Class<?> callerClass, FileDescriptor fd) {
1035+
policyManager.checkFileDescriptorWrite(callerClass);
1036+
}
1037+
1038+
@Override
1039+
public void check$java_io_FileWriter$(Class<?> callerClass, String name) {
1040+
policyManager.checkFileWrite(callerClass, new File(name));
1041+
}
1042+
1043+
@Override
1044+
public void check$java_io_FileWriter$(Class<?> callerClass, String name, boolean append) {
1045+
policyManager.checkFileWrite(callerClass, new File(name));
1046+
}
1047+
1048+
@Override
1049+
public void check$java_io_FileWriter$(Class<?> callerClass, String name, Charset charset) {
1050+
policyManager.checkFileWrite(callerClass, new File(name));
1051+
}
1052+
1053+
@Override
1054+
public void check$java_io_FileWriter$(Class<?> callerClass, String name, Charset charset, boolean append) {
1055+
policyManager.checkFileWrite(callerClass, new File(name));
1056+
}
1057+
1058+
@Override
1059+
public void check$java_io_RandomAccessFile$(Class<?> callerClass, String name, String mode) {
1060+
if (mode.equals("r")) {
1061+
policyManager.checkFileRead(callerClass, new File(name));
1062+
} else {
1063+
policyManager.checkFileWrite(callerClass, new File(name));
1064+
}
1065+
}
1066+
1067+
@Override
1068+
public void check$java_io_RandomAccessFile$(Class<?> callerClass, File file, String mode) {
1069+
if (mode.equals("r")) {
1070+
policyManager.checkFileRead(callerClass, file);
1071+
} else {
1072+
policyManager.checkFileWrite(callerClass, file);
1073+
}
1074+
}
1075+
9671076
@Override
9681077
public void check$java_util_Scanner$(Class<?> callerClass, File source) {
9691078
policyManager.checkFileRead(callerClass, source);

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,14 @@ public void checkFileWrite(Class<?> callerClass, Path path) {
304304
}
305305
}
306306

307+
public void checkFileDescriptorRead(Class<?> callerClass) {
308+
neverEntitled(callerClass, () -> "read file descriptor");
309+
}
310+
311+
public void checkFileDescriptorWrite(Class<?> callerClass) {
312+
neverEntitled(callerClass, () -> "write file descriptor");
313+
}
314+
307315
/**
308316
* Invoked when we try to get an arbitrary {@code FileAttributeView} class. Such a class can modify attributes, like owner etc.;
309317
* we could think about introducing checks for each of the operations, but for now we over-approximate this and simply deny when it is
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
com.maxmind.db:
2+
- files:
3+
- relative_path: "ingest-geoip/"
4+
relative_to: "config"
5+
mode: "read_write"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
ALL-UNNAMED:
22
- manage_threads
33
- outbound_network
4+
- files:
5+
- relative_path: "repository-s3/aws-web-identity-token-file"
6+
relative_to: "config"
7+
mode: "read"
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
org.elasticsearch.blobcache:
2+
- files:
3+
- relative_path: "shared_snapshot_cache"
4+
relative_to: "data"
5+
mode: "read_write"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,10 @@
11
ALL-UNNAMED:
22
- manage_threads
3+
- files:
4+
- relative_path: ".mime.types"
5+
relative_to: "home"
6+
mode: "read"
7+
- relative_path: ".mailcap"
8+
relative_to: "home"
9+
mode: "read"
10+

0 commit comments

Comments
 (0)