Skip to content

Commit 4bfdb42

Browse files
committed
add skeleton for base dir
1 parent 0e9e9f6 commit 4bfdb42

File tree

5 files changed

+95
-32
lines changed

5 files changed

+95
-32
lines changed

libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ private static Class<?>[] findClassesToRetransform(Class<?>[] loadedClasses, Set
108108
}
109109

110110
private static PolicyManager createPolicyManager() {
111-
Map<String, Policy> pluginPolicies = EntitlementBootstrap.bootstrapArgs().pluginPolicies();
111+
EntitlementBootstrap.BootstrapArgs bootstrapArgs = EntitlementBootstrap.bootstrapArgs();
112+
Map<String, Policy> pluginPolicies = bootstrapArgs.pluginPolicies();
113+
Path configDir = bootstrapArgs.configDir();
112114

113115
// TODO(ES-10031): Decide what goes in the elasticsearch default policy and extend it
114116
var serverPolicy = new Policy(
@@ -136,7 +138,15 @@ private static PolicyManager createPolicyManager() {
136138
// this should be removed once https://github.com/elastic/elasticsearch/issues/109335 is completed
137139
List<Entitlement> agentEntitlements = List.of(new CreateClassLoaderEntitlement());
138140
var resolver = EntitlementBootstrap.bootstrapArgs().pluginResolver();
139-
return new PolicyManager(serverPolicy, agentEntitlements, pluginPolicies, resolver, AGENTS_PACKAGE_NAME, ENTITLEMENTS_MODULE);
141+
return new PolicyManager(
142+
serverPolicy,
143+
agentEntitlements,
144+
pluginPolicies,
145+
resolver,
146+
AGENTS_PACKAGE_NAME,
147+
ENTITLEMENTS_MODULE,
148+
configDir
149+
);
140150
}
141151

142152
/**

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,26 @@
2020
import static org.elasticsearch.core.PathUtils.getDefaultFileSystem;
2121

2222
public final class FileAccessTree {
23-
public static final FileAccessTree EMPTY = new FileAccessTree(FilesEntitlement.EMPTY);
23+
public static final FileAccessTree EMPTY = new FileAccessTree(FilesEntitlement.EMPTY, null);
2424
private static final String FILE_SEPARATOR = getDefaultFileSystem().getSeparator();
2525

2626
private final String[] readPaths;
2727
private final String[] writePaths;
2828

29-
private FileAccessTree(FilesEntitlement filesEntitlement) {
29+
private FileAccessTree(FilesEntitlement filesEntitlement, Path configFile) {
3030
List<String> readPaths = new ArrayList<>();
3131
List<String> writePaths = new ArrayList<>();
3232
for (FilesEntitlement.FileData fileData : filesEntitlement.filesData()) {
33-
var path = normalizePath(Path.of(fileData.path()));
33+
Path path = Path.of(fileData.path());
34+
if (fileData.baseDir() == FilesEntitlement.BaseDir.CONFIG) {
35+
path = configFile.resolve(path);
36+
}
37+
String pathStr = normalizePath(path);
3438
var mode = fileData.mode();
3539
if (mode == FilesEntitlement.Mode.READ_WRITE) {
36-
writePaths.add(path);
40+
writePaths.add(pathStr);
3741
}
38-
readPaths.add(path);
42+
readPaths.add(pathStr);
3943
}
4044

4145
readPaths.sort(String::compareTo);
@@ -45,8 +49,8 @@ private FileAccessTree(FilesEntitlement filesEntitlement) {
4549
this.writePaths = writePaths.toArray(new String[0]);
4650
}
4751

48-
public static FileAccessTree of(FilesEntitlement filesEntitlement) {
49-
return new FileAccessTree(filesEntitlement);
52+
public static FileAccessTree of(FilesEntitlement filesEntitlement, Path configFile) {
53+
return new FileAccessTree(filesEntitlement, configFile);
5054
}
5155

5256
boolean canRead(Path path) {

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public static ModuleEntitlements none(String componentName) {
7272
return new ModuleEntitlements(componentName, Map.of(), FileAccessTree.EMPTY);
7373
}
7474

75-
public static ModuleEntitlements from(String componentName, List<Entitlement> entitlements) {
75+
public static ModuleEntitlements from(String componentName, List<Entitlement> entitlements, Path configPath) {
7676
FilesEntitlement filesEntitlement = FilesEntitlement.EMPTY;
7777
for (Entitlement entitlement : entitlements) {
7878
if (entitlement instanceof FilesEntitlement) {
@@ -82,7 +82,7 @@ public static ModuleEntitlements from(String componentName, List<Entitlement> en
8282
return new ModuleEntitlements(
8383
componentName,
8484
entitlements.stream().collect(groupingBy(Entitlement::getClass)),
85-
FileAccessTree.of(filesEntitlement)
85+
FileAccessTree.of(filesEntitlement, configPath)
8686
);
8787
}
8888

@@ -133,13 +133,16 @@ private static Set<Module> findSystemModules() {
133133
*/
134134
private final Module entitlementsModule;
135135

136+
private final Path configDir;
137+
136138
public PolicyManager(
137139
Policy serverPolicy,
138140
List<Entitlement> apmAgentEntitlements,
139141
Map<String, Policy> pluginPolicies,
140142
Function<Class<?>, String> pluginResolver,
141143
String apmAgentPackageName,
142-
Module entitlementsModule
144+
Module entitlementsModule,
145+
Path configDir
143146
) {
144147
this.serverEntitlements = buildScopeEntitlementsMap(requireNonNull(serverPolicy));
145148
this.apmAgentEntitlements = apmAgentEntitlements;
@@ -149,6 +152,7 @@ public PolicyManager(
149152
this.pluginResolver = pluginResolver;
150153
this.apmAgentPackageName = apmAgentPackageName;
151154
this.entitlementsModule = entitlementsModule;
155+
this.configDir = configDir;
152156

153157
for (var e : serverEntitlements.entrySet()) {
154158
validateEntitlementsPerModule(SERVER_COMPONENT_NAME, e.getKey(), e.getValue());
@@ -410,7 +414,7 @@ private ModuleEntitlements computeEntitlements(Class<?> requestingClass) {
410414

411415
if (requestingModule.isNamed() == false && requestingClass.getPackageName().startsWith(apmAgentPackageName)) {
412416
// The APM agent is the only thing running non-modular in the system classloader
413-
return ModuleEntitlements.from(APM_AGENT_COMPONENT_NAME, apmAgentEntitlements);
417+
return ModuleEntitlements.from(APM_AGENT_COMPONENT_NAME, apmAgentEntitlements, configDir);
414418
}
415419

416420
return ModuleEntitlements.none(UNKNOWN_COMPONENT_NAME);
@@ -425,7 +429,7 @@ private ModuleEntitlements getModuleScopeEntitlements(
425429
if (entitlements == null) {
426430
return ModuleEntitlements.none(componentName);
427431
}
428-
return ModuleEntitlements.from(componentName, entitlements);
432+
return ModuleEntitlements.from(componentName, entitlements, configDir);
429433
}
430434

431435
private static boolean isServerModule(Module requestingModule) {

libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/entitlements/FilesEntitlement.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,12 @@ public enum Mode {
2929
READ_WRITE
3030
}
3131

32-
public record FileData(String path, Mode mode) {
32+
public enum BaseDir {
33+
NONE,
34+
CONFIG
35+
}
36+
37+
public record FileData(String path, Mode mode, BaseDir baseDir) {
3338

3439
}
3540

@@ -60,10 +65,21 @@ public static FilesEntitlement build(List<Object> paths) {
6065
if (mode == null) {
6166
throw new PolicyValidationException("files entitlement must contain mode for every listed file");
6267
}
68+
String baseDirString = file.remove("base_dir");
69+
BaseDir baseDir = BaseDir.NONE;
70+
if (baseDirString != null) {
71+
if ("config".equals(baseDirString)) {
72+
baseDir = BaseDir.CONFIG;
73+
} else {
74+
throw new PolicyValidationException(
75+
"unexpected basedir [" + baseDirString + "] for in a listed file for files entitlement"
76+
);
77+
}
78+
}
6379
if (file.isEmpty() == false) {
6480
throw new PolicyValidationException("unknown key(s) " + file + " in a listed file for files entitlement");
6581
}
66-
filesData.add(new FileData(path, parseMode(mode)));
82+
filesData.add(new FileData(path, parseMode(mode), baseDir));
6783
}
6884
return new FilesEntitlement(filesData);
6985
}

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

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ public void testGetEntitlementsThrowsOnMissingPluginUnnamedModule() {
7171
Map.of("plugin1", createPluginPolicy("plugin.module")),
7272
c -> "plugin1",
7373
TEST_AGENTS_PACKAGE_NAME,
74-
NO_ENTITLEMENTS_MODULE
74+
NO_ENTITLEMENTS_MODULE,
75+
null
7576
);
7677

7778
// Any class from the current module (unnamed) will do
@@ -90,7 +91,8 @@ public void testGetEntitlementsThrowsOnMissingPolicyForPlugin() {
9091
Map.of(),
9192
c -> "plugin1",
9293
TEST_AGENTS_PACKAGE_NAME,
93-
NO_ENTITLEMENTS_MODULE
94+
NO_ENTITLEMENTS_MODULE,
95+
null
9496
);
9597

9698
// Any class from the current module (unnamed) will do
@@ -109,7 +111,8 @@ public void testGetEntitlementsFailureIsCached() {
109111
Map.of(),
110112
c -> "plugin1",
111113
TEST_AGENTS_PACKAGE_NAME,
112-
NO_ENTITLEMENTS_MODULE
114+
NO_ENTITLEMENTS_MODULE,
115+
null
113116
);
114117

115118
// Any class from the current module (unnamed) will do
@@ -133,7 +136,8 @@ public void testGetEntitlementsReturnsEntitlementsForPluginUnnamedModule() {
133136
Map.ofEntries(entry("plugin2", createPluginPolicy(ALL_UNNAMED))),
134137
c -> "plugin2",
135138
TEST_AGENTS_PACKAGE_NAME,
136-
NO_ENTITLEMENTS_MODULE
139+
NO_ENTITLEMENTS_MODULE,
140+
null
137141
);
138142

139143
// Any class from the current module (unnamed) will do
@@ -150,7 +154,8 @@ public void testGetEntitlementsThrowsOnMissingPolicyForServer() throws ClassNotF
150154
Map.of(),
151155
c -> null,
152156
TEST_AGENTS_PACKAGE_NAME,
153-
NO_ENTITLEMENTS_MODULE
157+
NO_ENTITLEMENTS_MODULE,
158+
null
154159
);
155160

156161
// Tests do not run modular, so we cannot use a server class.
@@ -176,7 +181,8 @@ public void testGetEntitlementsReturnsEntitlementsForServerModule() throws Class
176181
Map.of(),
177182
c -> null,
178183
TEST_AGENTS_PACKAGE_NAME,
179-
NO_ENTITLEMENTS_MODULE
184+
NO_ENTITLEMENTS_MODULE,
185+
null
180186
);
181187

182188
// Tests do not run modular, so we cannot use a server class.
@@ -201,7 +207,8 @@ public void testGetEntitlementsReturnsEntitlementsForPluginModule() throws IOExc
201207
Map.of("mock-plugin", createPluginPolicy("org.example.plugin")),
202208
c -> "mock-plugin",
203209
TEST_AGENTS_PACKAGE_NAME,
204-
NO_ENTITLEMENTS_MODULE
210+
NO_ENTITLEMENTS_MODULE,
211+
null
205212
);
206213

207214
var layer = createLayerForJar(jar, "org.example.plugin");
@@ -220,7 +227,8 @@ public void testGetEntitlementsResultIsCached() {
220227
Map.ofEntries(entry("plugin2", createPluginPolicy(ALL_UNNAMED))),
221228
c -> "plugin2",
222229
TEST_AGENTS_PACKAGE_NAME,
223-
NO_ENTITLEMENTS_MODULE
230+
NO_ENTITLEMENTS_MODULE,
231+
null
224232
);
225233

226234
// Any class from the current module (unnamed) will do
@@ -278,7 +286,8 @@ public void testAgentsEntitlements() throws IOException, ClassNotFoundException
278286
Map.of(),
279287
c -> c.getPackageName().startsWith(TEST_AGENTS_PACKAGE_NAME) ? null : "test",
280288
TEST_AGENTS_PACKAGE_NAME,
281-
NO_ENTITLEMENTS_MODULE
289+
NO_ENTITLEMENTS_MODULE,
290+
null
282291
);
283292
ModuleEntitlements agentsEntitlements = policyManager.getEntitlements(TestAgent.class);
284293
assertThat(agentsEntitlements.hasEntitlement(CreateClassLoaderEntitlement.class), is(true));
@@ -305,7 +314,8 @@ public void testDuplicateEntitlements() {
305314
Map.of(),
306315
c -> "test",
307316
TEST_AGENTS_PACKAGE_NAME,
308-
NO_ENTITLEMENTS_MODULE
317+
NO_ENTITLEMENTS_MODULE,
318+
null
309319
)
310320
);
311321
assertEquals(
@@ -321,7 +331,8 @@ public void testDuplicateEntitlements() {
321331
Map.of(),
322332
c -> "test",
323333
TEST_AGENTS_PACKAGE_NAME,
324-
NO_ENTITLEMENTS_MODULE
334+
NO_ENTITLEMENTS_MODULE,
335+
null
325336
)
326337
);
327338
assertEquals(
@@ -344,15 +355,20 @@ public void testDuplicateEntitlements() {
344355
List.of(
345356
FilesEntitlement.EMPTY,
346357
new CreateClassLoaderEntitlement(),
347-
new FilesEntitlement(List.of(new FilesEntitlement.FileData("test", FilesEntitlement.Mode.READ)))
358+
new FilesEntitlement(
359+
List.of(
360+
new FilesEntitlement.FileData("test", FilesEntitlement.Mode.READ, FilesEntitlement.BaseDir.NONE)
361+
)
362+
)
348363
)
349364
)
350365
)
351366
)
352367
),
353368
c -> "plugin1",
354369
TEST_AGENTS_PACKAGE_NAME,
355-
NO_ENTITLEMENTS_MODULE
370+
NO_ENTITLEMENTS_MODULE,
371+
null
356372
)
357373
);
358374
assertEquals(
@@ -371,7 +387,8 @@ public void testPluginResolverOverridesAgents() {
371387
Map.of(),
372388
c -> "test", // Insist that the class is in a plugin
373389
TEST_AGENTS_PACKAGE_NAME,
374-
NO_ENTITLEMENTS_MODULE
390+
NO_ENTITLEMENTS_MODULE,
391+
null
375392
);
376393
ModuleEntitlements notAgentsEntitlements = policyManager.getEntitlements(TestAgent.class);
377394
assertThat(notAgentsEntitlements.hasEntitlement(CreateClassLoaderEntitlement.class), is(false));
@@ -385,7 +402,15 @@ private static Class<?> makeClassInItsOwnModule() throws IOException, ClassNotFo
385402
}
386403

387404
private static PolicyManager policyManager(String agentsPackageName, Module entitlementsModule) {
388-
return new PolicyManager(createEmptyTestServerPolicy(), List.of(), Map.of(), c -> "test", agentsPackageName, entitlementsModule);
405+
return new PolicyManager(
406+
createEmptyTestServerPolicy(),
407+
List.of(),
408+
Map.of(),
409+
c -> "test",
410+
agentsPackageName,
411+
entitlementsModule,
412+
null
413+
);
389414
}
390415

391416
private static Policy createEmptyTestServerPolicy() {
@@ -404,7 +429,11 @@ private static Policy createPluginPolicy(String... pluginModules) {
404429
name -> new Scope(
405430
name,
406431
List.of(
407-
new FilesEntitlement(List.of(new FilesEntitlement.FileData("/test/path", FilesEntitlement.Mode.READ))),
432+
new FilesEntitlement(
433+
List.of(
434+
new FilesEntitlement.FileData("/test/path", FilesEntitlement.Mode.READ, FilesEntitlement.BaseDir.NONE)
435+
)
436+
),
408437
new CreateClassLoaderEntitlement()
409438
)
410439
)

0 commit comments

Comments
 (0)