Skip to content

Commit ebf398f

Browse files
Merge remote-tracking branch 'elastic/main' into bytes-transport-response
2 parents 87438ae + 1ac5178 commit ebf398f

File tree

19 files changed

+522
-492
lines changed

19 files changed

+522
-492
lines changed

libs/entitlement/src/main/java/org/elasticsearch/entitlement/bootstrap/EntitlementBootstrap.java

Lines changed: 32 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,13 @@
1515
import com.sun.tools.attach.VirtualMachine;
1616

1717
import org.elasticsearch.core.Nullable;
18+
import org.elasticsearch.core.PathUtils;
1819
import org.elasticsearch.core.SuppressForbidden;
1920
import org.elasticsearch.entitlement.initialization.EntitlementInitialization;
21+
import org.elasticsearch.entitlement.runtime.policy.PathLookup;
22+
import org.elasticsearch.entitlement.runtime.policy.PathLookupImpl;
2023
import org.elasticsearch.entitlement.runtime.policy.Policy;
24+
import org.elasticsearch.entitlement.runtime.policy.PolicyManager;
2125
import org.elasticsearch.logging.LogManager;
2226
import org.elasticsearch.logging.Logger;
2327

@@ -36,36 +40,16 @@ public class EntitlementBootstrap {
3640
public record BootstrapArgs(
3741
@Nullable Policy serverPolicyPatch,
3842
Map<String, Policy> pluginPolicies,
39-
Function<Class<?>, String> pluginResolver,
40-
Function<String, Stream<String>> settingResolver,
41-
Path[] dataDirs,
42-
Path[] sharedRepoDirs,
43-
Path configDir,
44-
Path libDir,
45-
Path modulesDir,
46-
Path pluginsDir,
43+
Function<Class<?>, PolicyManager.PolicyScope> scopeResolver,
44+
PathLookup pathLookup,
4745
Map<String, Path> sourcePaths,
48-
Path logsDir,
49-
Path tempDir,
50-
Path pidFile,
5146
Set<Class<?>> suppressFailureLogClasses
5247
) {
5348
public BootstrapArgs {
5449
requireNonNull(pluginPolicies);
55-
requireNonNull(pluginResolver);
56-
requireNonNull(settingResolver);
57-
requireNonNull(dataDirs);
58-
if (dataDirs.length == 0) {
59-
throw new IllegalArgumentException("must provide at least one data directory");
60-
}
61-
requireNonNull(sharedRepoDirs);
62-
requireNonNull(configDir);
63-
requireNonNull(libDir);
64-
requireNonNull(modulesDir);
65-
requireNonNull(pluginsDir);
50+
requireNonNull(scopeResolver);
51+
requireNonNull(pathLookup);
6652
requireNonNull(sourcePaths);
67-
requireNonNull(logsDir);
68-
requireNonNull(tempDir);
6953
requireNonNull(suppressFailureLogClasses);
7054
}
7155
}
@@ -82,7 +66,7 @@ public static BootstrapArgs bootstrapArgs() {
8266
*
8367
* @param serverPolicyPatch a policy with additional entitlements to patch the embedded server layer policy
8468
* @param pluginPolicies a map holding policies for plugins (and modules), by plugin (or module) name.
85-
* @param pluginResolver a functor to map a Java Class to the plugin it belongs to (the plugin name).
69+
* @param scopeResolver a functor to map a Java Class to the component and module it belongs to.
8670
* @param settingResolver a functor to resolve a setting name pattern for one or more Elasticsearch settings.
8771
* @param dataDirs data directories for Elasticsearch
8872
* @param sharedRepoDirs shared repository directories for Elasticsearch
@@ -99,7 +83,7 @@ public static BootstrapArgs bootstrapArgs() {
9983
public static void bootstrap(
10084
Policy serverPolicyPatch,
10185
Map<String, Policy> pluginPolicies,
102-
Function<Class<?>, String> pluginResolver,
86+
Function<Class<?>, PolicyManager.PolicyScope> scopeResolver,
10387
Function<String, Stream<String>> settingResolver,
10488
Path[] dataDirs,
10589
Path[] sharedRepoDirs,
@@ -120,24 +104,35 @@ public static void bootstrap(
120104
EntitlementBootstrap.bootstrapArgs = new BootstrapArgs(
121105
serverPolicyPatch,
122106
pluginPolicies,
123-
pluginResolver,
124-
settingResolver,
125-
dataDirs,
126-
sharedRepoDirs,
127-
configDir,
128-
libDir,
129-
modulesDir,
130-
pluginsDir,
107+
scopeResolver,
108+
new PathLookupImpl(
109+
getUserHome(),
110+
configDir,
111+
dataDirs,
112+
sharedRepoDirs,
113+
libDir,
114+
modulesDir,
115+
pluginsDir,
116+
logsDir,
117+
tempDir,
118+
pidFile,
119+
settingResolver
120+
),
131121
sourcePaths,
132-
logsDir,
133-
tempDir,
134-
pidFile,
135122
suppressFailureLogClasses
136123
);
137124
exportInitializationToAgent();
138125
loadAgent(findAgentJar());
139126
}
140127

128+
private static Path getUserHome() {
129+
String userHome = System.getProperty("user.home");
130+
if (userHome == null) {
131+
throw new IllegalStateException("user.home system property is required");
132+
}
133+
return PathUtils.get(userHome);
134+
}
135+
141136
@SuppressForbidden(reason = "The VirtualMachine API is the only way to attach a java agent dynamically")
142137
private static void loadAgent(String agentPath) {
143138
try {

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

Lines changed: 35 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@
5858
import java.nio.file.attribute.FileAttribute;
5959
import java.nio.file.spi.FileSystemProvider;
6060
import java.util.ArrayList;
61-
import java.util.Arrays;
6261
import java.util.Collections;
6362
import java.util.HashMap;
63+
import java.util.HashSet;
6464
import java.util.List;
6565
import java.util.Map;
6666
import java.util.Set;
@@ -70,10 +70,14 @@
7070
import java.util.stream.Stream;
7171
import java.util.stream.StreamSupport;
7272

73+
import static org.elasticsearch.entitlement.runtime.policy.PathLookup.BaseDir.CONFIG;
74+
import static org.elasticsearch.entitlement.runtime.policy.PathLookup.BaseDir.DATA;
75+
import static org.elasticsearch.entitlement.runtime.policy.PathLookup.BaseDir.LIB;
76+
import static org.elasticsearch.entitlement.runtime.policy.PathLookup.BaseDir.LOGS;
77+
import static org.elasticsearch.entitlement.runtime.policy.PathLookup.BaseDir.MODULES;
78+
import static org.elasticsearch.entitlement.runtime.policy.PathLookup.BaseDir.PLUGINS;
79+
import static org.elasticsearch.entitlement.runtime.policy.PathLookup.BaseDir.SHARED_REPO;
7380
import static org.elasticsearch.entitlement.runtime.policy.Platform.LINUX;
74-
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.BaseDir.CONFIG;
75-
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.BaseDir.DATA;
76-
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.BaseDir.SHARED_REPO;
7781
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.Mode.READ;
7882
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.Mode.READ_WRITE;
7983

@@ -86,7 +90,6 @@
8690
*/
8791
public class EntitlementInitialization {
8892

89-
private static final String AGENTS_PACKAGE_NAME = "co.elastic.apm.agent";
9093
private static final Module ENTITLEMENTS_MODULE = PolicyManager.class.getModule();
9194

9295
private static ElasticsearchEntitlementChecker manager;
@@ -165,27 +168,20 @@ private static Class<?>[] findClassesToRetransform(Class<?>[] loadedClasses, Set
165168
private static PolicyManager createPolicyManager() {
166169
EntitlementBootstrap.BootstrapArgs bootstrapArgs = EntitlementBootstrap.bootstrapArgs();
167170
Map<String, Policy> pluginPolicies = bootstrapArgs.pluginPolicies();
168-
var pathLookup = new PathLookup(
169-
getUserHome(),
170-
bootstrapArgs.configDir(),
171-
bootstrapArgs.dataDirs(),
172-
bootstrapArgs.sharedRepoDirs(),
173-
bootstrapArgs.tempDir(),
174-
bootstrapArgs.settingResolver()
175-
);
171+
PathLookup pathLookup = bootstrapArgs.pathLookup();
176172

177173
List<Scope> serverScopes = new ArrayList<>();
178174
List<FileData> serverModuleFileDatas = new ArrayList<>();
179175
Collections.addAll(
180176
serverModuleFileDatas,
181177
// Base ES directories
182-
FileData.ofPath(bootstrapArgs.pluginsDir(), READ),
183-
FileData.ofPath(bootstrapArgs.modulesDir(), READ),
184-
FileData.ofPath(bootstrapArgs.configDir(), READ),
185-
FileData.ofPath(bootstrapArgs.logsDir(), READ_WRITE),
186-
FileData.ofPath(bootstrapArgs.libDir(), READ),
187-
FileData.ofRelativePath(Path.of(""), DATA, READ_WRITE),
188-
FileData.ofRelativePath(Path.of(""), SHARED_REPO, READ_WRITE),
178+
FileData.ofBaseDirPath(PLUGINS, READ),
179+
FileData.ofBaseDirPath(MODULES, READ),
180+
FileData.ofBaseDirPath(CONFIG, READ),
181+
FileData.ofBaseDirPath(LOGS, READ_WRITE),
182+
FileData.ofBaseDirPath(LIB, READ),
183+
FileData.ofBaseDirPath(DATA, READ_WRITE),
184+
FileData.ofBaseDirPath(SHARED_REPO, READ_WRITE),
189185
// exclusive settings file
190186
FileData.ofRelativePath(Path.of("operator/settings.json"), CONFIG, READ_WRITE).withExclusive(true),
191187
// OS release on Linux
@@ -206,8 +202,8 @@ private static PolicyManager createPolicyManager() {
206202
FileData.ofPath(Path.of("/proc/self/mountinfo"), READ).withPlatform(LINUX),
207203
FileData.ofPath(Path.of("/proc/diskstats"), READ).withPlatform(LINUX)
208204
);
209-
if (bootstrapArgs.pidFile() != null) {
210-
serverModuleFileDatas.add(FileData.ofPath(bootstrapArgs.pidFile(), READ_WRITE));
205+
if (pathLookup.pidFile() != null) {
206+
serverModuleFileDatas.add(FileData.ofPath(pathLookup.pidFile(), READ_WRITE));
211207
}
212208

213209
Collections.addAll(
@@ -219,8 +215,8 @@ private static PolicyManager createPolicyManager() {
219215
new FilesEntitlement(
220216
List.of(
221217
// TODO: what in es.base is accessing shared repo?
222-
FileData.ofRelativePath(Path.of(""), SHARED_REPO, READ_WRITE),
223-
FileData.ofRelativePath(Path.of(""), DATA, READ_WRITE)
218+
FileData.ofBaseDirPath(SHARED_REPO, READ_WRITE),
219+
FileData.ofBaseDirPath(DATA, READ_WRITE)
224220
)
225221
)
226222
)
@@ -245,25 +241,17 @@ private static PolicyManager createPolicyManager() {
245241
List.of(
246242
new LoadNativeLibrariesEntitlement(),
247243
new ManageThreadsEntitlement(),
248-
new FilesEntitlement(
249-
List.of(FileData.ofPath(bootstrapArgs.configDir(), READ), FileData.ofRelativePath(Path.of(""), DATA, READ_WRITE))
250-
)
244+
new FilesEntitlement(List.of(FileData.ofBaseDirPath(CONFIG, READ), FileData.ofBaseDirPath(DATA, READ_WRITE)))
251245
)
252246
),
253-
new Scope(
254-
"org.apache.lucene.misc",
255-
List.of(new FilesEntitlement(List.of(FileData.ofRelativePath(Path.of(""), DATA, READ_WRITE))))
256-
),
247+
new Scope("org.apache.lucene.misc", List.of(new FilesEntitlement(List.of(FileData.ofBaseDirPath(DATA, READ_WRITE))))),
257248
new Scope(
258249
"org.apache.logging.log4j.core",
259-
List.of(new ManageThreadsEntitlement(), new FilesEntitlement(List.of(FileData.ofPath(bootstrapArgs.logsDir(), READ_WRITE))))
250+
List.of(new ManageThreadsEntitlement(), new FilesEntitlement(List.of(FileData.ofBaseDirPath(LOGS, READ_WRITE))))
260251
),
261252
new Scope(
262253
"org.elasticsearch.nativeaccess",
263-
List.of(
264-
new LoadNativeLibrariesEntitlement(),
265-
new FilesEntitlement(List.of(FileData.ofRelativePath(Path.of(""), DATA, READ_WRITE)))
266-
)
254+
List.of(new LoadNativeLibrariesEntitlement(), new FilesEntitlement(List.of(FileData.ofBaseDirPath(DATA, READ_WRITE))))
267255
)
268256
);
269257

@@ -288,7 +276,7 @@ private static PolicyManager createPolicyManager() {
288276
new Scope(
289277
"org.bouncycastle.fips.core",
290278
// read to lib dir is required for checksum validation
291-
List.of(new FilesEntitlement(List.of(FileData.ofPath(bootstrapArgs.libDir(), READ))), new ManageThreadsEntitlement())
279+
List.of(new FilesEntitlement(List.of(FileData.ofBaseDirPath(LIB, READ))), new ManageThreadsEntitlement())
292280
)
293281
);
294282
}
@@ -312,50 +300,35 @@ private static PolicyManager createPolicyManager() {
312300
new LoadNativeLibrariesEntitlement(),
313301
new FilesEntitlement(
314302
List.of(
315-
FileData.ofPath(bootstrapArgs.logsDir(), READ_WRITE),
303+
FileData.ofBaseDirPath(LOGS, READ_WRITE),
316304
FileData.ofPath(Path.of("/proc/meminfo"), READ),
317305
FileData.ofPath(Path.of("/sys/fs/cgroup/"), READ)
318306
)
319307
)
320308
);
321309

322-
validateFilesEntitlements(
323-
pluginPolicies,
324-
pathLookup,
325-
bootstrapArgs.configDir(),
326-
bootstrapArgs.pluginsDir(),
327-
bootstrapArgs.modulesDir(),
328-
bootstrapArgs.libDir()
329-
);
310+
validateFilesEntitlements(pluginPolicies, pathLookup);
330311

331312
return new PolicyManager(
332313
serverPolicy,
333314
agentEntitlements,
334315
pluginPolicies,
335-
EntitlementBootstrap.bootstrapArgs().pluginResolver(),
316+
EntitlementBootstrap.bootstrapArgs().scopeResolver(),
336317
EntitlementBootstrap.bootstrapArgs().sourcePaths(),
337-
AGENTS_PACKAGE_NAME,
338318
ENTITLEMENTS_MODULE,
339319
pathLookup,
340320
bootstrapArgs.suppressFailureLogClasses()
341321
);
342322
}
343323

344-
private static Set<Path> pathSet(Path... paths) {
345-
return Arrays.stream(paths).map(x -> x.toAbsolutePath().normalize()).collect(Collectors.toUnmodifiableSet());
346-
}
347-
348324
// package visible for tests
349-
static void validateFilesEntitlements(
350-
Map<String, Policy> pluginPolicies,
351-
PathLookup pathLookup,
352-
Path configDir,
353-
Path pluginsDir,
354-
Path modulesDir,
355-
Path libDir
356-
) {
357-
var readAccessForbidden = pathSet(pluginsDir, modulesDir, libDir);
358-
var writeAccessForbidden = pathSet(configDir);
325+
static void validateFilesEntitlements(Map<String, Policy> pluginPolicies, PathLookup pathLookup) {
326+
Set<Path> readAccessForbidden = new HashSet<>();
327+
pathLookup.getBaseDirPaths(PLUGINS).forEach(p -> readAccessForbidden.add(p.toAbsolutePath().normalize()));
328+
pathLookup.getBaseDirPaths(MODULES).forEach(p -> readAccessForbidden.add(p.toAbsolutePath().normalize()));
329+
pathLookup.getBaseDirPaths(LIB).forEach(p -> readAccessForbidden.add(p.toAbsolutePath().normalize()));
330+
Set<Path> writeAccessForbidden = new HashSet<>();
331+
pathLookup.getBaseDirPaths(CONFIG).forEach(p -> writeAccessForbidden.add(p.toAbsolutePath().normalize()));
359332
for (var pluginPolicy : pluginPolicies.entrySet()) {
360333
for (var scope : pluginPolicy.getValue().scopes()) {
361334
var filesEntitlement = scope.entitlements()

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import static java.util.Comparator.comparing;
3535
import static org.elasticsearch.core.PathUtils.getDefaultFileSystem;
3636
import static org.elasticsearch.entitlement.runtime.policy.FileUtils.PATH_ORDER;
37+
import static org.elasticsearch.entitlement.runtime.policy.PathLookup.BaseDir.CONFIG;
38+
import static org.elasticsearch.entitlement.runtime.policy.PathLookup.BaseDir.TEMP;
3739
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.Mode.READ_WRITE;
3840

3941
public final class FileAccessTree {
@@ -167,9 +169,9 @@ private FileAccessTree(FilesEntitlement filesEntitlement, PathLookup pathLookup,
167169
}
168170

169171
// everything has access to the temp dir, config dir, to their own dir (their own jar files) and the jdk
170-
addPathAndMaybeLink.accept(pathLookup.tempDir(), READ_WRITE);
172+
pathLookup.getBaseDirPaths(TEMP).forEach(tempPath -> addPathAndMaybeLink.accept(tempPath, READ_WRITE));
171173
// TODO: this grants read access to the config dir for all modules until explicit read entitlements can be added
172-
addPathAndMaybeLink.accept(pathLookup.configDir(), Mode.READ);
174+
pathLookup.getBaseDirPaths(CONFIG).forEach(configPath -> addPathAndMaybeLink.accept(configPath, Mode.READ));
173175
if (componentPath != null) {
174176
addPathAndMaybeLink.accept(componentPath, Mode.READ);
175177
}

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

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,29 @@
1010
package org.elasticsearch.entitlement.runtime.policy;
1111

1212
import java.nio.file.Path;
13-
import java.util.function.Function;
1413
import java.util.stream.Stream;
1514

16-
public record PathLookup(
17-
Path homeDir,
18-
Path configDir,
19-
Path[] dataDirs,
20-
Path[] sharedRepoDirs,
21-
Path tempDir,
22-
Function<String, Stream<String>> settingResolver
23-
) {}
15+
/**
16+
* Resolves paths for known directories checked by entitlements.
17+
*/
18+
public interface PathLookup {
19+
enum BaseDir {
20+
USER_HOME,
21+
CONFIG,
22+
DATA,
23+
SHARED_REPO,
24+
LIB,
25+
MODULES,
26+
PLUGINS,
27+
LOGS,
28+
TEMP
29+
}
30+
31+
Path pidFile();
32+
33+
Stream<Path> getBaseDirPaths(BaseDir baseDir);
34+
35+
Stream<Path> resolveRelativePaths(BaseDir baseDir, Path relativePath);
36+
37+
Stream<Path> resolveSettingPaths(BaseDir baseDir, String settingName);
38+
}

0 commit comments

Comments
 (0)