Skip to content

Commit 2cf8e6a

Browse files
authored
Miscellaneous java.base file entitlements (elastic#122906) (elastic#122957)
* java.base entitlements * SuppressForbidden, and add a missing test * Revert logging back to commented-out printlns * Merge FileCheckActions and rename for overloads * Remove stray logger * Remove more traces of logging change * Remove more traces of logging
1 parent d337e29 commit 2cf8e6a

File tree

4 files changed

+293
-16
lines changed

4 files changed

+293
-16
lines changed

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
import java.nio.file.attribute.FileAttribute;
6060
import java.nio.file.attribute.UserPrincipal;
6161
import java.nio.file.spi.FileSystemProvider;
62+
import java.security.KeyStore;
63+
import java.security.Provider;
6264
import java.security.cert.CertStoreParameters;
6365
import java.util.List;
6466
import java.util.Locale;
@@ -559,12 +561,50 @@ public interface EntitlementChecker {
559561

560562
void check$java_io_RandomAccessFile$(Class<?> callerClass, File file, String mode);
561563

564+
void check$java_security_KeyStore$$getInstance(Class<?> callerClass, File file, char[] password);
565+
566+
void check$java_security_KeyStore$$getInstance(Class<?> callerClass, File file, KeyStore.LoadStoreParameter param);
567+
568+
void check$java_security_KeyStore$Builder$$newInstance(Class<?> callerClass, File file, KeyStore.ProtectionParameter protection);
569+
570+
void check$java_security_KeyStore$Builder$$newInstance(
571+
Class<?> callerClass,
572+
String type,
573+
Provider provider,
574+
File file,
575+
KeyStore.ProtectionParameter protection
576+
);
577+
562578
void check$java_util_Scanner$(Class<?> callerClass, File source);
563579

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

566582
void check$java_util_Scanner$(Class<?> callerClass, File source, Charset charset);
567583

584+
void check$java_util_jar_JarFile$(Class<?> callerClass, String name);
585+
586+
void check$java_util_jar_JarFile$(Class<?> callerClass, String name, boolean verify);
587+
588+
void check$java_util_jar_JarFile$(Class<?> callerClass, File file);
589+
590+
void check$java_util_jar_JarFile$(Class<?> callerClass, File file, boolean verify);
591+
592+
void check$java_util_jar_JarFile$(Class<?> callerClass, File file, boolean verify, int mode);
593+
594+
void check$java_util_jar_JarFile$(Class<?> callerClass, File file, boolean verify, int mode, Runtime.Version version);
595+
596+
void check$java_util_zip_ZipFile$(Class<?> callerClass, String name);
597+
598+
void check$java_util_zip_ZipFile$(Class<?> callerClass, String name, Charset charset);
599+
600+
void check$java_util_zip_ZipFile$(Class<?> callerClass, File file);
601+
602+
void check$java_util_zip_ZipFile$(Class<?> callerClass, File file, int mode);
603+
604+
void check$java_util_zip_ZipFile$(Class<?> callerClass, File file, Charset charset);
605+
606+
void check$java_util_zip_ZipFile$(Class<?> callerClass, File file, int mode, Charset charset);
607+
568608
// nio
569609
void check$java_nio_file_Files$$getOwner(Class<?> callerClass, Path path, LinkOption... options);
570610

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

Lines changed: 147 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
package org.elasticsearch.entitlement.qa.test;
1111

12+
import org.elasticsearch.core.CheckedRunnable;
1213
import org.elasticsearch.core.SuppressForbidden;
1314
import org.elasticsearch.entitlement.qa.entitled.EntitledActions;
1415

@@ -26,12 +27,22 @@
2627
import java.nio.file.Path;
2728
import java.nio.file.Paths;
2829
import java.nio.file.attribute.UserPrincipal;
30+
import java.security.GeneralSecurityException;
31+
import java.security.KeyStore;
2932
import java.util.Scanner;
30-
33+
import java.util.jar.JarFile;
34+
import java.util.zip.ZipException;
35+
import java.util.zip.ZipFile;
36+
37+
import static java.nio.charset.Charset.defaultCharset;
38+
import static java.util.zip.ZipFile.OPEN_DELETE;
39+
import static java.util.zip.ZipFile.OPEN_READ;
40+
import static org.elasticsearch.entitlement.qa.entitled.EntitledActions.createTempFileForWrite;
3141
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.ALWAYS_DENIED;
3242
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.PLUGINS;
3343

3444
@SuppressForbidden(reason = "Explicitly checking APIs that are forbidden")
45+
@SuppressWarnings("unused") // Called via reflection
3546
class FileCheckActions {
3647

3748
static Path testRootDir = Paths.get(System.getProperty("es.entitlements.testdir"));
@@ -207,21 +218,6 @@ static void fileSetWritableOwner() throws IOException {
207218
readWriteFile().toFile().setWritable(true, false);
208219
}
209220

210-
@EntitlementTest(expectedAccess = PLUGINS)
211-
static void createScannerFile() throws FileNotFoundException {
212-
new Scanner(readFile().toFile());
213-
}
214-
215-
@EntitlementTest(expectedAccess = PLUGINS)
216-
static void createScannerFileWithCharset() throws IOException {
217-
new Scanner(readFile().toFile(), StandardCharsets.UTF_8);
218-
}
219-
220-
@EntitlementTest(expectedAccess = PLUGINS)
221-
static void createScannerFileWithCharsetName() throws FileNotFoundException {
222-
new Scanner(readFile().toFile(), "UTF-8");
223-
}
224-
225221
@EntitlementTest(expectedAccess = PLUGINS)
226222
static void createFileInputStreamFile() throws IOException {
227223
new FileInputStream(readFile().toFile()).close();
@@ -363,5 +359,140 @@ static void filesSetOwner() throws IOException {
363359
Files.setOwner(readWriteFile(), owner); // set to existing owner, just trying to execute the method
364360
}
365361

362+
@EntitlementTest(expectedAccess = PLUGINS)
363+
static void keystoreGetInstance_FileCharArray() throws IOException {
364+
try {
365+
KeyStore.getInstance(readFile().toFile(), new char[0]);
366+
} catch (GeneralSecurityException expected) {
367+
return;
368+
}
369+
throw new AssertionError("Expected an exception");
370+
}
371+
372+
@EntitlementTest(expectedAccess = PLUGINS)
373+
static void keystoreGetInstance_FileLoadStoreParameter() throws IOException {
374+
try {
375+
KeyStore.LoadStoreParameter loadStoreParameter = () -> null;
376+
KeyStore.getInstance(readFile().toFile(), loadStoreParameter);
377+
} catch (GeneralSecurityException expected) {
378+
return;
379+
}
380+
throw new AssertionError("Expected an exception");
381+
}
382+
383+
@EntitlementTest(expectedAccess = PLUGINS)
384+
static void keystoreBuilderNewInstance() {
385+
try {
386+
KeyStore.Builder.newInstance("", null, readFile().toFile(), null);
387+
} catch (NullPointerException expected) {
388+
return;
389+
}
390+
throw new AssertionError("Expected an exception");
391+
}
392+
393+
@EntitlementTest(expectedAccess = PLUGINS)
394+
static void zipFile_String() throws IOException {
395+
expectZipException(() -> new ZipFile(readFile().toString()).close());
396+
}
397+
398+
@EntitlementTest(expectedAccess = PLUGINS)
399+
static void zipFile_StringCharset() throws IOException {
400+
expectZipException(() -> new ZipFile(readFile().toString(), defaultCharset()).close());
401+
}
402+
403+
@EntitlementTest(expectedAccess = PLUGINS)
404+
static void zipFile_File() throws IOException {
405+
expectZipException(() -> new ZipFile(readFile().toFile()).close());
406+
}
407+
408+
@EntitlementTest(expectedAccess = PLUGINS)
409+
static void zipFile_FileCharset() throws IOException {
410+
expectZipException(() -> new ZipFile(readFile().toFile(), defaultCharset()).close());
411+
}
412+
413+
@EntitlementTest(expectedAccess = PLUGINS)
414+
static void zipFile_FileReadOnly() throws IOException {
415+
expectZipException(() -> new ZipFile(readFile().toFile(), OPEN_READ).close());
416+
}
417+
418+
@EntitlementTest(expectedAccess = PLUGINS)
419+
static void zipFile_FileReadAndDelete() throws IOException {
420+
expectZipException(() -> new ZipFile(createTempFileForWrite().toFile(), OPEN_READ | OPEN_DELETE).close());
421+
}
422+
423+
@EntitlementTest(expectedAccess = PLUGINS)
424+
static void zipFile_ReadOnlyCharset() throws IOException {
425+
expectZipException(() -> new ZipFile(readFile().toFile(), OPEN_READ, defaultCharset()).close());
426+
}
427+
428+
@EntitlementTest(expectedAccess = PLUGINS)
429+
static void zipFile_ReadAndDeleteCharset() throws IOException {
430+
expectZipException(() -> new ZipFile(createTempFileForWrite().toFile(), OPEN_READ | OPEN_DELETE, defaultCharset()).close());
431+
}
432+
433+
@EntitlementTest(expectedAccess = PLUGINS)
434+
static void jarFile_String() throws IOException {
435+
expectZipException(() -> new JarFile(readFile().toString()).close());
436+
}
437+
438+
@EntitlementTest(expectedAccess = PLUGINS)
439+
static void jarFile_StringBoolean() throws IOException {
440+
expectZipException(() -> new JarFile(readFile().toString(), false).close());
441+
}
442+
443+
@EntitlementTest(expectedAccess = PLUGINS)
444+
static void jarFile_FileReadOnly() throws IOException {
445+
expectZipException(() -> new JarFile(readFile().toFile(), false, OPEN_READ).close());
446+
}
447+
448+
@EntitlementTest(expectedAccess = PLUGINS)
449+
static void jarFile_FileReadAndDelete() throws IOException {
450+
expectZipException(() -> new JarFile(createTempFileForWrite().toFile(), false, OPEN_READ | OPEN_DELETE).close());
451+
}
452+
453+
@EntitlementTest(expectedAccess = PLUGINS)
454+
static void jarFile_FileBooleanReadOnlyVersion() throws IOException {
455+
expectZipException(() -> new JarFile(readFile().toFile(), false, OPEN_READ, Runtime.version()).close());
456+
}
457+
458+
@EntitlementTest(expectedAccess = PLUGINS)
459+
static void jarFile_FileBooleanReadAndDeleteOnlyVersion() throws IOException {
460+
expectZipException(() -> new JarFile(createTempFileForWrite().toFile(), false, OPEN_READ | OPEN_DELETE, Runtime.version()).close());
461+
}
462+
463+
@EntitlementTest(expectedAccess = PLUGINS)
464+
static void jarFile_File() throws IOException {
465+
expectZipException(() -> new JarFile(readFile().toFile()).close());
466+
}
467+
468+
@EntitlementTest(expectedAccess = PLUGINS)
469+
static void jarFileFileBoolean() throws IOException {
470+
expectZipException(() -> new JarFile(readFile().toFile(), false).close());
471+
}
472+
473+
private static void expectZipException(CheckedRunnable<IOException> action) throws IOException {
474+
try {
475+
action.run();
476+
} catch (ZipException expected) {
477+
return;
478+
}
479+
throw new AssertionError("Expected an exception");
480+
}
481+
482+
@EntitlementTest(expectedAccess = PLUGINS)
483+
static void createScannerFile() throws FileNotFoundException {
484+
new Scanner(readFile().toFile());
485+
}
486+
487+
@EntitlementTest(expectedAccess = PLUGINS)
488+
static void createScannerFileWithCharset() throws IOException {
489+
new Scanner(readFile().toFile(), StandardCharsets.UTF_8);
490+
}
491+
492+
@EntitlementTest(expectedAccess = PLUGINS)
493+
static void createScannerFileWithCharsetName() throws FileNotFoundException {
494+
new Scanner(readFile().toFile(), "UTF-8");
495+
}
496+
366497
private FileCheckActions() {}
367498
}

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

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767
import java.nio.file.attribute.FileAttribute;
6868
import java.nio.file.attribute.UserPrincipal;
6969
import java.nio.file.spi.FileSystemProvider;
70+
import java.security.KeyStore;
71+
import java.security.Provider;
7072
import java.security.cert.CertStoreParameters;
7173
import java.util.List;
7274
import java.util.Locale;
@@ -1145,6 +1147,36 @@ public void checkSelectorProviderInheritedChannel(Class<?> callerClass, Selector
11451147
}
11461148
}
11471149

1150+
@Override
1151+
public void check$java_security_KeyStore$$getInstance(Class<?> callerClass, File file, char[] password) {
1152+
policyManager.checkFileRead(callerClass, file);
1153+
}
1154+
1155+
@Override
1156+
public void check$java_security_KeyStore$$getInstance(Class<?> callerClass, File file, KeyStore.LoadStoreParameter param) {
1157+
policyManager.checkFileRead(callerClass, file);
1158+
}
1159+
1160+
@Override
1161+
public void check$java_security_KeyStore$Builder$$newInstance(
1162+
Class<?> callerClass,
1163+
File file,
1164+
KeyStore.ProtectionParameter protection
1165+
) {
1166+
policyManager.checkFileRead(callerClass, file);
1167+
}
1168+
1169+
@Override
1170+
public void check$java_security_KeyStore$Builder$$newInstance(
1171+
Class<?> callerClass,
1172+
String type,
1173+
Provider provider,
1174+
File file,
1175+
KeyStore.ProtectionParameter protection
1176+
) {
1177+
policyManager.checkFileRead(callerClass, file);
1178+
}
1179+
11481180
@Override
11491181
public void check$java_util_Scanner$(Class<?> callerClass, File source) {
11501182
policyManager.checkFileRead(callerClass, source);
@@ -1160,6 +1192,66 @@ public void checkSelectorProviderInheritedChannel(Class<?> callerClass, Selector
11601192
policyManager.checkFileRead(callerClass, source);
11611193
}
11621194

1195+
@Override
1196+
public void check$java_util_jar_JarFile$(Class<?> callerClass, String name) {
1197+
policyManager.checkFileRead(callerClass, new File(name));
1198+
}
1199+
1200+
@Override
1201+
public void check$java_util_jar_JarFile$(Class<?> callerClass, String name, boolean verify) {
1202+
policyManager.checkFileRead(callerClass, new File(name));
1203+
}
1204+
1205+
@Override
1206+
public void check$java_util_jar_JarFile$(Class<?> callerClass, File file) {
1207+
policyManager.checkFileRead(callerClass, file);
1208+
}
1209+
1210+
@Override
1211+
public void check$java_util_jar_JarFile$(Class<?> callerClass, File file, boolean verify) {
1212+
policyManager.checkFileRead(callerClass, file);
1213+
}
1214+
1215+
@Override
1216+
public void check$java_util_jar_JarFile$(Class<?> callerClass, File file, boolean verify, int mode) {
1217+
policyManager.checkFileWithZipMode(callerClass, file, mode);
1218+
}
1219+
1220+
@Override
1221+
public void check$java_util_jar_JarFile$(Class<?> callerClass, File file, boolean verify, int mode, Runtime.Version version) {
1222+
policyManager.checkFileWithZipMode(callerClass, file, mode);
1223+
}
1224+
1225+
@Override
1226+
public void check$java_util_zip_ZipFile$(Class<?> callerClass, String name) {
1227+
policyManager.checkFileRead(callerClass, new File(name));
1228+
}
1229+
1230+
@Override
1231+
public void check$java_util_zip_ZipFile$(Class<?> callerClass, String name, Charset charset) {
1232+
policyManager.checkFileRead(callerClass, new File(name));
1233+
}
1234+
1235+
@Override
1236+
public void check$java_util_zip_ZipFile$(Class<?> callerClass, File file) {
1237+
policyManager.checkFileRead(callerClass, file);
1238+
}
1239+
1240+
@Override
1241+
public void check$java_util_zip_ZipFile$(Class<?> callerClass, File file, int mode) {
1242+
policyManager.checkFileWithZipMode(callerClass, file, mode);
1243+
}
1244+
1245+
@Override
1246+
public void check$java_util_zip_ZipFile$(Class<?> callerClass, File file, Charset charset) {
1247+
policyManager.checkFileRead(callerClass, file);
1248+
}
1249+
1250+
@Override
1251+
public void check$java_util_zip_ZipFile$(Class<?> callerClass, File file, int mode, Charset charset) {
1252+
policyManager.checkFileWithZipMode(callerClass, file, mode);
1253+
}
1254+
11631255
// nio
11641256

11651257
@Override

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
import static java.util.function.Predicate.not;
4949
import static java.util.stream.Collectors.groupingBy;
5050
import static java.util.stream.Collectors.toUnmodifiableMap;
51+
import static java.util.zip.ZipFile.OPEN_DELETE;
52+
import static java.util.zip.ZipFile.OPEN_READ;
5153

5254
public class PolicyManager {
5355
private static final Logger logger = LogManager.getLogger(PolicyManager.class);
@@ -304,6 +306,18 @@ public void checkFileWrite(Class<?> callerClass, Path path) {
304306
}
305307
}
306308

309+
@SuppressForbidden(reason = "Explicitly checking File apis")
310+
public void checkFileWithZipMode(Class<?> callerClass, File file, int zipMode) {
311+
assert zipMode == OPEN_READ || zipMode == (OPEN_READ | OPEN_DELETE);
312+
if ((zipMode & OPEN_DELETE) == OPEN_DELETE) {
313+
// This needs both read and write, but we happen to know that checkFileWrite
314+
// actually checks both.
315+
checkFileWrite(callerClass, file);
316+
} else {
317+
checkFileRead(callerClass, file);
318+
}
319+
}
320+
307321
public void checkFileDescriptorRead(Class<?> callerClass) {
308322
neverEntitled(callerClass, () -> "read file descriptor");
309323
}

0 commit comments

Comments
 (0)