10
10
package org .elasticsearch .entitlement .initialization ;
11
11
12
12
import org .elasticsearch .core .Booleans ;
13
- import org .elasticsearch .core .Strings ;
14
13
import org .elasticsearch .entitlement .bootstrap .EntitlementBootstrap ;
15
14
import org .elasticsearch .entitlement .bridge .EntitlementChecker ;
16
15
import org .elasticsearch .entitlement .runtime .api .ElasticsearchEntitlementChecker ;
17
- import org .elasticsearch .entitlement .runtime .policy .FileAccessTree ;
18
16
import org .elasticsearch .entitlement .runtime .policy .PathLookup ;
19
17
import org .elasticsearch .entitlement .runtime .policy .Policy ;
20
18
import org .elasticsearch .entitlement .runtime .policy .PolicyManager ;
21
- import org .elasticsearch .entitlement .runtime .policy .PolicyUtils ;
22
- import org .elasticsearch .entitlement .runtime .policy .Scope ;
23
- import org .elasticsearch .entitlement .runtime .policy .entitlements .CreateClassLoaderEntitlement ;
24
- import org .elasticsearch .entitlement .runtime .policy .entitlements .Entitlement ;
25
- import org .elasticsearch .entitlement .runtime .policy .entitlements .ExitVMEntitlement ;
26
- import org .elasticsearch .entitlement .runtime .policy .entitlements .FilesEntitlement ;
27
- import org .elasticsearch .entitlement .runtime .policy .entitlements .FilesEntitlement .FileData ;
28
- import org .elasticsearch .entitlement .runtime .policy .entitlements .InboundNetworkEntitlement ;
29
- import org .elasticsearch .entitlement .runtime .policy .entitlements .LoadNativeLibrariesEntitlement ;
30
- import org .elasticsearch .entitlement .runtime .policy .entitlements .ManageThreadsEntitlement ;
31
- import org .elasticsearch .entitlement .runtime .policy .entitlements .OutboundNetworkEntitlement ;
32
- import org .elasticsearch .entitlement .runtime .policy .entitlements .ReadStoreAttributesEntitlement ;
33
- import org .elasticsearch .entitlement .runtime .policy .entitlements .SetHttpsConnectionPropertiesEntitlement ;
34
- import org .elasticsearch .entitlement .runtime .policy .entitlements .WriteSystemPropertiesEntitlement ;
35
19
36
20
import java .lang .instrument .Instrumentation ;
37
21
import java .lang .reflect .Constructor ;
38
22
import java .lang .reflect .InvocationTargetException ;
39
- import java .nio .file .Path ;
40
- import java .util .ArrayList ;
41
- import java .util .Collections ;
42
- import java .util .HashSet ;
43
- import java .util .List ;
44
23
import java .util .Map ;
45
24
import java .util .Set ;
46
25
47
- import static org .elasticsearch .entitlement .runtime .policy .PathLookup .BaseDir .CONFIG ;
48
- import static org .elasticsearch .entitlement .runtime .policy .PathLookup .BaseDir .DATA ;
49
- import static org .elasticsearch .entitlement .runtime .policy .PathLookup .BaseDir .LIB ;
50
- import static org .elasticsearch .entitlement .runtime .policy .PathLookup .BaseDir .LOGS ;
51
- import static org .elasticsearch .entitlement .runtime .policy .PathLookup .BaseDir .MODULES ;
52
- import static org .elasticsearch .entitlement .runtime .policy .PathLookup .BaseDir .PLUGINS ;
53
- import static org .elasticsearch .entitlement .runtime .policy .PathLookup .BaseDir .SHARED_REPO ;
54
- import static org .elasticsearch .entitlement .runtime .policy .Platform .LINUX ;
55
- import static org .elasticsearch .entitlement .runtime .policy .entitlements .FilesEntitlement .Mode .READ ;
56
- import static org .elasticsearch .entitlement .runtime .policy .entitlements .FilesEntitlement .Mode .READ_WRITE ;
57
-
58
26
/**
59
27
* Called by the agent during {@code agentmain} to configure the entitlement system,
60
28
* instantiate and configure an {@link EntitlementChecker},
@@ -108,149 +76,11 @@ private static PolicyManager createPolicyManager() {
108
76
Map <String , Policy > pluginPolicies = bootstrapArgs .pluginPolicies ();
109
77
PathLookup pathLookup = bootstrapArgs .pathLookup ();
110
78
111
- List <Scope > serverScopes = new ArrayList <>();
112
- List <FileData > serverModuleFileDatas = new ArrayList <>();
113
- Collections .addAll (
114
- serverModuleFileDatas ,
115
- // Base ES directories
116
- FileData .ofBaseDirPath (PLUGINS , READ ),
117
- FileData .ofBaseDirPath (MODULES , READ ),
118
- FileData .ofBaseDirPath (CONFIG , READ ),
119
- FileData .ofBaseDirPath (LOGS , READ_WRITE ),
120
- FileData .ofBaseDirPath (LIB , READ ),
121
- FileData .ofBaseDirPath (DATA , READ_WRITE ),
122
- FileData .ofBaseDirPath (SHARED_REPO , READ_WRITE ),
123
- // exclusive settings file
124
- FileData .ofRelativePath (Path .of ("operator/settings.json" ), CONFIG , READ_WRITE ).withExclusive (true ),
125
-
126
- // OS release on Linux
127
- FileData .ofPath (Path .of ("/etc/os-release" ), READ ).withPlatform (LINUX ),
128
- FileData .ofPath (Path .of ("/etc/system-release" ), READ ).withPlatform (LINUX ),
129
- FileData .ofPath (Path .of ("/usr/lib/os-release" ), READ ).withPlatform (LINUX ),
130
- // read max virtual memory areas
131
- FileData .ofPath (Path .of ("/proc/sys/vm/max_map_count" ), READ ).withPlatform (LINUX ),
132
- FileData .ofPath (Path .of ("/proc/meminfo" ), READ ).withPlatform (LINUX ),
133
- // load averages on Linux
134
- FileData .ofPath (Path .of ("/proc/loadavg" ), READ ).withPlatform (LINUX ),
135
- // control group stats on Linux. cgroup v2 stats are in an unpredicable
136
- // location under `/sys/fs/cgroup`, so unfortunately we have to allow
137
- // read access to the entire directory hierarchy.
138
- FileData .ofPath (Path .of ("/proc/self/cgroup" ), READ ).withPlatform (LINUX ),
139
- FileData .ofPath (Path .of ("/sys/fs/cgroup/" ), READ ).withPlatform (LINUX ),
140
- // // io stats on Linux
141
- FileData .ofPath (Path .of ("/proc/self/mountinfo" ), READ ).withPlatform (LINUX ),
142
- FileData .ofPath (Path .of ("/proc/diskstats" ), READ ).withPlatform (LINUX )
143
- );
144
- if (pathLookup .pidFile () != null ) {
145
- serverModuleFileDatas .add (FileData .ofPath (pathLookup .pidFile (), READ_WRITE ));
146
- }
147
-
148
- Collections .addAll (
149
- serverScopes ,
150
- new Scope (
151
- "org.elasticsearch.base" ,
152
- List .of (
153
- new CreateClassLoaderEntitlement (),
154
- new FilesEntitlement (
155
- List .of (
156
- // TODO: what in es.base is accessing shared repo?
157
- FileData .ofBaseDirPath (SHARED_REPO , READ_WRITE ),
158
- FileData .ofBaseDirPath (DATA , READ_WRITE )
159
- )
160
- )
161
- )
162
- ),
163
- new Scope ("org.elasticsearch.xcontent" , List .of (new CreateClassLoaderEntitlement ())),
164
- new Scope (
165
- "org.elasticsearch.server" ,
166
- List .of (
167
- new ExitVMEntitlement (),
168
- new ReadStoreAttributesEntitlement (),
169
- new CreateClassLoaderEntitlement (),
170
- new InboundNetworkEntitlement (),
171
- new LoadNativeLibrariesEntitlement (),
172
- new ManageThreadsEntitlement (),
173
- new FilesEntitlement (serverModuleFileDatas )
174
- )
175
- ),
176
- new Scope ("java.desktop" , List .of (new LoadNativeLibrariesEntitlement ())),
177
- new Scope ("org.apache.httpcomponents.httpclient" , List .of (new OutboundNetworkEntitlement ())),
178
- new Scope (
179
- "org.apache.lucene.core" ,
180
- List .of (
181
- new LoadNativeLibrariesEntitlement (),
182
- new ManageThreadsEntitlement (),
183
- new FilesEntitlement (List .of (FileData .ofBaseDirPath (CONFIG , READ ), FileData .ofBaseDirPath (DATA , READ_WRITE )))
184
- )
185
- ),
186
- new Scope ("org.apache.lucene.misc" , List .of (new FilesEntitlement (List .of (FileData .ofBaseDirPath (DATA , READ_WRITE ))))),
187
- new Scope (
188
- "org.apache.logging.log4j.core" ,
189
- List .of (new ManageThreadsEntitlement (), new FilesEntitlement (List .of (FileData .ofBaseDirPath (LOGS , READ_WRITE ))))
190
- ),
191
- new Scope (
192
- "org.elasticsearch.nativeaccess" ,
193
- List .of (new LoadNativeLibrariesEntitlement (), new FilesEntitlement (List .of (FileData .ofBaseDirPath (DATA , READ_WRITE ))))
194
- )
195
- );
196
-
197
- // conditionally add FIPS entitlements if FIPS only functionality is enforced
198
- if (Booleans .parseBoolean (System .getProperty ("org.bouncycastle.fips.approved_only" ), false )) {
199
- // if custom trust store is set, grant read access to its location, otherwise use the default JDK trust store
200
- String trustStore = System .getProperty ("javax.net.ssl.trustStore" );
201
- Path trustStorePath = trustStore != null
202
- ? Path .of (trustStore )
203
- : Path .of (System .getProperty ("java.home" )).resolve ("lib/security/jssecacerts" );
204
-
205
- Collections .addAll (
206
- serverScopes ,
207
- new Scope (
208
- "org.bouncycastle.fips.tls" ,
209
- List .of (
210
- new FilesEntitlement (List .of (FileData .ofPath (trustStorePath , READ ))),
211
- new ManageThreadsEntitlement (),
212
- new OutboundNetworkEntitlement ()
213
- )
214
- ),
215
- new Scope (
216
- "org.bouncycastle.fips.core" ,
217
- // read to lib dir is required for checksum validation
218
- List .of (new FilesEntitlement (List .of (FileData .ofBaseDirPath (LIB , READ ))), new ManageThreadsEntitlement ())
219
- )
220
- );
221
- }
222
-
223
- var serverPolicy = new Policy (
224
- "server" ,
225
- bootstrapArgs .serverPolicyPatch () == null
226
- ? serverScopes
227
- : PolicyUtils .mergeScopes (serverScopes , bootstrapArgs .serverPolicyPatch ().scopes ())
228
- );
229
-
230
- // agents run without a module, so this is a special hack for the apm agent
231
- // this should be removed once https://github.com/elastic/elasticsearch/issues/109335 is completed
232
- // See also modules/apm/src/main/plugin-metadata/entitlement-policy.yaml
233
- List <Entitlement > agentEntitlements = List .of (
234
- new CreateClassLoaderEntitlement (),
235
- new ManageThreadsEntitlement (),
236
- new SetHttpsConnectionPropertiesEntitlement (),
237
- new OutboundNetworkEntitlement (),
238
- new WriteSystemPropertiesEntitlement (Set .of ("AsyncProfiler.safemode" )),
239
- new LoadNativeLibrariesEntitlement (),
240
- new FilesEntitlement (
241
- List .of (
242
- FileData .ofBaseDirPath (LOGS , READ_WRITE ),
243
- FileData .ofPath (Path .of ("/proc/meminfo" ), READ ),
244
- FileData .ofPath (Path .of ("/sys/fs/cgroup/" ), READ )
245
- )
246
- )
247
- );
248
-
249
- validateFilesEntitlements (pluginPolicies , pathLookup );
79
+ FilesEntitlementsValidation .validate (pluginPolicies , pathLookup );
250
80
251
81
return new PolicyManager (
252
- serverPolicy ,
253
- agentEntitlements ,
82
+ HardcodedEntitlements . serverPolicy ( pathLookup . pidFile (), bootstrapArgs . serverPolicyPatch ()) ,
83
+ HardcodedEntitlements . agentEntitlements () ,
254
84
pluginPolicies ,
255
85
EntitlementBootstrap .bootstrapArgs ().scopeResolver (),
256
86
EntitlementBootstrap .bootstrapArgs ().sourcePaths (),
@@ -260,74 +90,6 @@ private static PolicyManager createPolicyManager() {
260
90
);
261
91
}
262
92
263
- // package visible for tests
264
- static void validateFilesEntitlements (Map <String , Policy > pluginPolicies , PathLookup pathLookup ) {
265
- Set <Path > readAccessForbidden = new HashSet <>();
266
- pathLookup .getBaseDirPaths (PLUGINS ).forEach (p -> readAccessForbidden .add (p .toAbsolutePath ().normalize ()));
267
- pathLookup .getBaseDirPaths (MODULES ).forEach (p -> readAccessForbidden .add (p .toAbsolutePath ().normalize ()));
268
- pathLookup .getBaseDirPaths (LIB ).forEach (p -> readAccessForbidden .add (p .toAbsolutePath ().normalize ()));
269
- Set <Path > writeAccessForbidden = new HashSet <>();
270
- pathLookup .getBaseDirPaths (CONFIG ).forEach (p -> writeAccessForbidden .add (p .toAbsolutePath ().normalize ()));
271
- for (var pluginPolicy : pluginPolicies .entrySet ()) {
272
- for (var scope : pluginPolicy .getValue ().scopes ()) {
273
- var filesEntitlement = scope .entitlements ()
274
- .stream ()
275
- .filter (x -> x instanceof FilesEntitlement )
276
- .map (x -> ((FilesEntitlement ) x ))
277
- .findFirst ();
278
- if (filesEntitlement .isPresent ()) {
279
- var fileAccessTree = FileAccessTree .withoutExclusivePaths (filesEntitlement .get (), pathLookup , null );
280
- validateReadFilesEntitlements (pluginPolicy .getKey (), scope .moduleName (), fileAccessTree , readAccessForbidden );
281
- validateWriteFilesEntitlements (pluginPolicy .getKey (), scope .moduleName (), fileAccessTree , writeAccessForbidden );
282
- }
283
- }
284
- }
285
- }
286
-
287
- private static IllegalArgumentException buildValidationException (
288
- String componentName ,
289
- String moduleName ,
290
- Path forbiddenPath ,
291
- FilesEntitlement .Mode mode
292
- ) {
293
- return new IllegalArgumentException (
294
- Strings .format (
295
- "policy for module [%s] in [%s] has an invalid file entitlement. Any path under [%s] is forbidden for mode [%s]." ,
296
- moduleName ,
297
- componentName ,
298
- forbiddenPath ,
299
- mode
300
- )
301
- );
302
- }
303
-
304
- private static void validateReadFilesEntitlements (
305
- String componentName ,
306
- String moduleName ,
307
- FileAccessTree fileAccessTree ,
308
- Set <Path > readForbiddenPaths
309
- ) {
310
-
311
- for (Path forbiddenPath : readForbiddenPaths ) {
312
- if (fileAccessTree .canRead (forbiddenPath )) {
313
- throw buildValidationException (componentName , moduleName , forbiddenPath , READ );
314
- }
315
- }
316
- }
317
-
318
- private static void validateWriteFilesEntitlements (
319
- String componentName ,
320
- String moduleName ,
321
- FileAccessTree fileAccessTree ,
322
- Set <Path > writeForbiddenPaths
323
- ) {
324
- for (Path forbiddenPath : writeForbiddenPaths ) {
325
- if (fileAccessTree .canWrite (forbiddenPath )) {
326
- throw buildValidationException (componentName , moduleName , forbiddenPath , READ_WRITE );
327
- }
328
- }
329
- }
330
-
331
93
/**
332
94
* If bytecode verification is enabled, ensure these classes get loaded before transforming/retransforming them.
333
95
* For these classes, the order in which we transform and verify them matters. Verification during class transformation is at least an
0 commit comments