Skip to content

Commit 2b9570a

Browse files
committed
updates
1 parent e839df5 commit 2b9570a

File tree

3 files changed

+72
-79
lines changed

3 files changed

+72
-79
lines changed

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

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

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

12-
import org.elasticsearch.entitlement.runtime.policy.PolicyManager.ExclusivePath;
1312
import org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement;
1413

1514
import java.nio.file.Path;
@@ -23,6 +22,39 @@
2322

2423
public final class FileAccessTree {
2524

25+
record ExclusiveFileEntitlement(String componentName, String moduleName, FilesEntitlement filesEntitlement) {}
26+
27+
record ExclusivePath(String componentName, String moduleName, String path) {}
28+
29+
static List<ExclusivePath> buildExclusivePathList(List<ExclusiveFileEntitlement> exclusiveFileEntitlements, PathLookup pathLookup) {
30+
List<ExclusivePath> exclusivePaths = new ArrayList<>();
31+
for (ExclusiveFileEntitlement efe : exclusiveFileEntitlements) {
32+
for (FilesEntitlement.FileData fd : efe.filesEntitlement().filesData()) {
33+
if (fd.exclusive()) {
34+
List<Path> paths = fd.resolvePaths(pathLookup).toList();
35+
for (Path path : paths) {
36+
exclusivePaths.add(new ExclusivePath(efe.componentName(), efe.moduleName(), normalizePath(path)));
37+
}
38+
}
39+
}
40+
}
41+
exclusivePaths.sort((ep1, ep2) -> PATH_ORDER.compare(ep1.path(), ep2.path()));
42+
return exclusivePaths;
43+
}
44+
45+
static void validateExclusivePaths(List<ExclusivePath> exclusivePaths) {
46+
if (exclusivePaths.isEmpty() == false) {
47+
ExclusivePath currentExclusivePath = exclusivePaths.get(0);
48+
for (int i = 1; i < exclusivePaths.size(); ++i) {
49+
ExclusivePath nextPath = exclusivePaths.get(i);
50+
if (isParent(currentExclusivePath.path(), nextPath.path())) {
51+
52+
}
53+
currentExclusivePath = nextPath;
54+
}
55+
}
56+
}
57+
2658
private static final String FILE_SEPARATOR = getDefaultFileSystem().getSeparator();
2759

2860
private final String[] exclusivePaths;
@@ -38,7 +70,9 @@ private FileAccessTree(
3870
) {
3971
List<String> updatedExclusivePaths = new ArrayList<>();
4072
for (ExclusivePath exclusivePath : exclusivePaths) {
41-
updatedExclusivePaths.add(normalizePath(exclusivePath.path()));
73+
if (exclusivePath.componentName().equals(componentName) == false || exclusivePath.moduleName().equals(moduleName) == false) {
74+
updatedExclusivePaths.add(exclusivePath.path());
75+
}
4276
}
4377

4478
List<String> readPaths = new ArrayList<>();
@@ -48,30 +82,11 @@ private FileAccessTree(
4882
var paths = fileData.resolvePaths(pathLookup);
4983
paths.forEach(path -> {
5084
var normalized = normalizePath(path);
51-
for (ExclusivePath exclusivePath : exclusivePaths) {
52-
if (exclusivePath.componentName().equals(componentName) == false
53-
|| exclusivePath.moduleName().equals(moduleName) == false) {
54-
if (true) throw new IllegalArgumentException(
55-
path.getFileSystem() + " " + exclusivePath.path().getFileSystem() + " " + path.startsWith(exclusivePath.path())
85+
for (String exclusivePath : updatedExclusivePaths) {
86+
if (isParent(exclusivePath, normalized)) {
87+
throw new IllegalArgumentException(
88+
"[" + componentName + "] [" + moduleName + "] cannot use exclusive path [" + exclusivePath + "]"
5689
);
57-
if (path.startsWith(exclusivePath.path())) {
58-
throw new IllegalArgumentException(
59-
"["
60-
+ componentName
61-
+ "] ["
62-
+ moduleName
63-
+ "] cannot use"
64-
+ "exclusive path ["
65-
+ exclusivePath.path()
66-
+ "] from ["
67-
+ exclusivePath.componentName()
68-
+ "] "
69-
+ "["
70-
+ exclusivePath.moduleName()
71-
+ "]"
72-
);
73-
}
74-
updatedExclusivePaths.add(normalizePath(exclusivePath.path()));
7590
}
7691
}
7792
if (mode == FilesEntitlement.Mode.READ_WRITE) {
@@ -86,14 +101,13 @@ private FileAccessTree(
86101
readPaths.add(tempDir);
87102
writePaths.add(tempDir);
88103

104+
updatedExclusivePaths.sort(PATH_ORDER);
89105
readPaths.sort(PATH_ORDER);
90106
writePaths.sort(PATH_ORDER);
91107

92108
this.exclusivePaths = updatedExclusivePaths.toArray(new String[0]);
93109
this.readPaths = pruneSortedPaths(readPaths).toArray(new String[0]);
94110
this.writePaths = pruneSortedPaths(writePaths).toArray(new String[0]);
95-
// if (true) throw new IllegalStateException("EXCLUSIVE: " + Arrays.toString(this.exclusivePaths) +
96-
// "\n READ: " + Arrays.toString(this.readPaths) + "\n WRITE: " + Arrays.toString(this.writePaths));
97111
}
98112

99113
private static List<String> pruneSortedPaths(List<String> paths) {
@@ -110,7 +124,6 @@ private static List<String> pruneSortedPaths(List<String> paths) {
110124
}
111125
}
112126
return prunedReadPaths;
113-
114127
}
115128

116129
public static FileAccessTree of(

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

Lines changed: 15 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import org.elasticsearch.entitlement.bridge.EntitlementChecker;
1616
import org.elasticsearch.entitlement.instrumentation.InstrumentationService;
1717
import org.elasticsearch.entitlement.runtime.api.NotEntitledException;
18+
import org.elasticsearch.entitlement.runtime.policy.FileAccessTree.ExclusiveFileEntitlement;
19+
import org.elasticsearch.entitlement.runtime.policy.FileAccessTree.ExclusivePath;
1820
import org.elasticsearch.entitlement.runtime.policy.entitlements.CreateClassLoaderEntitlement;
1921
import org.elasticsearch.entitlement.runtime.policy.entitlements.Entitlement;
2022
import org.elasticsearch.entitlement.runtime.policy.entitlements.ExitVMEntitlement;
@@ -35,7 +37,6 @@
3537
import java.lang.module.ModuleReference;
3638
import java.nio.file.Path;
3739
import java.util.ArrayList;
38-
import java.util.Comparator;
3940
import java.util.HashSet;
4041
import java.util.List;
4142
import java.util.Map;
@@ -172,29 +173,31 @@ public PolicyManager(
172173
this.pathLookup = requireNonNull(pathLookup);
173174
this.defaultFileAccess = FileAccessTree.of("", "", FilesEntitlement.EMPTY, pathLookup, List.of());
174175

175-
List<ExclusivePath> exclusivePaths = new ArrayList<>();
176+
List<ExclusiveFileEntitlement> exclusiveFileEntitlements = new ArrayList<>();
176177
for (var e : serverEntitlements.entrySet()) {
177-
validateEntitlementsPerModule(SERVER_COMPONENT_NAME, e.getKey(), e.getValue());
178-
buildExclusivePathList(exclusivePaths, pathLookup, SERVER_COMPONENT_NAME, e.getKey(), e.getValue());
178+
validateEntitlementsPerModule(SERVER_COMPONENT_NAME, e.getKey(), e.getValue(), exclusiveFileEntitlements);
179179
}
180-
validateEntitlementsPerModule(APM_AGENT_COMPONENT_NAME, ALL_UNNAMED, apmAgentEntitlements);
181-
buildExclusivePathList(exclusivePaths, pathLookup, APM_AGENT_COMPONENT_NAME, ALL_UNNAMED, apmAgentEntitlements);
180+
validateEntitlementsPerModule(APM_AGENT_COMPONENT_NAME, ALL_UNNAMED, apmAgentEntitlements, exclusiveFileEntitlements);
182181
for (var p : pluginsEntitlements.entrySet()) {
183182
for (var m : p.getValue().entrySet()) {
184-
validateEntitlementsPerModule(p.getKey(), m.getKey(), m.getValue());
185-
buildExclusivePathList(exclusivePaths, pathLookup, p.getKey(), m.getKey(), m.getValue());
183+
validateEntitlementsPerModule(p.getKey(), m.getKey(), m.getValue(), exclusiveFileEntitlements);
186184
}
187185
}
188-
exclusivePaths.sort(Comparator.comparing(ExclusivePath::path));
189-
validateExclusivePaths(exclusivePaths);
186+
List<ExclusivePath> exclusivePaths = FileAccessTree.buildExclusivePathList(exclusiveFileEntitlements, pathLookup);
187+
FileAccessTree.validateExclusivePaths(exclusivePaths);
190188
this.exclusivePaths = exclusivePaths;
191189
}
192190

193191
private static Map<String, List<Entitlement>> buildScopeEntitlementsMap(Policy policy) {
194192
return policy.scopes().stream().collect(toUnmodifiableMap(Scope::moduleName, Scope::entitlements));
195193
}
196194

197-
private static void validateEntitlementsPerModule(String componentName, String moduleName, List<Entitlement> entitlements) {
195+
private static void validateEntitlementsPerModule(
196+
String componentName,
197+
String moduleName,
198+
List<Entitlement> entitlements,
199+
List<ExclusiveFileEntitlement> exclusiveFileEntitlements
200+
) {
198201
Set<Class<? extends Entitlement>> found = new HashSet<>();
199202
for (var e : entitlements) {
200203
if (found.contains(e.getClass())) {
@@ -203,43 +206,8 @@ private static void validateEntitlementsPerModule(String componentName, String m
203206
);
204207
}
205208
found.add(e.getClass());
206-
}
207-
}
208-
209-
record ExclusivePath(String componentName, String moduleName, Path path) {}
210-
211-
private static void buildExclusivePathList(
212-
List<ExclusivePath> exclusivePaths,
213-
PathLookup pathLookup,
214-
String componentName,
215-
String moduleName,
216-
List<Entitlement> entitlements
217-
) {
218-
for (var e : entitlements) {
219209
if (e instanceof FilesEntitlement fe) {
220-
for (FilesEntitlement.FileData fd : fe.filesData()) {
221-
if (fd.exclusive()) {
222-
List<Path> paths = fd.resolvePaths(pathLookup).toList();
223-
for (Path path : paths) {
224-
exclusivePaths.add(new ExclusivePath(componentName, moduleName, path));
225-
}
226-
}
227-
}
228-
}
229-
}
230-
}
231-
232-
private static void validateExclusivePaths(List<ExclusivePath> exclusivePaths) {
233-
if (exclusivePaths.isEmpty() == false) {
234-
ExclusivePath currentExclusivePath = exclusivePaths.get(0);
235-
for (int i = 1; i < exclusivePaths.size(); ++i) {
236-
ExclusivePath nextPath = exclusivePaths.get(i);
237-
if (nextPath.path().equals(currentExclusivePath.path())) {
238-
// TODO: throw
239-
} else if (nextPath.path().startsWith(currentExclusivePath.path())) {
240-
// TODO: throw
241-
}
242-
currentExclusivePath = nextPath;
210+
exclusiveFileEntitlements.add(new ExclusiveFileEntitlement(componentName, moduleName, fe));
243211
}
244212
}
245213
}

libs/entitlement/src/test/java/org/elasticsearch/entitlement/runtime/policy/FileAccessTreeTests.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99

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

12+
import org.apache.lucene.tests.util.LuceneTestCase;
1213
import org.elasticsearch.common.settings.Settings;
13-
import org.elasticsearch.entitlement.runtime.policy.PolicyManager.ExclusivePath;
14+
import org.elasticsearch.entitlement.runtime.policy.FileAccessTree.ExclusivePath;
1415
import org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement;
1516
import org.elasticsearch.test.ESTestCase;
1617
import org.junit.BeforeClass;
@@ -24,6 +25,7 @@
2425
import static org.elasticsearch.core.PathUtils.getDefaultFileSystem;
2526
import static org.hamcrest.Matchers.is;
2627

28+
@LuceneTestCase.SuppressFileSystems("*")
2729
public class FileAccessTreeTests extends ESTestCase {
2830

2931
static Path root;
@@ -237,8 +239,18 @@ public void testBasicExclusiveAccess() {
237239
}
238240

239241
public void testInvalidExclusiveAccess() {
240-
var tree = accessTree(entitlement("foo/bar", "read"), exclusivePaths("test-component", "diff-module", "foo"));
241-
242+
var iae = assertThrows(
243+
IllegalArgumentException.class,
244+
() -> accessTree(entitlement("foo/bar", "read"), exclusivePaths("test-component", "diff-module", "foo"))
245+
);
246+
assertThat(
247+
iae.getMessage(),
248+
is(
249+
"[test-component] [test-module] cannot use exclusive path "
250+
+ "[/home/jdconrad/Code/elastic/elasticsearch/libs/entitlement/build/testrun/test/temp/"
251+
+ "org.elasticsearch.entitlement.runtime.policy.FileAccessTreeTests_F47C6163CA22BE09-001/tempDir-002/foo]"
252+
)
253+
);
242254
}
243255

244256
FileAccessTree accessTree(FilesEntitlement entitlement, List<ExclusivePath> exclusivePaths) {
@@ -263,7 +275,7 @@ static FilesEntitlement entitlement(Map<String, String> value) {
263275
static List<ExclusivePath> exclusivePaths(String componentName, String moduleName, String... paths) {
264276
List<ExclusivePath> exclusivePaths = new ArrayList<>();
265277
for (String path : paths) {
266-
exclusivePaths.add(new ExclusivePath(componentName, moduleName, path(path)));
278+
exclusivePaths.add(new ExclusivePath(componentName, moduleName, path(path).toString()));
267279
}
268280
return exclusivePaths;
269281
}

0 commit comments

Comments
 (0)