[Entitlements] Add check functions for NIO Files (#122591)

This commit is contained in:
Lorenzo Dematté 2025-02-19 21:55:06 +01:00 committed by GitHub
parent bf31ee6f18
commit 20b829fc14
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 1234 additions and 57 deletions

View File

@ -14,6 +14,7 @@ import java.io.FileDescriptor;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.foreign.AddressLayout;
@ -58,12 +59,18 @@ import java.nio.file.AccessMode;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryStream;
import java.nio.file.FileStore;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitor;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.nio.file.WatchService;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.UserPrincipal;
import java.nio.file.spi.FileSystemProvider;
import java.security.KeyStore;
@ -77,6 +84,7 @@ import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ForkJoinPool;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import javax.net.ssl.HostnameVerifier;
@ -674,6 +682,173 @@ public interface EntitlementChecker {
void check$java_nio_file_Files$$setOwner(Class<?> callerClass, Path path, UserPrincipal principal);
void check$java_nio_file_Files$$newInputStream(Class<?> callerClass, Path path, OpenOption... options);
void check$java_nio_file_Files$$newOutputStream(Class<?> callerClass, Path path, OpenOption... options);
void check$java_nio_file_Files$$newByteChannel(
Class<?> callerClass,
Path path,
Set<? extends OpenOption> options,
FileAttribute<?>... attrs
);
void check$java_nio_file_Files$$newByteChannel(Class<?> callerClass, Path path, OpenOption... options);
void check$java_nio_file_Files$$newDirectoryStream(Class<?> callerClass, Path dir);
void check$java_nio_file_Files$$newDirectoryStream(Class<?> callerClass, Path dir, String glob);
void check$java_nio_file_Files$$newDirectoryStream(Class<?> callerClass, Path dir, DirectoryStream.Filter<? super Path> filter);
void check$java_nio_file_Files$$createFile(Class<?> callerClass, Path path, FileAttribute<?>... attrs);
void check$java_nio_file_Files$$createDirectory(Class<?> callerClass, Path dir, FileAttribute<?>... attrs);
void check$java_nio_file_Files$$createDirectories(Class<?> callerClass, Path dir, FileAttribute<?>... attrs);
void check$java_nio_file_Files$$createTempFile(Class<?> callerClass, Path dir, String prefix, String suffix, FileAttribute<?>... attrs);
void check$java_nio_file_Files$$createTempFile(Class<?> callerClass, String prefix, String suffix, FileAttribute<?>... attrs);
void check$java_nio_file_Files$$createTempDirectory(Class<?> callerClass, Path dir, String prefix, FileAttribute<?>... attrs);
void check$java_nio_file_Files$$createTempDirectory(Class<?> callerClass, String prefix, FileAttribute<?>... attrs);
void check$java_nio_file_Files$$createSymbolicLink(Class<?> callerClass, Path link, Path target, FileAttribute<?>... attrs);
void check$java_nio_file_Files$$createLink(Class<?> callerClass, Path link, Path existing);
void check$java_nio_file_Files$$delete(Class<?> callerClass, Path path);
void check$java_nio_file_Files$$deleteIfExists(Class<?> callerClass, Path path);
void check$java_nio_file_Files$$copy(Class<?> callerClass, Path source, Path target, CopyOption... options);
void check$java_nio_file_Files$$move(Class<?> callerClass, Path source, Path target, CopyOption... options);
void check$java_nio_file_Files$$readSymbolicLink(Class<?> callerClass, Path link);
void check$java_nio_file_Files$$getFileStore(Class<?> callerClass, Path path);
void check$java_nio_file_Files$$isSameFile(Class<?> callerClass, Path path, Path path2);
void check$java_nio_file_Files$$mismatch(Class<?> callerClass, Path path, Path path2);
void check$java_nio_file_Files$$isHidden(Class<?> callerClass, Path path);
void check$java_nio_file_Files$$getFileAttributeView(
Class<?> callerClass,
Path path,
Class<? extends FileAttributeView> type,
LinkOption... options
);
void check$java_nio_file_Files$$readAttributes(
Class<?> callerClass,
Path path,
Class<? extends BasicFileAttributes> type,
LinkOption... options
);
void check$java_nio_file_Files$$setAttribute(Class<?> callerClass, Path path, String attribute, Object value, LinkOption... options);
void check$java_nio_file_Files$$getAttribute(Class<?> callerClass, Path path, String attribute, LinkOption... options);
void check$java_nio_file_Files$$readAttributes(Class<?> callerClass, Path path, String attributes, LinkOption... options);
void check$java_nio_file_Files$$getPosixFilePermissions(Class<?> callerClass, Path path, LinkOption... options);
void check$java_nio_file_Files$$setPosixFilePermissions(Class<?> callerClass, Path path, Set<PosixFilePermission> perms);
void check$java_nio_file_Files$$isSymbolicLink(Class<?> callerClass, Path path);
void check$java_nio_file_Files$$isDirectory(Class<?> callerClass, Path path, LinkOption... options);
void check$java_nio_file_Files$$isRegularFile(Class<?> callerClass, Path path, LinkOption... options);
void check$java_nio_file_Files$$getLastModifiedTime(Class<?> callerClass, Path path, LinkOption... options);
void check$java_nio_file_Files$$setLastModifiedTime(Class<?> callerClass, Path path, FileTime time);
void check$java_nio_file_Files$$size(Class<?> callerClass, Path path);
void check$java_nio_file_Files$$exists(Class<?> callerClass, Path path, LinkOption... options);
void check$java_nio_file_Files$$notExists(Class<?> callerClass, Path path, LinkOption... options);
void check$java_nio_file_Files$$isReadable(Class<?> callerClass, Path path);
void check$java_nio_file_Files$$isWritable(Class<?> callerClass, Path path);
void check$java_nio_file_Files$$isExecutable(Class<?> callerClass, Path path);
void check$java_nio_file_Files$$walkFileTree(
Class<?> callerClass,
Path start,
Set<FileVisitOption> options,
int maxDepth,
FileVisitor<? super Path> visitor
);
void check$java_nio_file_Files$$walkFileTree(Class<?> callerClass, Path start, FileVisitor<? super Path> visitor);
void check$java_nio_file_Files$$newBufferedReader(Class<?> callerClass, Path path, Charset cs);
void check$java_nio_file_Files$$newBufferedReader(Class<?> callerClass, Path path);
void check$java_nio_file_Files$$newBufferedWriter(Class<?> callerClass, Path path, Charset cs, OpenOption... options);
void check$java_nio_file_Files$$newBufferedWriter(Class<?> callerClass, Path path, OpenOption... options);
void check$java_nio_file_Files$$copy(Class<?> callerClass, InputStream in, Path target, CopyOption... options);
void check$java_nio_file_Files$$copy(Class<?> callerClass, Path source, OutputStream out);
void check$java_nio_file_Files$$readAllBytes(Class<?> callerClass, Path path);
void check$java_nio_file_Files$$readString(Class<?> callerClass, Path path);
void check$java_nio_file_Files$$readString(Class<?> callerClass, Path path, Charset cs);
void check$java_nio_file_Files$$readAllLines(Class<?> callerClass, Path path, Charset cs);
void check$java_nio_file_Files$$readAllLines(Class<?> callerClass, Path path);
void check$java_nio_file_Files$$write(Class<?> callerClass, Path path, byte[] bytes, OpenOption... options);
void check$java_nio_file_Files$$write(
Class<?> callerClass,
Path path,
Iterable<? extends CharSequence> lines,
Charset cs,
OpenOption... options
);
void check$java_nio_file_Files$$write(Class<?> callerClass, Path path, Iterable<? extends CharSequence> lines, OpenOption... options);
void check$java_nio_file_Files$$writeString(Class<?> callerClass, Path path, CharSequence csq, OpenOption... options);
void check$java_nio_file_Files$$writeString(Class<?> callerClass, Path path, CharSequence csq, Charset cs, OpenOption... options);
void check$java_nio_file_Files$$list(Class<?> callerClass, Path dir);
void check$java_nio_file_Files$$walk(Class<?> callerClass, Path start, int maxDepth, FileVisitOption... options);
void check$java_nio_file_Files$$walk(Class<?> callerClass, Path start, FileVisitOption... options);
void check$java_nio_file_Files$$find(
Class<?> callerClass,
Path start,
int maxDepth,
BiPredicate<Path, BasicFileAttributes> matcher,
FileVisitOption... options
);
void check$java_nio_file_Files$$lines(Class<?> callerClass, Path path, Charset cs);
void check$java_nio_file_Files$$lines(Class<?> callerClass, Path path);
// file system providers
void check$java_nio_file_spi_FileSystemProvider$(Class<?> callerClass);

View File

@ -23,10 +23,8 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.UserPrincipal;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.util.Scanner;
@ -343,22 +341,6 @@ class FileCheckActions {
new RandomAccessFile(readWriteFile().toFile(), "rw").close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void filesGetOwner() throws IOException {
Files.getOwner(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void filesProbeContentType() throws IOException {
Files.probeContentType(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void filesSetOwner() throws IOException {
UserPrincipal owner = EntitledActions.getFileOwner(readWriteFile());
Files.setOwner(readWriteFile(), owner); // set to existing owner, just trying to execute the method
}
@EntitlementTest(expectedAccess = PLUGINS)
static void keystoreGetInstance_FileCharArray() throws IOException {
try {

View File

@ -0,0 +1,475 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/
package org.elasticsearch.entitlement.qa.test;
import org.elasticsearch.core.SuppressForbidden;
import org.elasticsearch.entitlement.qa.entitled.EntitledActions;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystemException;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileOwnerAttributeView;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.UserPrincipal;
import java.time.Instant;
import java.util.List;
import java.util.Set;
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.ALWAYS_DENIED;
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.PLUGINS;
import static org.elasticsearch.entitlement.qa.test.FileCheckActions.readDir;
import static org.elasticsearch.entitlement.qa.test.FileCheckActions.readFile;
import static org.elasticsearch.entitlement.qa.test.FileCheckActions.readWriteDir;
import static org.elasticsearch.entitlement.qa.test.FileCheckActions.readWriteFile;
class NioFilesActions {
@EntitlementTest(expectedAccess = PLUGINS)
static void filesGetOwner() throws IOException {
Files.getOwner(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void filesProbeContentType() throws IOException {
Files.probeContentType(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void filesSetOwner() throws IOException {
UserPrincipal owner = EntitledActions.getFileOwner(readWriteFile());
Files.setOwner(readWriteFile(), owner); // set to existing owner, just trying to execute the method
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesNewInputStream() throws IOException {
Files.newInputStream(readFile()).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesNewOutputStream() throws IOException {
Files.newOutputStream(readWriteFile()).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesNewByteChannelRead() throws IOException {
Files.newByteChannel(readFile(), Set.of(StandardOpenOption.READ)).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesNewByteChannelWrite() throws IOException {
Files.newByteChannel(readWriteFile(), Set.of(StandardOpenOption.WRITE)).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesNewByteChannelReadVarargs() throws IOException {
Files.newByteChannel(readFile(), StandardOpenOption.READ).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesNewByteChannelWriteVarargs() throws IOException {
Files.newByteChannel(readWriteFile(), StandardOpenOption.WRITE).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesNewDirectoryStream() throws IOException {
Files.newDirectoryStream(FileCheckActions.readDir()).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesNewDirectoryStreamGlob() throws IOException {
Files.newDirectoryStream(FileCheckActions.readDir(), "*").close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesNewDirectoryStreamFilter() throws IOException {
Files.newDirectoryStream(FileCheckActions.readDir(), entry -> false).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesCreateFile() throws IOException {
Files.createFile(readWriteDir().resolve("file.txt"));
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesCreateDirectory() throws IOException {
var directory = EntitledActions.createTempDirectoryForWrite();
Files.createDirectory(directory.resolve("subdir"));
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesCreateDirectories() throws IOException {
var directory = EntitledActions.createTempDirectoryForWrite();
Files.createDirectories(directory.resolve("subdir").resolve("subsubdir"));
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesCreateTempFileInDir() throws IOException {
Files.createTempFile(readWriteDir(), "prefix", "suffix");
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesCreateTempDirectoryInDir() throws IOException {
Files.createTempDirectory(readWriteDir(), "prefix");
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesCreateSymbolicLink() throws IOException {
var directory = EntitledActions.createTempDirectoryForWrite();
try {
Files.createSymbolicLink(directory.resolve("link"), readFile());
} catch (UnsupportedOperationException | FileSystemException e) {
// OK not to implement symbolic link in the filesystem
}
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesCreateLink() throws IOException {
var directory = EntitledActions.createTempDirectoryForWrite();
try {
Files.createLink(directory.resolve("link"), readFile());
} catch (UnsupportedOperationException | FileSystemException e) {
// OK not to implement symbolic link in the filesystem
}
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesDelete() throws IOException {
var file = EntitledActions.createTempFileForWrite();
Files.delete(file);
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesDeleteIfExists() throws IOException {
var file = EntitledActions.createTempFileForWrite();
Files.deleteIfExists(file);
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesReadSymbolicLink() throws IOException {
var link = EntitledActions.createTempSymbolicLink();
Files.readSymbolicLink(link);
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesCopy() throws IOException {
var directory = EntitledActions.createTempDirectoryForWrite();
Files.copy(readFile(), directory.resolve("copied"));
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesMove() throws IOException {
var directory = EntitledActions.createTempDirectoryForWrite();
var file = EntitledActions.createTempFileForWrite();
Files.move(file, directory.resolve("moved"));
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesIsSameFile() throws IOException {
Files.isSameFile(readWriteFile(), readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesMismatch() throws IOException {
Files.mismatch(readWriteFile(), readFile());
}
@SuppressForbidden(reason = "testing entitlements on this API specifically")
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesIsHidden() throws IOException {
Files.isHidden(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesGetFileStore() throws IOException {
var file = EntitledActions.createTempFileForRead();
Files.getFileStore(file);
}
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void checkFilesGetFileAttributeView() {
Files.getFileAttributeView(readFile(), FileOwnerAttributeView.class);
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesReadAttributesWithClass() throws IOException {
Files.readAttributes(readFile(), BasicFileAttributes.class);
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesReadAttributesWithString() throws IOException {
Files.readAttributes(readFile(), "*");
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesGetAttribute() throws IOException {
try {
Files.getAttribute(readFile(), "dos:hidden");
} catch (UnsupportedOperationException | IllegalArgumentException | FileSystemException e) {
// OK if the file does not have/does not support the attribute
}
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesSetAttribute() throws IOException {
var file = EntitledActions.createTempFileForWrite();
try {
Files.setAttribute(file, "dos:hidden", true);
} catch (UnsupportedOperationException | IllegalArgumentException | FileSystemException e) {
// OK if the file does not have/does not support the attribute
}
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesGetPosixFilePermissions() throws IOException {
try {
Files.getPosixFilePermissions(readFile());
} catch (UnsupportedOperationException | IllegalArgumentException | FileSystemException e) {
// OK if the file does not have/does not support the attribute
}
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesSetPosixFilePermissions() throws IOException {
var file = EntitledActions.createTempFileForWrite();
try {
Files.setPosixFilePermissions(file, Set.of());
} catch (UnsupportedOperationException | IllegalArgumentException | FileSystemException e) {
// OK if the file does not have/does not support the attribute
}
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesIsSymbolicLink() {
Files.isSymbolicLink(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesIsDirectory() {
Files.isDirectory(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesIsRegularFile() {
Files.isRegularFile(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesGetLastModifiedTime() throws IOException {
Files.getLastModifiedTime(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesSetLastModifiedTime() throws IOException {
var file = EntitledActions.createTempFileForWrite();
Files.setLastModifiedTime(file, FileTime.from(Instant.now()));
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesSize() throws IOException {
Files.size(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesExists() {
Files.exists(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesNotExists() {
Files.notExists(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesIsReadable() {
Files.isReadable(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesIsWriteable() {
Files.isWritable(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesIsExecutable() {
Files.isExecutable(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesWalkFileTree() throws IOException {
Files.walkFileTree(readDir(), new FileVisitor<>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.SKIP_SUBTREE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.SKIP_SUBTREE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return FileVisitResult.SKIP_SUBTREE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
return FileVisitResult.SKIP_SUBTREE;
}
});
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesWalkFileTreeWithOptions() throws IOException {
Files.walkFileTree(readDir(), Set.of(FileVisitOption.FOLLOW_LINKS), 2, new FileVisitor<>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.SKIP_SUBTREE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
return FileVisitResult.SKIP_SUBTREE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return FileVisitResult.SKIP_SUBTREE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
return FileVisitResult.SKIP_SUBTREE;
}
});
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesNewBufferedReader() throws IOException {
Files.newBufferedReader(readFile()).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesNewBufferedReaderWithCharset() throws IOException {
Files.newBufferedReader(readFile(), Charset.defaultCharset()).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesNewBufferedWriter() throws IOException {
Files.newBufferedWriter(readWriteFile(), StandardOpenOption.WRITE).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesNewBufferedWriterWithCharset() throws IOException {
Files.newBufferedWriter(readWriteFile(), Charset.defaultCharset(), StandardOpenOption.WRITE).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesCopyInputStream() throws IOException {
var directory = EntitledActions.createTempDirectoryForWrite();
Files.copy(new ByteArrayInputStream("foo".getBytes(StandardCharsets.UTF_8)), directory.resolve("copied"));
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesCopyOutputStream() throws IOException {
Files.copy(readFile(), new ByteArrayOutputStream());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesReadAllBytes() throws IOException {
Files.readAllBytes(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesReadString() throws IOException {
Files.readString(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesReadStringWithCharset() throws IOException {
Files.readString(readFile(), Charset.defaultCharset());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesReadAllLines() throws IOException {
Files.readAllLines(readFile());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesReadAllLinesWithCharset() throws IOException {
Files.readAllLines(readFile(), Charset.defaultCharset());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesWrite() throws IOException {
var directory = EntitledActions.createTempDirectoryForWrite();
Files.write(directory.resolve("file"), "foo".getBytes(StandardCharsets.UTF_8));
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesWriteLines() throws IOException {
var directory = EntitledActions.createTempDirectoryForWrite();
Files.write(directory.resolve("file"), List.of("foo"));
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesWriteString() throws IOException {
var directory = EntitledActions.createTempDirectoryForWrite();
Files.writeString(directory.resolve("file"), "foo");
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesWriteStringWithCharset() throws IOException {
var directory = EntitledActions.createTempDirectoryForWrite();
Files.writeString(directory.resolve("file"), "foo", Charset.defaultCharset());
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesList() throws IOException {
Files.list(readDir()).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesWalk() throws IOException {
Files.walk(readDir()).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesWalkWithDepth() throws IOException {
Files.walk(readDir(), 2).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesFind() throws IOException {
Files.find(readDir(), 2, (path, basicFileAttributes) -> false).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesLines() throws IOException {
Files.lines(readFile()).close();
}
@EntitlementTest(expectedAccess = PLUGINS)
static void checkFilesLinesWithCharset() throws IOException {
Files.lines(readFile(), Charset.defaultCharset()).close();
}
private NioFilesActions() {}
}

View File

@ -189,6 +189,7 @@ public class RestEntitlementsCheckAction extends BaseRestHandler {
getTestEntries(FileStoreActions.class),
getTestEntries(ManageThreadsActions.class),
getTestEntries(NativeActions.class),
getTestEntries(NioFilesActions.class),
getTestEntries(NioFileSystemActions.class),
getTestEntries(PathActions.class),
getTestEntries(SpiActions.class),

View File

@ -38,7 +38,7 @@ class EntitlementsTestRule implements TestRule {
Map.of(
"files",
List.of(
Map.of("path", tempDir.resolve("read_dir"), "mode", "read"),
Map.of("path", tempDir.resolve("read_dir"), "mode", "read_write"),
Map.of("path", tempDir.resolve("read_write_dir"), "mode", "read_write"),
Map.of("path", tempDir.resolve("read_file"), "mode", "read"),
Map.of("path", tempDir.resolve("read_write_file"), "mode", "read_write")

View File

@ -39,6 +39,7 @@ public class EntitlementBootstrap {
Function<Class<?>, String> pluginResolver,
Function<String, String> settingResolver,
Function<String, Stream<String>> settingGlobResolver,
Function<String, Path> repoDirResolver,
Path[] dataDirs,
Path configDir,
Path logsDir,
@ -49,6 +50,7 @@ public class EntitlementBootstrap {
requireNonNull(pluginResolver);
requireNonNull(settingResolver);
requireNonNull(settingGlobResolver);
requireNonNull(repoDirResolver);
requireNonNull(dataDirs);
if (dataDirs.length == 0) {
throw new IllegalArgumentException("must provide at least one data directory");
@ -71,6 +73,9 @@ public class EntitlementBootstrap {
*
* @param pluginPolicies a map holding policies for plugins (and modules), by plugin (or module) name.
* @param pluginResolver a functor to map a Java Class to the plugin it belongs to (the plugin name).
* @param settingResolver a functor to resolve the value of an Elasticsearch setting.
* @param settingGlobResolver a functor to resolve a glob expression for one or more Elasticsearch settings.
* @param repoDirResolver a functor to map a repository location to its Elasticsearch path.
* @param dataDirs data directories for Elasticsearch
* @param configDir the config directory for Elasticsearch
* @param tempDir the temp directory for Elasticsearch
@ -81,6 +86,7 @@ public class EntitlementBootstrap {
Function<Class<?>, String> pluginResolver,
Function<String, String> settingResolver,
Function<String, Stream<String>> settingGlobResolver,
Function<String, Path> repoDirResolver,
Path[] dataDirs,
Path configDir,
Path logsDir,
@ -95,6 +101,7 @@ public class EntitlementBootstrap {
pluginResolver,
settingResolver,
settingGlobResolver,
repoDirResolver,
dataDirs,
configDir,
logsDir,

View File

@ -52,7 +52,6 @@ import java.nio.file.WatchService;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.spi.FileSystemProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@ -147,7 +146,18 @@ public class EntitlementInitialization {
List<Scope> serverScopes = new ArrayList<>();
Collections.addAll(
serverScopes,
new Scope("org.elasticsearch.base", List.of(new CreateClassLoaderEntitlement())),
new Scope(
"org.elasticsearch.base",
List.of(
new CreateClassLoaderEntitlement(),
new FilesEntitlement(
List.of(
FileData.ofPath(bootstrapArgs.repoDirResolver().apply(""), READ_WRITE),
FileData.ofRelativePath(Path.of(""), FilesEntitlement.BaseDir.DATA, READ_WRITE)
)
)
)
),
new Scope("org.elasticsearch.xcontent", List.of(new CreateClassLoaderEntitlement())),
new Scope(
"org.elasticsearch.server",
@ -160,31 +170,32 @@ public class EntitlementInitialization {
new LoadNativeLibrariesEntitlement(),
new ManageThreadsEntitlement(),
new FilesEntitlement(
Stream.concat(
Stream.of(
FileData.ofPath(bootstrapArgs.tempDir(), READ_WRITE),
FileData.ofPath(bootstrapArgs.configDir(), READ),
FileData.ofPath(bootstrapArgs.logsDir(), READ_WRITE),
// OS release on Linux
FileData.ofPath(Path.of("/etc/os-release"), READ),
FileData.ofPath(Path.of("/etc/system-release"), READ),
FileData.ofPath(Path.of("/usr/lib/os-release"), READ),
// read max virtual memory areas
FileData.ofPath(Path.of("/proc/sys/vm/max_map_count"), READ),
FileData.ofPath(Path.of("/proc/meminfo"), READ),
// load averages on Linux
FileData.ofPath(Path.of("/proc/loadavg"), READ),
// control group stats on Linux. cgroup v2 stats are in an unpredicable
// location under `/sys/fs/cgroup`, so unfortunately we have to allow
// read access to the entire directory hierarchy.
FileData.ofPath(Path.of("/proc/self/cgroup"), READ),
FileData.ofPath(Path.of("/sys/fs/cgroup/"), READ),
// // io stats on Linux
FileData.ofPath(Path.of("/proc/self/mountinfo"), READ),
FileData.ofPath(Path.of("/proc/diskstats"), READ)
),
Arrays.stream(bootstrapArgs.dataDirs()).map(d -> FileData.ofPath(d, READ))
).toList()
List.of(
// Base ES directories
FileData.ofPath(bootstrapArgs.tempDir(), READ_WRITE),
FileData.ofPath(bootstrapArgs.configDir(), READ),
FileData.ofPath(bootstrapArgs.logsDir(), READ_WRITE),
FileData.ofRelativePath(Path.of(""), FilesEntitlement.BaseDir.DATA, READ_WRITE),
FileData.ofPath(bootstrapArgs.repoDirResolver().apply(""), READ_WRITE),
// OS release on Linux
FileData.ofPath(Path.of("/etc/os-release"), READ),
FileData.ofPath(Path.of("/etc/system-release"), READ),
FileData.ofPath(Path.of("/usr/lib/os-release"), READ),
// read max virtual memory areas
FileData.ofPath(Path.of("/proc/sys/vm/max_map_count"), READ),
FileData.ofPath(Path.of("/proc/meminfo"), READ),
// load averages on Linux
FileData.ofPath(Path.of("/proc/loadavg"), READ),
// control group stats on Linux. cgroup v2 stats are in an unpredicable
// location under `/sys/fs/cgroup`, so unfortunately we have to allow
// read access to the entire directory hierarchy.
FileData.ofPath(Path.of("/proc/self/cgroup"), READ),
FileData.ofPath(Path.of("/sys/fs/cgroup/"), READ),
// // io stats on Linux
FileData.ofPath(Path.of("/proc/self/mountinfo"), READ),
FileData.ofPath(Path.of("/proc/diskstats"), READ)
)
)
)
),
@ -196,13 +207,18 @@ public class EntitlementInitialization {
new LoadNativeLibrariesEntitlement(),
new ManageThreadsEntitlement(),
new FilesEntitlement(
Stream.concat(
Stream.of(FileData.ofPath(bootstrapArgs.configDir(), READ)),
Arrays.stream(bootstrapArgs.dataDirs()).map(d -> FileData.ofPath(d, READ_WRITE))
).toList()
List.of(
FileData.ofPath(bootstrapArgs.configDir(), READ),
FileData.ofPath(bootstrapArgs.tempDir(), READ),
FileData.ofRelativePath(Path.of(""), FilesEntitlement.BaseDir.DATA, READ_WRITE)
)
)
)
),
new Scope(
"org.apache.lucene.misc",
List.of(new FilesEntitlement(List.of(FileData.ofRelativePath(Path.of(""), FilesEntitlement.BaseDir.DATA, READ_WRITE))))
),
new Scope("org.apache.logging.log4j.core", List.of(new ManageThreadsEntitlement())),
new Scope(
"org.elasticsearch.nativeaccess",
@ -226,7 +242,16 @@ public class EntitlementInitialization {
var serverPolicy = new Policy("server", serverScopes);
// agents run without a module, so this is a special hack for the apm agent
// this should be removed once https://github.com/elastic/elasticsearch/issues/109335 is completed
List<Entitlement> agentEntitlements = List.of(new CreateClassLoaderEntitlement(), new ManageThreadsEntitlement());
List<Entitlement> agentEntitlements = List.of(
new CreateClassLoaderEntitlement(),
new ManageThreadsEntitlement(),
new FilesEntitlement(
List.of(
FileData.ofPath(Path.of("/co/elastic/apm/agent/"), READ),
FileData.ofPath(Path.of("/agent/co/elastic/apm/agent/"), READ)
)
)
);
var resolver = EntitlementBootstrap.bootstrapArgs().pluginResolver();
return new PolicyManager(
serverPolicy,

View File

@ -19,6 +19,7 @@ import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.foreign.AddressLayout;
@ -64,6 +65,8 @@ import java.nio.file.AccessMode;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryStream;
import java.nio.file.FileStore;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
@ -71,12 +74,17 @@ import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.nio.file.WatchEvent;
import java.nio.file.WatchService;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.UserPrincipal;
import java.nio.file.spi.FileSystemProvider;
import java.security.KeyStore;
import java.security.Provider;
import java.security.cert.CertStoreParameters;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@ -85,6 +93,7 @@ import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ForkJoinPool;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import javax.net.ssl.HostnameVerifier;
@ -1356,6 +1365,411 @@ public class ElasticsearchEntitlementChecker implements EntitlementChecker {
policyManager.checkFileWrite(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$newInputStream(Class<?> callerClass, Path path, OpenOption... options) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$newOutputStream(Class<?> callerClass, Path path, OpenOption... options) {
policyManager.checkFileWrite(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$newByteChannel(
Class<?> callerClass,
Path path,
Set<? extends OpenOption> options,
FileAttribute<?>... attrs
) {
if (isOpenForWrite(options)) {
policyManager.checkFileWrite(callerClass, path);
} else {
policyManager.checkFileRead(callerClass, path);
}
}
@Override
public void check$java_nio_file_Files$$newByteChannel(Class<?> callerClass, Path path, OpenOption... options) {
if (isOpenForWrite(options)) {
policyManager.checkFileWrite(callerClass, path);
} else {
policyManager.checkFileRead(callerClass, path);
}
}
@Override
public void check$java_nio_file_Files$$newDirectoryStream(Class<?> callerClass, Path dir) {
policyManager.checkFileRead(callerClass, dir);
}
@Override
public void check$java_nio_file_Files$$newDirectoryStream(Class<?> callerClass, Path dir, String glob) {
policyManager.checkFileRead(callerClass, dir);
}
@Override
public void check$java_nio_file_Files$$newDirectoryStream(Class<?> callerClass, Path dir, DirectoryStream.Filter<? super Path> filter) {
policyManager.checkFileRead(callerClass, dir);
}
@Override
public void check$java_nio_file_Files$$createFile(Class<?> callerClass, Path path, FileAttribute<?>... attrs) {
policyManager.checkFileWrite(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$createDirectory(Class<?> callerClass, Path dir, FileAttribute<?>... attrs) {
policyManager.checkFileWrite(callerClass, dir);
}
@Override
public void check$java_nio_file_Files$$createDirectories(Class<?> callerClass, Path dir, FileAttribute<?>... attrs) {
policyManager.checkFileWrite(callerClass, dir);
}
@Override
public void check$java_nio_file_Files$$createTempFile(
Class<?> callerClass,
Path dir,
String prefix,
String suffix,
FileAttribute<?>... attrs
) {
policyManager.checkFileWrite(callerClass, dir);
}
@Override
public void check$java_nio_file_Files$$createTempFile(Class<?> callerClass, String prefix, String suffix, FileAttribute<?>... attrs) {
policyManager.checkCreateTempFile(callerClass);
}
@Override
public void check$java_nio_file_Files$$createTempDirectory(Class<?> callerClass, Path dir, String prefix, FileAttribute<?>... attrs) {
policyManager.checkFileWrite(callerClass, dir);
}
@Override
public void check$java_nio_file_Files$$createTempDirectory(Class<?> callerClass, String prefix, FileAttribute<?>... attrs) {
policyManager.checkCreateTempFile(callerClass);
}
@Override
public void check$java_nio_file_Files$$createSymbolicLink(Class<?> callerClass, Path link, Path target, FileAttribute<?>... attrs) {
policyManager.checkFileRead(callerClass, target);
policyManager.checkFileWrite(callerClass, link);
}
@Override
public void check$java_nio_file_Files$$createLink(Class<?> callerClass, Path link, Path existing) {
policyManager.checkFileRead(callerClass, existing);
policyManager.checkFileWrite(callerClass, link);
}
@Override
public void check$java_nio_file_Files$$delete(Class<?> callerClass, Path path) {
policyManager.checkFileWrite(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$deleteIfExists(Class<?> callerClass, Path path) {
policyManager.checkFileWrite(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$copy(Class<?> callerClass, Path source, Path target, CopyOption... options) {
policyManager.checkFileRead(callerClass, source);
policyManager.checkFileWrite(callerClass, target);
}
@Override
public void check$java_nio_file_Files$$move(Class<?> callerClass, Path source, Path target, CopyOption... options) {
policyManager.checkFileWrite(callerClass, source);
policyManager.checkFileWrite(callerClass, target);
}
@Override
public void check$java_nio_file_Files$$readSymbolicLink(Class<?> callerClass, Path link) {
policyManager.checkFileRead(callerClass, link);
}
@Override
public void check$java_nio_file_Files$$getFileStore(Class<?> callerClass, Path path) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$isSameFile(Class<?> callerClass, Path path, Path path2) {
policyManager.checkFileRead(callerClass, path);
policyManager.checkFileRead(callerClass, path2);
}
@Override
public void check$java_nio_file_Files$$mismatch(Class<?> callerClass, Path path, Path path2) {
policyManager.checkFileRead(callerClass, path);
policyManager.checkFileRead(callerClass, path2);
}
@Override
public void check$java_nio_file_Files$$isHidden(Class<?> callerClass, Path path) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$getFileAttributeView(
Class<?> callerClass,
Path path,
Class<? extends FileAttributeView> type,
LinkOption... options
) {
policyManager.checkGetFileAttributeView(callerClass);
}
@Override
public void check$java_nio_file_Files$$readAttributes(
Class<?> callerClass,
Path path,
Class<? extends BasicFileAttributes> type,
LinkOption... options
) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$setAttribute(
Class<?> callerClass,
Path path,
String attribute,
Object value,
LinkOption... options
) {
policyManager.checkFileWrite(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$getAttribute(Class<?> callerClass, Path path, String attribute, LinkOption... options) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$readAttributes(Class<?> callerClass, Path path, String attributes, LinkOption... options) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$getPosixFilePermissions(Class<?> callerClass, Path path, LinkOption... options) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$setPosixFilePermissions(Class<?> callerClass, Path path, Set<PosixFilePermission> perms) {
policyManager.checkFileWrite(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$isSymbolicLink(Class<?> callerClass, Path path) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$isDirectory(Class<?> callerClass, Path path, LinkOption... options) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$isRegularFile(Class<?> callerClass, Path path, LinkOption... options) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$getLastModifiedTime(Class<?> callerClass, Path path, LinkOption... options) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$setLastModifiedTime(Class<?> callerClass, Path path, FileTime time) {
policyManager.checkFileWrite(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$size(Class<?> callerClass, Path path) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$exists(Class<?> callerClass, Path path, LinkOption... options) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$notExists(Class<?> callerClass, Path path, LinkOption... options) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$isReadable(Class<?> callerClass, Path path) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$isWritable(Class<?> callerClass, Path path) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$isExecutable(Class<?> callerClass, Path path) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$walkFileTree(
Class<?> callerClass,
Path start,
Set<FileVisitOption> options,
int maxDepth,
FileVisitor<? super Path> visitor
) {
policyManager.checkFileRead(callerClass, start);
}
@Override
public void check$java_nio_file_Files$$walkFileTree(Class<?> callerClass, Path start, FileVisitor<? super Path> visitor) {
policyManager.checkFileRead(callerClass, start);
}
@Override
public void check$java_nio_file_Files$$newBufferedReader(Class<?> callerClass, Path path, Charset cs) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$newBufferedReader(Class<?> callerClass, Path path) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$newBufferedWriter(Class<?> callerClass, Path path, Charset cs, OpenOption... options) {
policyManager.checkFileWrite(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$newBufferedWriter(Class<?> callerClass, Path path, OpenOption... options) {
policyManager.checkFileWrite(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$copy(Class<?> callerClass, InputStream in, Path target, CopyOption... options) {
policyManager.checkFileWrite(callerClass, target);
}
@Override
public void check$java_nio_file_Files$$copy(Class<?> callerClass, Path source, OutputStream out) {
policyManager.checkFileRead(callerClass, source);
}
@Override
public void check$java_nio_file_Files$$readAllBytes(Class<?> callerClass, Path path) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$readString(Class<?> callerClass, Path path) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$readString(Class<?> callerClass, Path path, Charset cs) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$readAllLines(Class<?> callerClass, Path path, Charset cs) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$readAllLines(Class<?> callerClass, Path path) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$write(Class<?> callerClass, Path path, byte[] bytes, OpenOption... options) {
policyManager.checkFileWrite(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$write(
Class<?> callerClass,
Path path,
Iterable<? extends CharSequence> lines,
Charset cs,
OpenOption... options
) {
policyManager.checkFileWrite(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$write(
Class<?> callerClass,
Path path,
Iterable<? extends CharSequence> lines,
OpenOption... options
) {
policyManager.checkFileWrite(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$writeString(Class<?> callerClass, Path path, CharSequence csq, OpenOption... options) {
policyManager.checkFileWrite(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$writeString(
Class<?> callerClass,
Path path,
CharSequence csq,
Charset cs,
OpenOption... options
) {
policyManager.checkFileWrite(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$list(Class<?> callerClass, Path dir) {
policyManager.checkFileRead(callerClass, dir);
}
@Override
public void check$java_nio_file_Files$$walk(Class<?> callerClass, Path start, int maxDepth, FileVisitOption... options) {
policyManager.checkFileRead(callerClass, start);
}
@Override
public void check$java_nio_file_Files$$walk(Class<?> callerClass, Path start, FileVisitOption... options) {
policyManager.checkFileRead(callerClass, start);
}
@Override
public void check$java_nio_file_Files$$find(
Class<?> callerClass,
Path start,
int maxDepth,
BiPredicate<Path, BasicFileAttributes> matcher,
FileVisitOption... options
) {
policyManager.checkFileRead(callerClass, start);
}
@Override
public void check$java_nio_file_Files$$lines(Class<?> callerClass, Path path, Charset cs) {
policyManager.checkFileRead(callerClass, path);
}
@Override
public void check$java_nio_file_Files$$lines(Class<?> callerClass, Path path) {
policyManager.checkFileRead(callerClass, path);
}
// file system providers
@Override
@ -1391,6 +1805,17 @@ public class ElasticsearchEntitlementChecker implements EntitlementChecker {
|| options.contains(StandardOpenOption.DELETE_ON_CLOSE);
}
private static boolean isOpenForWrite(OpenOption... options) {
return Arrays.stream(options)
.anyMatch(
o -> o.equals(StandardOpenOption.WRITE)
|| o.equals(StandardOpenOption.APPEND)
|| o.equals(StandardOpenOption.CREATE)
|| o.equals(StandardOpenOption.CREATE_NEW)
|| o.equals(StandardOpenOption.DELETE_ON_CLOSE)
);
}
@Override
public void checkNewFileChannel(
Class<?> callerClass,

View File

@ -12,6 +12,7 @@ package org.elasticsearch.entitlement.runtime.policy;
import org.elasticsearch.core.Strings;
import org.elasticsearch.core.SuppressForbidden;
import org.elasticsearch.entitlement.bootstrap.EntitlementBootstrap;
import org.elasticsearch.entitlement.bridge.EntitlementChecker;
import org.elasticsearch.entitlement.instrumentation.InstrumentationService;
import org.elasticsearch.entitlement.runtime.api.NotEntitledException;
import org.elasticsearch.entitlement.runtime.policy.entitlements.CreateClassLoaderEntitlement;
@ -310,6 +311,10 @@ public class PolicyManager {
}
}
public void checkCreateTempFile(Class<?> callerClass) {
checkFileWrite(callerClass, pathLookup.tempDir());
}
@SuppressForbidden(reason = "Explicitly checking File apis")
public void checkFileWithZipMode(Class<?> callerClass, File file, int zipMode) {
assert zipMode == OPEN_READ || zipMode == (OPEN_READ | OPEN_DELETE);
@ -548,6 +553,10 @@ public class PolicyManager {
logger.debug("Entitlement trivially allowed from system module [{}]", requestingClass.getModule().getName());
return true;
}
if (EntitlementChecker.class.isAssignableFrom(requestingClass)) {
logger.debug("Entitlement trivially allowed for EntitlementChecker class");
return true;
}
logger.trace("Entitlement not trivially allowed");
return false;
}

View File

@ -0,0 +1,5 @@
org.elasticsearch.analysis.common:
- files:
- relative_path: analysis
relative_to: config
mode: read

View File

@ -1,5 +1,10 @@
org.elasticsearch.ingest.geoip:
- files:
- relative_path: "ingest-geoip"
relative_to: config
mode: read
com.maxmind.db:
- files:
- relative_path: "ingest-geoip/"
relative_to: "config"
mode: "read_write"
- relative_path: "ingest-geoip/"
relative_to: "config"
mode: "read_write"

View File

@ -0,0 +1,5 @@
org.elasticsearch.ingest.useragent:
- files:
- relative_path: ingest-user-agent
relative_to: config
mode: read

View File

@ -1,3 +1,7 @@
ALL-UNNAMED:
- manage_threads
- outbound_network
- files:
- relative_path: ""
relative_to: config
mode: read

View File

@ -6,3 +6,10 @@ io.netty.common:
mode: "read"
- path: "/usr/lib/os-release"
mode: "read"
- path: "/proc/sys/net/core/somaxconn"
mode: read
com.azure.identity:
- files:
- relative_path: "storage-azure/" #/config/storage-azure/azure-federated-token
relative_to: config
mode: read

View File

@ -11,3 +11,5 @@ io.netty.common:
mode: "read"
- path: "/usr/lib/os-release"
mode: "read"
- path: "/proc/sys/net/core/somaxconn"
mode: read

View File

@ -0,0 +1,5 @@
org.elasticsearch.analysis.icu:
- files:
- relative_path: ""
relative_to: config
mode: read

View File

@ -5,3 +5,7 @@ ALL-UNNAMED:
- write_system_properties:
properties:
- hadoop.home.dir
- files:
- relative_path: "repository-hdfs/"
relative_to: config
mode: read_write

View File

@ -0,0 +1,5 @@
ALL-UNNAMED:
- files:
- relative_path: "indices/"
relative_to: data
mode: read_write

View File

@ -247,6 +247,7 @@ class Elasticsearch {
pluginsResolver::resolveClassToPluginName,
nodeEnv.settings()::get,
nodeEnv.settings()::getGlobValues,
nodeEnv::resolveRepoDir,
nodeEnv.dataDirs(),
nodeEnv.configDir(),
nodeEnv.logsDir(),

View File

@ -1,5 +1,5 @@
org.elasticsearch.blobcache:
- files:
- relative_path: "shared_snapshot_cache"
relative_to: "data"
mode: "read_write"
- relative_path: ""
relative_to: data
mode: read_write

View File

@ -1,3 +1,13 @@
org.elasticsearch.xcore:
- files:
- relative_path: ""
relative_to: config
mode: read
org.elasticsearch.sslconfig:
- files:
- relative_path: ""
relative_to: config
mode: read
org.apache.httpcomponents.httpclient:
- outbound_network # For SamlRealm
- manage_threads

View File

@ -3,3 +3,7 @@ ALL-UNNAMED:
- write_system_properties:
properties:
- org.apache.xml.security.ignoreLineBreaks
- files:
- relative_path: ""
relative_to: config
mode: read

View File

@ -1,2 +1,9 @@
org.elasticsearch.ml:
- manage_threads
- files:
- relative_path: mlmodel.conf
relative_to: config
mode: read
- relative_path: "ml-local-data/"
relative_to: data
mode: read_write

View File

@ -0,0 +1,8 @@
org.elasticsearch.searchablesnapshots:
- files:
- relative_path: snapshot_cache
relative_to: data
mode: read_write
- relative_path: indices
relative_to: data
mode: read_write

View File

@ -1,5 +1,9 @@
org.elasticsearch.security:
- set_https_connection_properties # for CommandLineHttpClient
- files:
- relative_path: ""
relative_to: config
mode: read
io.netty.transport:
- manage_threads
- inbound_network
@ -13,6 +17,8 @@ io.netty.common:
mode: "read"
- path: "/usr/lib/os-release"
mode: "read"
- path: "/proc/sys/net/core/somaxconn"
mode: read
org.opensaml.xmlsec.impl:
- write_system_properties:
properties: