13
13
import org .elasticsearch .core .SuppressForbidden ;
14
14
import org .elasticsearch .entitlement .instrumentation .InstrumentationService ;
15
15
import org .elasticsearch .entitlement .runtime .api .NotEntitledException ;
16
+ import org .elasticsearch .entitlement .runtime .policy .FileAccessTree .ExclusiveFileEntitlement ;
17
+ import org .elasticsearch .entitlement .runtime .policy .FileAccessTree .ExclusivePath ;
16
18
import org .elasticsearch .entitlement .runtime .policy .entitlements .CreateClassLoaderEntitlement ;
17
19
import org .elasticsearch .entitlement .runtime .policy .entitlements .Entitlement ;
18
20
import org .elasticsearch .entitlement .runtime .policy .entitlements .ExitVMEntitlement ;
32
34
import java .lang .module .ModuleFinder ;
33
35
import java .lang .module .ModuleReference ;
34
36
import java .nio .file .Path ;
37
+ import java .util .ArrayList ;
35
38
import java .util .HashSet ;
36
39
import java .util .List ;
37
40
import java .util .Map ;
@@ -91,7 +94,7 @@ ModuleEntitlements defaultEntitlements(String componentName) {
91
94
}
92
95
93
96
// pkg private for testing
94
- ModuleEntitlements policyEntitlements (String componentName , List <Entitlement > entitlements ) {
97
+ ModuleEntitlements policyEntitlements (String componentName , String moduleName , List <Entitlement > entitlements ) {
95
98
FilesEntitlement filesEntitlement = FilesEntitlement .EMPTY ;
96
99
for (Entitlement entitlement : entitlements ) {
97
100
if (entitlement instanceof FilesEntitlement ) {
@@ -101,7 +104,7 @@ ModuleEntitlements policyEntitlements(String componentName, List<Entitlement> en
101
104
return new ModuleEntitlements (
102
105
componentName ,
103
106
entitlements .stream ().collect (groupingBy (Entitlement ::getClass )),
104
- FileAccessTree .of (filesEntitlement , pathLookup )
107
+ FileAccessTree .of (componentName , moduleName , filesEntitlement , pathLookup , exclusivePaths )
105
108
);
106
109
}
107
110
@@ -143,6 +146,13 @@ private static Set<Module> findSystemModules() {
143
146
*/
144
147
private final Module entitlementsModule ;
145
148
149
+ /**
150
+ * Paths that are only allowed for a single module. Used to generate
151
+ * structures to indicate other modules aren't allowed to use these
152
+ * files in {@link FileAccessTree}s.
153
+ */
154
+ private final List <ExclusivePath > exclusivePaths ;
155
+
146
156
public PolicyManager (
147
157
Policy serverPolicy ,
148
158
List <Entitlement > apmAgentEntitlements ,
@@ -162,25 +172,40 @@ public PolicyManager(
162
172
this .apmAgentPackageName = apmAgentPackageName ;
163
173
this .entitlementsModule = entitlementsModule ;
164
174
this .pathLookup = requireNonNull (pathLookup );
165
- this .defaultFileAccess = FileAccessTree .of (FilesEntitlement .EMPTY , pathLookup );
175
+ this .defaultFileAccess = FileAccessTree .of (
176
+ UNKNOWN_COMPONENT_NAME ,
177
+ UNKNOWN_COMPONENT_NAME ,
178
+ FilesEntitlement .EMPTY ,
179
+ pathLookup ,
180
+ List .of ()
181
+ );
166
182
this .mutedClasses = suppressFailureLogClasses ;
167
183
184
+ List <ExclusiveFileEntitlement > exclusiveFileEntitlements = new ArrayList <>();
168
185
for (var e : serverEntitlements .entrySet ()) {
169
- validateEntitlementsPerModule (SERVER_COMPONENT_NAME , e .getKey (), e .getValue ());
186
+ validateEntitlementsPerModule (SERVER_COMPONENT_NAME , e .getKey (), e .getValue (), exclusiveFileEntitlements );
170
187
}
171
- validateEntitlementsPerModule (APM_AGENT_COMPONENT_NAME , "unnamed" , apmAgentEntitlements );
188
+ validateEntitlementsPerModule (APM_AGENT_COMPONENT_NAME , ALL_UNNAMED , apmAgentEntitlements , exclusiveFileEntitlements );
172
189
for (var p : pluginsEntitlements .entrySet ()) {
173
190
for (var m : p .getValue ().entrySet ()) {
174
- validateEntitlementsPerModule (p .getKey (), m .getKey (), m .getValue ());
191
+ validateEntitlementsPerModule (p .getKey (), m .getKey (), m .getValue (), exclusiveFileEntitlements );
175
192
}
176
193
}
194
+ List <ExclusivePath > exclusivePaths = FileAccessTree .buildExclusivePathList (exclusiveFileEntitlements , pathLookup );
195
+ FileAccessTree .validateExclusivePaths (exclusivePaths );
196
+ this .exclusivePaths = exclusivePaths ;
177
197
}
178
198
179
199
private static Map <String , List <Entitlement >> buildScopeEntitlementsMap (Policy policy ) {
180
200
return policy .scopes ().stream ().collect (toUnmodifiableMap (Scope ::moduleName , Scope ::entitlements ));
181
201
}
182
202
183
- private static void validateEntitlementsPerModule (String componentName , String moduleName , List <Entitlement > entitlements ) {
203
+ private static void validateEntitlementsPerModule (
204
+ String componentName ,
205
+ String moduleName ,
206
+ List <Entitlement > entitlements ,
207
+ List <ExclusiveFileEntitlement > exclusiveFileEntitlements
208
+ ) {
184
209
Set <Class <? extends Entitlement >> found = new HashSet <>();
185
210
for (var e : entitlements ) {
186
211
if (found .contains (e .getClass ())) {
@@ -189,6 +214,9 @@ private static void validateEntitlementsPerModule(String componentName, String m
189
214
);
190
215
}
191
216
found .add (e .getClass ());
217
+ if (e instanceof FilesEntitlement fe ) {
218
+ exclusiveFileEntitlements .add (new ExclusiveFileEntitlement (componentName , moduleName , fe ));
219
+ }
192
220
}
193
221
}
194
222
@@ -498,7 +526,7 @@ private ModuleEntitlements computeEntitlements(Class<?> requestingClass) {
498
526
499
527
if (requestingModule .isNamed () == false && requestingClass .getPackageName ().startsWith (apmAgentPackageName )) {
500
528
// The APM agent is the only thing running non-modular in the system classloader
501
- return policyEntitlements (APM_AGENT_COMPONENT_NAME , apmAgentEntitlements );
529
+ return policyEntitlements (APM_AGENT_COMPONENT_NAME , ALL_UNNAMED , apmAgentEntitlements );
502
530
}
503
531
504
532
return defaultEntitlements (UNKNOWN_COMPONENT_NAME );
@@ -513,7 +541,7 @@ private ModuleEntitlements getModuleScopeEntitlements(
513
541
if (entitlements == null ) {
514
542
return defaultEntitlements (componentName );
515
543
}
516
- return policyEntitlements (componentName , entitlements );
544
+ return policyEntitlements (componentName , moduleName , entitlements );
517
545
}
518
546
519
547
private static boolean isServerModule (Module requestingModule ) {
0 commit comments