Skip to content

Commit 9cb4f48

Browse files
Merge branch 'main' into threadpool-merge-scheduler-sort-all-merges-take-2
2 parents f2b1472 + 7fd1add commit 9cb4f48

File tree

34 files changed

+1254
-69
lines changed

34 files changed

+1254
-69
lines changed

build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/RestrictedBuildApiService.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ private static ListMultimap<Class<?>, String> createLegacyRestTestBasePluginUsag
9393
map.put(LegacyRestTestBasePlugin.class, ":x-pack:qa:smoke-test-security-with-mustache");
9494
map.put(LegacyRestTestBasePlugin.class, ":x-pack:qa:xpack-prefix-rest-compat");
9595
map.put(LegacyRestTestBasePlugin.class, ":modules:ingest-geoip:qa:file-based-update");
96-
map.put(LegacyRestTestBasePlugin.class, ":plugins:discovery-ec2:qa:amazon-ec2");
9796
map.put(LegacyRestTestBasePlugin.class, ":plugins:discovery-gce:qa:gce");
9897
map.put(LegacyRestTestBasePlugin.class, ":x-pack:qa:multi-cluster-search-security:legacy-with-basic-license");
9998
map.put(LegacyRestTestBasePlugin.class, ":x-pack:qa:multi-cluster-search-security:legacy-with-full-license");

docs/changelog/121971.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 121971
2+
summary: Do not fetch reserved roles from native store when Get Role API is called
3+
area: Authorization
4+
type: enhancement
5+
issues: []

libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@
5858
import java.nio.file.LinkOption;
5959
import java.nio.file.OpenOption;
6060
import java.nio.file.Path;
61+
import java.nio.file.WatchEvent;
62+
import java.nio.file.WatchService;
6163
import java.nio.file.attribute.FileAttribute;
6264
import java.nio.file.attribute.UserPrincipal;
6365
import java.nio.file.spi.FileSystemProvider;
@@ -654,6 +656,19 @@ void checkNewByteChannel(
654656

655657
void checkType(Class<?> callerClass, FileStore that);
656658

659+
// path
660+
void checkPathToRealPath(Class<?> callerClass, Path that, LinkOption... options);
661+
662+
void checkPathRegister(Class<?> callerClass, Path that, WatchService watcher, WatchEvent.Kind<?>... events);
663+
664+
void checkPathRegister(
665+
Class<?> callerClass,
666+
Path that,
667+
WatchService watcher,
668+
WatchEvent.Kind<?>[] events,
669+
WatchEvent.Modifier... modifiers
670+
);
671+
657672
////////////////////
658673
//
659674
// Thread management
@@ -674,5 +689,4 @@ void checkNewByteChannel(
674689
void check$java_lang_Thread$setUncaughtExceptionHandler(Class<?> callerClass, Thread thread, Thread.UncaughtExceptionHandler ueh);
675690

676691
void check$java_lang_ThreadGroup$setMaxPriority(Class<?> callerClass, ThreadGroup threadGroup, int pri);
677-
678692
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.entitlement.qa.test;
11+
12+
import java.io.IOException;
13+
import java.nio.file.FileSystems;
14+
import java.nio.file.LinkOption;
15+
import java.nio.file.WatchEvent;
16+
17+
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.PLUGINS;
18+
19+
class PathActions {
20+
21+
@EntitlementTest(expectedAccess = PLUGINS)
22+
static void checkToRealPath() throws IOException {
23+
FileCheckActions.readFile().toRealPath();
24+
}
25+
26+
@EntitlementTest(expectedAccess = PLUGINS)
27+
static void checkToRealPathNoFollow() throws IOException {
28+
FileCheckActions.readFile().toRealPath(LinkOption.NOFOLLOW_LINKS);
29+
}
30+
31+
@SuppressWarnings("rawtypes")
32+
@EntitlementTest(expectedAccess = PLUGINS)
33+
static void checkRegister() throws IOException {
34+
try (var watchService = FileSystems.getDefault().newWatchService()) {
35+
FileCheckActions.readFile().register(watchService, new WatchEvent.Kind[0]);
36+
} catch (IllegalArgumentException e) {
37+
// intentionally no events registered
38+
}
39+
}
40+
41+
@SuppressWarnings("rawtypes")
42+
@EntitlementTest(expectedAccess = PLUGINS)
43+
static void checkRegisterWithModifiers() throws IOException {
44+
try (var watchService = FileSystems.getDefault().newWatchService()) {
45+
FileCheckActions.readFile().register(watchService, new WatchEvent.Kind[0], new WatchEvent.Modifier[0]);
46+
} catch (IllegalArgumentException e) {
47+
// intentionally no events registered
48+
}
49+
}
50+
}

libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/RestEntitlementsCheckAction.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ static CheckAction alwaysDenied(CheckedRunnable<Exception> action) {
190190
getTestEntries(ManageThreadsActions.class),
191191
getTestEntries(NativeActions.class),
192192
getTestEntries(NioFileSystemActions.class),
193+
getTestEntries(PathActions.class),
193194
getTestEntries(SpiActions.class),
194195
getTestEntries(SystemActions.class)
195196
)

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ public record BootstrapArgs(
3838
Function<Class<?>, String> pluginResolver,
3939
Path[] dataDirs,
4040
Path configDir,
41-
Path tempDir
41+
Path tempDir,
42+
Path logsDir
4243
) {
4344
public BootstrapArgs {
4445
requireNonNull(pluginPolicies);
@@ -64,22 +65,24 @@ public static BootstrapArgs bootstrapArgs() {
6465
*
6566
* @param pluginPolicies a map holding policies for plugins (and modules), by plugin (or module) name.
6667
* @param pluginResolver a functor to map a Java Class to the plugin it belongs to (the plugin name).
67-
* @param dataDirs data directories for Elasticsearch
68-
* @param configDir the config directory for Elasticsearch
69-
* @param tempDir the temp directory for Elasticsearch
68+
* @param dataDirs data directories for Elasticsearch
69+
* @param configDir the config directory for Elasticsearch
70+
* @param tempDir the temp directory for Elasticsearch
71+
* @param logsDir the log directory for Elasticsearch
7072
*/
7173
public static void bootstrap(
7274
Map<String, Policy> pluginPolicies,
7375
Function<Class<?>, String> pluginResolver,
7476
Path[] dataDirs,
7577
Path configDir,
76-
Path tempDir
78+
Path tempDir,
79+
Path logsDir
7780
) {
7881
logger.debug("Loading entitlement agent");
7982
if (EntitlementBootstrap.bootstrapArgs != null) {
8083
throw new IllegalStateException("plugin data is already set");
8184
}
82-
EntitlementBootstrap.bootstrapArgs = new BootstrapArgs(pluginPolicies, pluginResolver, dataDirs, configDir, tempDir);
85+
EntitlementBootstrap.bootstrapArgs = new BootstrapArgs(pluginPolicies, pluginResolver, dataDirs, configDir, tempDir, logsDir);
8386
exportInitializationToAgent();
8487
loadAgent(findAgentJar());
8588
selfTest();

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

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,12 @@
4646
import java.nio.file.LinkOption;
4747
import java.nio.file.OpenOption;
4848
import java.nio.file.Path;
49+
import java.nio.file.WatchEvent;
50+
import java.nio.file.WatchService;
4951
import java.nio.file.attribute.FileAttribute;
5052
import java.nio.file.spi.FileSystemProvider;
5153
import java.util.ArrayList;
54+
import java.util.Arrays;
5255
import java.util.HashMap;
5356
import java.util.List;
5457
import java.util.Map;
@@ -59,6 +62,7 @@
5962
import java.util.stream.Stream;
6063
import java.util.stream.StreamSupport;
6164

65+
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.Mode.READ;
6266
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.Mode.READ_WRITE;
6367

6468
/**
@@ -95,6 +99,7 @@ public static void initialize(Instrumentation inst) throws Exception {
9599
Stream.of(
96100
fileSystemProviderChecks(),
97101
fileStoreChecks(),
102+
pathChecks(),
98103
Stream.of(
99104
INSTRUMENTATION_SERVICE.lookupImplementationMethod(
100105
SelectorProvider.class,
@@ -129,6 +134,7 @@ private static PolicyManager createPolicyManager() {
129134
EntitlementBootstrap.BootstrapArgs bootstrapArgs = EntitlementBootstrap.bootstrapArgs();
130135
Map<String, Policy> pluginPolicies = bootstrapArgs.pluginPolicies();
131136
var pathLookup = new PathLookup(bootstrapArgs.configDir(), bootstrapArgs.dataDirs(), bootstrapArgs.tempDir());
137+
Path logsDir = EntitlementBootstrap.bootstrapArgs().logsDir();
132138

133139
// TODO(ES-10031): Decide what goes in the elasticsearch default policy and extend it
134140
var serverPolicy = new Policy(
@@ -147,13 +153,49 @@ private static PolicyManager createPolicyManager() {
147153
new LoadNativeLibrariesEntitlement(),
148154
new ManageThreadsEntitlement(),
149155
new FilesEntitlement(
150-
List.of(FilesEntitlement.FileData.ofPath(EntitlementBootstrap.bootstrapArgs().tempDir(), READ_WRITE))
156+
Stream.concat(
157+
Stream.of(
158+
FileData.ofPath(bootstrapArgs.tempDir(), READ_WRITE),
159+
FileData.ofPath(bootstrapArgs.configDir(), READ),
160+
FileData.ofPath(bootstrapArgs.logsDir(), READ_WRITE),
161+
// OS release on Linux
162+
FileData.ofPath(Path.of("/etc/os-release"), READ),
163+
FileData.ofPath(Path.of("/etc/system-release"), READ),
164+
FileData.ofPath(Path.of("/usr/lib/os-release"), READ),
165+
// read max virtual memory areas
166+
FileData.ofPath(Path.of("/proc/sys/vm/max_map_count"), READ),
167+
FileData.ofPath(Path.of("/proc/meminfo"), READ),
168+
// load averages on Linux
169+
FileData.ofPath(Path.of("/proc/loadavg"), READ),
170+
// control group stats on Linux. cgroup v2 stats are in an unpredicable
171+
// location under `/sys/fs/cgroup`, so unfortunately we have to allow
172+
// read access to the entire directory hierarchy.
173+
FileData.ofPath(Path.of("/proc/self/cgroup"), READ),
174+
FileData.ofPath(Path.of("/sys/fs/cgroup/"), READ),
175+
// // io stats on Linux
176+
FileData.ofPath(Path.of("/proc/self/mountinfo"), READ),
177+
FileData.ofPath(Path.of("/proc/diskstats"), READ)
178+
),
179+
Arrays.stream(bootstrapArgs.dataDirs()).map(d -> FileData.ofPath(d, READ))
180+
).toList()
151181
)
152182
)
153183
),
154184
new Scope("org.apache.httpcomponents.httpclient", List.of(new OutboundNetworkEntitlement())),
155185
new Scope("io.netty.transport", List.of(new InboundNetworkEntitlement(), new OutboundNetworkEntitlement())),
156-
new Scope("org.apache.lucene.core", List.of(new LoadNativeLibrariesEntitlement(), new ManageThreadsEntitlement())),
186+
new Scope(
187+
"org.apache.lucene.core",
188+
List.of(
189+
new LoadNativeLibrariesEntitlement(),
190+
new ManageThreadsEntitlement(),
191+
new FilesEntitlement(
192+
Stream.concat(
193+
Stream.of(FileData.ofPath(bootstrapArgs.configDir(), READ)),
194+
Arrays.stream(bootstrapArgs.dataDirs()).map(d -> FileData.ofPath(d, READ_WRITE))
195+
).toList()
196+
)
197+
)
198+
),
157199
new Scope("org.apache.logging.log4j.core", List.of(new ManageThreadsEntitlement())),
158200
new Scope(
159201
"org.elasticsearch.nativeaccess",
@@ -267,6 +309,33 @@ public InstrumentationService.InstrumentationInfo of(String methodName, Class<?>
267309
});
268310
}
269311

312+
private static Stream<InstrumentationService.InstrumentationInfo> pathChecks() {
313+
var pathClasses = StreamSupport.stream(FileSystems.getDefault().getRootDirectories().spliterator(), false)
314+
.map(Path::getClass)
315+
.distinct();
316+
return pathClasses.flatMap(pathClass -> {
317+
InstrumentationInfoFactory instrumentation = (String methodName, Class<?>... parameterTypes) -> INSTRUMENTATION_SERVICE
318+
.lookupImplementationMethod(
319+
Path.class,
320+
methodName,
321+
pathClass,
322+
EntitlementChecker.class,
323+
"checkPath" + Character.toUpperCase(methodName.charAt(0)) + methodName.substring(1),
324+
parameterTypes
325+
);
326+
327+
try {
328+
return Stream.of(
329+
instrumentation.of("toRealPath", LinkOption[].class),
330+
instrumentation.of("register", WatchService.class, WatchEvent.Kind[].class),
331+
instrumentation.of("register", WatchService.class, WatchEvent.Kind[].class, WatchEvent.Modifier[].class)
332+
);
333+
} catch (NoSuchMethodException | ClassNotFoundException e) {
334+
throw new RuntimeException(e);
335+
}
336+
});
337+
}
338+
270339
/**
271340
* Returns the "most recent" checker class compatible with the current runtime Java version.
272341
* For checkers, we have (optionally) version specific classes, each with a prefix (e.g. Java23).

libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.elasticsearch.entitlement.runtime.policy.PolicyManager;
1515

1616
import java.io.File;
17+
import java.io.IOException;
1718
import java.io.InputStream;
1819
import java.io.PrintStream;
1920
import java.io.PrintWriter;
@@ -60,10 +61,13 @@
6061
import java.nio.file.CopyOption;
6162
import java.nio.file.DirectoryStream;
6263
import java.nio.file.FileStore;
64+
import java.nio.file.Files;
6365
import java.nio.file.LinkOption;
6466
import java.nio.file.OpenOption;
6567
import java.nio.file.Path;
6668
import java.nio.file.StandardOpenOption;
69+
import java.nio.file.WatchEvent;
70+
import java.nio.file.WatchService;
6771
import java.nio.file.attribute.FileAttribute;
6872
import java.nio.file.attribute.UserPrincipal;
6973
import java.nio.file.spi.FileSystemProvider;
@@ -1369,4 +1373,38 @@ public void checkName(Class<?> callerClass, FileStore that) {
13691373
public void checkType(Class<?> callerClass, FileStore that) {
13701374
policyManager.checkReadStoreAttributes(callerClass);
13711375
}
1376+
1377+
@Override
1378+
public void checkPathToRealPath(Class<?> callerClass, Path that, LinkOption... options) {
1379+
boolean followLinks = true;
1380+
for (LinkOption option : options) {
1381+
if (option == LinkOption.NOFOLLOW_LINKS) {
1382+
followLinks = false;
1383+
}
1384+
}
1385+
if (followLinks) {
1386+
try {
1387+
policyManager.checkFileRead(callerClass, Files.readSymbolicLink(that));
1388+
} catch (IOException | UnsupportedOperationException e) {
1389+
// that is not a link, or unrelated IOException or unsupported
1390+
}
1391+
}
1392+
policyManager.checkFileRead(callerClass, that);
1393+
}
1394+
1395+
@Override
1396+
public void checkPathRegister(Class<?> callerClass, Path that, WatchService watcher, WatchEvent.Kind<?>... events) {
1397+
policyManager.checkFileRead(callerClass, that);
1398+
}
1399+
1400+
@Override
1401+
public void checkPathRegister(
1402+
Class<?> callerClass,
1403+
Path that,
1404+
WatchService watcher,
1405+
WatchEvent.Kind<?>[] events,
1406+
WatchEvent.Modifier... modifiers
1407+
) {
1408+
policyManager.checkFileRead(callerClass, that);
1409+
}
13721410
}

0 commit comments

Comments
 (0)