Skip to content

Commit 74e8ae5

Browse files
authored
Add single flag entitlement validation (#121234)
This adds basic flag entitlement validation when creating PolicyManager. If a module has the same flag entitlement as part of it's policy multiple times we will throw an IllegalArgumentException. With this validation we can safely assume FileEntitlement is the only one we currently have that allows multiple entitlements in a policy.
1 parent eb6f95d commit 74e8ae5

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.lang.module.ModuleFinder;
2121
import java.lang.module.ModuleReference;
2222
import java.nio.file.Path;
23+
import java.util.HashSet;
2324
import java.util.List;
2425
import java.util.Map;
2526
import java.util.Optional;
@@ -120,12 +121,43 @@ public PolicyManager(
120121
this.pluginResolver = pluginResolver;
121122
this.agentsPackageName = agentsPackageName;
122123
this.entitlementsModule = entitlementsModule;
124+
125+
for (var e : serverEntitlements.entrySet()) {
126+
validateEntitlementsPerModule("server", e.getKey(), e.getValue());
127+
}
128+
validateEntitlementsPerModule("agent", "unnamed", agentEntitlements);
129+
for (var p : pluginsEntitlements.entrySet()) {
130+
for (var m : p.getValue().entrySet()) {
131+
validateEntitlementsPerModule(p.getKey(), m.getKey(), m.getValue());
132+
}
133+
}
123134
}
124135

125136
private static Map<String, List<Entitlement>> buildScopeEntitlementsMap(Policy policy) {
126137
return policy.scopes().stream().collect(toUnmodifiableMap(Scope::moduleName, Scope::entitlements));
127138
}
128139

140+
private static void validateEntitlementsPerModule(String sourceName, String moduleName, List<Entitlement> entitlements) {
141+
Set<Class<? extends Entitlement>> flagEntitlements = new HashSet<>();
142+
for (var e : entitlements) {
143+
if (e instanceof FileEntitlement) {
144+
continue;
145+
}
146+
if (flagEntitlements.contains(e.getClass())) {
147+
throw new IllegalArgumentException(
148+
"["
149+
+ sourceName
150+
+ "] using module ["
151+
+ moduleName
152+
+ "] found duplicate flag entitlements ["
153+
+ e.getClass().getName()
154+
+ "]"
155+
);
156+
}
157+
flagEntitlements.add(e.getClass());
158+
}
159+
}
160+
129161
public void checkStartProcess(Class<?> callerClass) {
130162
neverEntitled(callerClass, "start process");
131163
}

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

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,78 @@ public void testAgentsEntitlements() throws IOException, ClassNotFoundException
286286
}
287287
}
288288

289+
public void testDuplicateFlagEntitlements() {
290+
IllegalArgumentException iae = expectThrows(
291+
IllegalArgumentException.class,
292+
() -> new PolicyManager(
293+
new Policy(
294+
"server",
295+
List.of(new Scope("test", List.of(new CreateClassLoaderEntitlement(), new CreateClassLoaderEntitlement())))
296+
),
297+
List.of(),
298+
Map.of(),
299+
c -> "test",
300+
TEST_AGENTS_PACKAGE_NAME,
301+
NO_ENTITLEMENTS_MODULE
302+
)
303+
);
304+
assertEquals(
305+
"[server] using module [test] found duplicate flag entitlements "
306+
+ "[org.elasticsearch.entitlement.runtime.policy.CreateClassLoaderEntitlement]",
307+
iae.getMessage()
308+
);
309+
310+
iae = expectThrows(
311+
IllegalArgumentException.class,
312+
() -> new PolicyManager(
313+
createEmptyTestServerPolicy(),
314+
List.of(new CreateClassLoaderEntitlement(), new CreateClassLoaderEntitlement()),
315+
Map.of(),
316+
c -> "test",
317+
TEST_AGENTS_PACKAGE_NAME,
318+
NO_ENTITLEMENTS_MODULE
319+
)
320+
);
321+
assertEquals(
322+
"[agent] using module [unnamed] found duplicate flag entitlements "
323+
+ "[org.elasticsearch.entitlement.runtime.policy.CreateClassLoaderEntitlement]",
324+
iae.getMessage()
325+
);
326+
327+
iae = expectThrows(
328+
IllegalArgumentException.class,
329+
() -> new PolicyManager(
330+
createEmptyTestServerPolicy(),
331+
List.of(),
332+
Map.of(
333+
"plugin1",
334+
new Policy(
335+
"test",
336+
List.of(
337+
new Scope(
338+
"test",
339+
List.of(
340+
new FileEntitlement("/test/path", FileEntitlement.Mode.READ),
341+
new CreateClassLoaderEntitlement(),
342+
new FileEntitlement("/test/test", FileEntitlement.Mode.READ),
343+
new CreateClassLoaderEntitlement()
344+
)
345+
)
346+
)
347+
)
348+
),
349+
c -> "plugin1",
350+
TEST_AGENTS_PACKAGE_NAME,
351+
NO_ENTITLEMENTS_MODULE
352+
)
353+
);
354+
assertEquals(
355+
"[plugin1] using module [test] found duplicate flag entitlements "
356+
+ "[org.elasticsearch.entitlement.runtime.policy.CreateClassLoaderEntitlement]",
357+
iae.getMessage()
358+
);
359+
}
360+
289361
private static Class<?> makeClassInItsOwnModule() throws IOException, ClassNotFoundException {
290362
final Path home = createTempDir();
291363
Path jar = createMockPluginJar(home);

0 commit comments

Comments
 (0)