1010package  org .elasticsearch .entitlement .initialization ;
1111
1212import  org .elasticsearch .core .Booleans ;
13- import  org .elasticsearch .core .Strings ;
1413import  org .elasticsearch .entitlement .bootstrap .EntitlementBootstrap ;
1514import  org .elasticsearch .entitlement .bridge .EntitlementChecker ;
1615import  org .elasticsearch .entitlement .runtime .api .ElasticsearchEntitlementChecker ;
17- import  org .elasticsearch .entitlement .runtime .policy .FileAccessTree ;
1816import  org .elasticsearch .entitlement .runtime .policy .PathLookup ;
1917import  org .elasticsearch .entitlement .runtime .policy .Policy ;
2018import  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 ;
3519
3620import  java .lang .instrument .Instrumentation ;
3721import  java .lang .reflect .Constructor ;
3822import  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 ;
4423import  java .util .Map ;
4524import  java .util .Set ;
4625
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- 
5826/** 
5927 * Called by the agent during {@code agentmain} to configure the entitlement system, 
6028 * instantiate and configure an {@link EntitlementChecker}, 
@@ -108,149 +76,11 @@ private static PolicyManager createPolicyManager() {
10876        Map <String , Policy > pluginPolicies  = bootstrapArgs .pluginPolicies ();
10977        PathLookup  pathLookup  = bootstrapArgs .pathLookup ();
11078
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 );
25080
25181        return  new  PolicyManager (
252-             serverPolicy ,
253-             agentEntitlements ,
82+             HardcodedEntitlements . serverPolicy ( pathLookup . pidFile (),  bootstrapArgs . serverPolicyPatch ()) ,
83+             HardcodedEntitlements . agentEntitlements () ,
25484            pluginPolicies ,
25585            EntitlementBootstrap .bootstrapArgs ().scopeResolver (),
25686            EntitlementBootstrap .bootstrapArgs ().sourcePaths (),
@@ -260,74 +90,6 @@ private static PolicyManager createPolicyManager() {
26090        );
26191    }
26292
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- 
33193    /** 
33294     * If bytecode verification is enabled, ensure these classes get loaded before transforming/retransforming them. 
33395     * For these classes, the order in which we transform and verify them matters. Verification during class transformation is at least an 
0 commit comments