Skip to content

Commit e355340

Browse files
authored
Merge branch 'main' into 2025/03/08/snapshot-finalization-threading
2 parents d278c14 + a2b0d96 commit e355340

File tree

41 files changed

+301
-384
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+301
-384
lines changed

docs/changelog/123588.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 123588
2+
summary: Give Kibana user 'all' permissions for .entity_analytics.* indices
3+
area: Infra/Core
4+
type: enhancement
5+
issues: []

docs/changelog/124451.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 124451
2+
summary: Improve downsample performance by avoiding to read unnecessary dimension values when downsampling.
3+
area: Downsampling
4+
type: bug
5+
issues: []

libs/entitlement/qa/entitled-plugin/src/main/java/org/elasticsearch/entitlement/qa/entitled/EntitledActions.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,19 @@ public static Path createTempSymbolicLink() throws IOException {
6666
return Files.createSymbolicLink(readDir().resolve("entitlements-link-" + random.nextLong()), readWriteDir());
6767
}
6868

69+
public static Path createK8sLikeMount() throws IOException {
70+
Path baseDir = readDir().resolve("k8s");
71+
var versionedDir = Files.createDirectories(baseDir.resolve("..version"));
72+
var actualFileMount = Files.createFile(versionedDir.resolve("mount-" + random.nextLong() + ".tmp"));
73+
74+
var dataDir = Files.createSymbolicLink(baseDir.resolve("..data"), versionedDir.getFileName());
75+
// mount-0.tmp -> ..data/mount-0.tmp -> ..version/mount-0.tmp
76+
return Files.createSymbolicLink(
77+
baseDir.resolve(actualFileMount.getFileName()),
78+
dataDir.getFileName().resolve(actualFileMount.getFileName())
79+
);
80+
}
81+
6982
public static URLConnection createHttpURLConnection() throws IOException {
7083
return URI.create("http://127.0.0.1:12345/").toURL().openConnection();
7184
}

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

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,13 @@ static void fileCreateTempFile() throws IOException {
9393

9494
@EntitlementTest(expectedAccess = PLUGINS)
9595
static void fileDelete() throws IOException {
96-
Path toDelete = readWriteDir().resolve("to_delete");
97-
EntitledActions.createFile(toDelete);
96+
var toDelete = EntitledActions.createTempFileForWrite();
9897
toDelete.toFile().delete();
9998
}
10099

101100
@EntitlementTest(expectedAccess = PLUGINS)
102101
static void fileDeleteOnExit() throws IOException {
103-
Path toDelete = readWriteDir().resolve("to_delete_on_exit");
104-
EntitledActions.createFile(toDelete);
102+
var toDelete = EntitledActions.createTempFileForWrite();
105103
toDelete.toFile().deleteOnExit();
106104
}
107105

@@ -174,9 +172,10 @@ static void fileMkdirs() {
174172

175173
@EntitlementTest(expectedAccess = PLUGINS)
176174
static void fileRenameTo() throws IOException {
177-
Path toRename = readWriteDir().resolve("to_rename");
175+
var dir = EntitledActions.createTempDirectoryForWrite();
176+
Path toRename = dir.resolve("to_rename");
178177
EntitledActions.createFile(toRename);
179-
toRename.toFile().renameTo(readWriteDir().resolve("renamed").toFile());
178+
toRename.toFile().renameTo(dir.resolve("renamed").toFile());
180179
}
181180

182181
@EntitlementTest(expectedAccess = PLUGINS)
@@ -206,8 +205,7 @@ static void fileSetReadableOwner() {
206205

207206
@EntitlementTest(expectedAccess = PLUGINS)
208207
static void fileSetReadOnly() throws IOException {
209-
Path readOnly = readWriteDir().resolve("read_only");
210-
EntitledActions.createFile(readOnly);
208+
Path readOnly = EntitledActions.createTempFileForWrite();
211209
readOnly.toFile().setReadOnly();
212210
}
213211

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,16 @@ static void checkFilesCreateSymbolicLink() throws IOException {
140140
}
141141
}
142142

143+
@EntitlementTest(expectedAccess = PLUGINS)
144+
static void checkFilesCreateRelativeSymbolicLink() throws IOException {
145+
var directory = EntitledActions.createTempDirectoryForWrite();
146+
try {
147+
Files.createSymbolicLink(directory.resolve("link"), Path.of("target"));
148+
} catch (UnsupportedOperationException | FileSystemException e) {
149+
// OK not to implement symbolic link in the filesystem
150+
}
151+
}
152+
143153
@EntitlementTest(expectedAccess = PLUGINS)
144154
static void checkFilesCreateLink() throws IOException {
145155
var directory = EntitledActions.createTempDirectoryForWrite();
@@ -150,6 +160,17 @@ static void checkFilesCreateLink() throws IOException {
150160
}
151161
}
152162

163+
@EntitlementTest(expectedAccess = PLUGINS)
164+
static void checkFilesCreateRelativeLink() throws IOException {
165+
var directory = EntitledActions.createTempDirectoryForWrite();
166+
var target = directory.resolve("target");
167+
try {
168+
Files.createLink(directory.resolve("link"), Path.of("target"));
169+
} catch (UnsupportedOperationException | FileSystemException e) {
170+
// OK not to implement symbolic link in the filesystem
171+
}
172+
}
173+
153174
@EntitlementTest(expectedAccess = PLUGINS)
154175
static void checkFilesDelete() throws IOException {
155176
var file = EntitledActions.createTempFileForWrite();

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
package org.elasticsearch.entitlement.qa.test;
1111

12+
import org.elasticsearch.entitlement.qa.entitled.EntitledActions;
13+
1214
import java.io.IOException;
1315
import java.nio.file.FileSystems;
1416
import java.nio.file.LinkOption;
@@ -24,6 +26,11 @@ static void checkToRealPath() throws IOException {
2426
FileCheckActions.readFile().toRealPath();
2527
}
2628

29+
@EntitlementTest(expectedAccess = PLUGINS)
30+
static void checkToRealPathWithK8sLikeMount() throws IOException, Exception {
31+
EntitledActions.createK8sLikeMount().toRealPath();
32+
}
33+
2734
@EntitlementTest(expectedAccess = PLUGINS)
2835
static void checkToRealPathNoFollow() throws IOException {
2936
FileCheckActions.readFile().toRealPath(LinkOption.NOFOLLOW_LINKS);

libs/entitlement/qa/src/javaRestTest/java/org/elasticsearch/entitlement/qa/EntitlementsTestRule.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class EntitlementsTestRule implements TestRule {
4040
"files",
4141
List.of(
4242
Map.of("path", tempDir.resolve("read_dir"), "mode", "read_write"),
43+
Map.of("path", tempDir.resolve("read_dir").resolve("k8s").resolve("..data"), "mode", "read", "exclusive", true),
4344
Map.of("path", tempDir.resolve("read_write_dir"), "mode", "read_write"),
4445
Map.of("path", tempDir.resolve("read_file"), "mode", "read"),
4546
Map.of("path", tempDir.resolve("read_write_file"), "mode", "read_write")

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

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.io.FileDescriptor;
2020
import java.io.FileFilter;
2121
import java.io.FilenameFilter;
22-
import java.io.IOException;
2322
import java.io.InputStream;
2423
import java.io.OutputStream;
2524
import java.io.PrintStream;
@@ -74,7 +73,6 @@
7473
import java.nio.file.FileStore;
7574
import java.nio.file.FileVisitOption;
7675
import java.nio.file.FileVisitor;
77-
import java.nio.file.Files;
7876
import java.nio.file.LinkOption;
7977
import java.nio.file.OpenOption;
8078
import java.nio.file.Path;
@@ -2050,16 +2048,21 @@ public void checkSelectorProviderInheritedChannel(Class<?> callerClass, Selector
20502048
policyManager.checkCreateTempFile(callerClass);
20512049
}
20522050

2051+
private static Path resolveLinkTarget(Path path, Path target) {
2052+
var parent = path.getParent();
2053+
return parent == null ? target : parent.resolve(target);
2054+
}
2055+
20532056
@Override
20542057
public void check$java_nio_file_Files$$createSymbolicLink(Class<?> callerClass, Path link, Path target, FileAttribute<?>... attrs) {
2055-
policyManager.checkFileRead(callerClass, target);
20562058
policyManager.checkFileWrite(callerClass, link);
2059+
policyManager.checkFileRead(callerClass, resolveLinkTarget(link, target));
20572060
}
20582061

20592062
@Override
20602063
public void check$java_nio_file_Files$$createLink(Class<?> callerClass, Path link, Path existing) {
2061-
policyManager.checkFileRead(callerClass, existing);
20622064
policyManager.checkFileWrite(callerClass, link);
2065+
policyManager.checkFileRead(callerClass, resolveLinkTarget(link, existing));
20632066
}
20642067

20652068
@Override
@@ -2548,13 +2551,13 @@ public void checkCreateDirectory(Class<?> callerClass, FileSystemProvider that,
25482551
@Override
25492552
public void checkCreateSymbolicLink(Class<?> callerClass, FileSystemProvider that, Path link, Path target, FileAttribute<?>... attrs) {
25502553
policyManager.checkFileWrite(callerClass, link);
2551-
policyManager.checkFileRead(callerClass, target);
2554+
policyManager.checkFileRead(callerClass, resolveLinkTarget(link, target));
25522555
}
25532556

25542557
@Override
25552558
public void checkCreateLink(Class<?> callerClass, FileSystemProvider that, Path link, Path existing) {
25562559
policyManager.checkFileWrite(callerClass, link);
2557-
policyManager.checkFileRead(callerClass, existing);
2560+
policyManager.checkFileRead(callerClass, resolveLinkTarget(link, existing));
25582561
}
25592562

25602563
@Override
@@ -2748,14 +2751,7 @@ public void checkPathToRealPath(Class<?> callerClass, Path that, LinkOption... o
27482751
followLinks = false;
27492752
}
27502753
}
2751-
if (followLinks) {
2752-
try {
2753-
policyManager.checkFileRead(callerClass, Files.readSymbolicLink(that));
2754-
} catch (IOException | UnsupportedOperationException e) {
2755-
// that is not a link, or unrelated IOException or unsupported
2756-
}
2757-
}
2758-
policyManager.checkFileRead(callerClass, that);
2754+
policyManager.checkFileRead(callerClass, that, followLinks);
27592755
}
27602756

27612757
@Override

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

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.elasticsearch.logging.Logger;
3232

3333
import java.io.File;
34+
import java.io.IOException;
3435
import java.lang.StackWalker.StackFrame;
3536
import java.lang.module.ModuleFinder;
3637
import java.lang.module.ModuleReference;
@@ -325,6 +326,10 @@ private static boolean isPathOnDefaultFilesystem(Path path) {
325326
}
326327

327328
public void checkFileRead(Class<?> callerClass, Path path) {
329+
checkFileRead(callerClass, path, false);
330+
}
331+
332+
public void checkFileRead(Class<?> callerClass, Path path, boolean followLinks) {
328333
if (isPathOnDefaultFilesystem(path) == false) {
329334
return;
330335
}
@@ -334,14 +339,28 @@ public void checkFileRead(Class<?> callerClass, Path path) {
334339
}
335340

336341
ModuleEntitlements entitlements = getEntitlements(requestingClass);
337-
if (entitlements.fileAccess().canRead(path) == false) {
342+
343+
Path realPath = null;
344+
boolean canRead = entitlements.fileAccess().canRead(path);
345+
if (canRead && followLinks) {
346+
try {
347+
realPath = path.toRealPath();
348+
} catch (IOException e) {
349+
// target not found or other IO error
350+
}
351+
if (realPath != null && realPath.equals(path) == false) {
352+
canRead = entitlements.fileAccess().canRead(realPath);
353+
}
354+
}
355+
356+
if (canRead == false) {
338357
notEntitled(
339358
Strings.format(
340359
"Not entitled: component [%s], module [%s], class [%s], entitlement [file], operation [read], path [%s]",
341360
entitlements.componentName(),
342361
requestingClass.getModule().getName(),
343362
requestingClass,
344-
path
363+
realPath == null ? path : Strings.format("%s -> %s", path, realPath)
345364
),
346365
callerClass
347366
);

libs/entitlement/src/test/java/org/elasticsearch/entitlement/runtime/policy/FileAccessTreeTests.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -365,17 +365,17 @@ public void testDuplicatePrunedPaths() {
365365

366366
public void testDuplicateExclusivePaths() {
367367
// Bunch o' handy definitions
368-
var originalFileData = FileData.ofPath(path("/a/b"), READ).withExclusive(true);
369-
var fileDataWithWriteMode = FileData.ofPath(path("/a/b"), READ_WRITE).withExclusive(true);
368+
var pathAB = path("/a/b");
369+
var pathCD = path("/c/d");
370+
var originalFileData = FileData.ofPath(pathAB, READ).withExclusive(true);
371+
var fileDataWithWriteMode = FileData.ofPath(pathAB, READ_WRITE).withExclusive(true);
370372
var original = new ExclusiveFileEntitlement("component1", "module1", new FilesEntitlement(List.of(originalFileData)));
371373
var differentComponent = new ExclusiveFileEntitlement("component2", original.moduleName(), original.filesEntitlement());
372374
var differentModule = new ExclusiveFileEntitlement(original.componentName(), "module2", original.filesEntitlement());
373375
var differentPath = new ExclusiveFileEntitlement(
374376
original.componentName(),
375377
original.moduleName(),
376-
new FilesEntitlement(
377-
List.of(FileData.ofPath(path("/c/d"), originalFileData.mode()).withExclusive(originalFileData.exclusive()))
378-
)
378+
new FilesEntitlement(List.of(FileData.ofPath(pathCD, originalFileData.mode()).withExclusive(originalFileData.exclusive())))
379379
);
380380
var differentMode = new ExclusiveFileEntitlement(
381381
original.componentName(),
@@ -387,7 +387,7 @@ public void testDuplicateExclusivePaths() {
387387
original.moduleName(),
388388
new FilesEntitlement(List.of(originalFileData.withPlatform(WINDOWS)))
389389
);
390-
var originalExclusivePath = new ExclusivePath("component1", Set.of("module1"), normalizePath(path("/a/b")));
390+
var originalExclusivePath = new ExclusivePath("component1", Set.of("module1"), normalizePath(pathAB));
391391

392392
// Some basic tests
393393

@@ -409,12 +409,17 @@ public void testDuplicateExclusivePaths() {
409409
originalExclusivePath,
410410
new ExclusivePath("component2", Set.of(original.moduleName()), originalExclusivePath.path()),
411411
new ExclusivePath(original.componentName(), Set.of("module2"), originalExclusivePath.path()),
412-
new ExclusivePath(original.componentName(), Set.of(original.moduleName()), normalizePath(path("/c/d")))
412+
new ExclusivePath(original.componentName(), Set.of(original.moduleName()), normalizePath(pathCD))
413413
);
414414
var iae = expectThrows(IllegalArgumentException.class, () -> buildExclusivePathList(distinctEntitlements, TEST_PATH_LOOKUP));
415+
var pathABString = pathAB.toAbsolutePath().toString();
415416
assertThat(
416417
iae.getMessage(),
417-
equalTo("Path [/a/b] is already exclusive to [component1][module1], cannot add exclusive access for [component2][module1]")
418+
equalTo(
419+
"Path ["
420+
+ pathABString
421+
+ "] is already exclusive to [component1][module1], cannot add exclusive access for [component2][module1]"
422+
)
418423
);
419424

420425
var equivalentEntitlements = List.of(original, differentMode, differentPlatform);

0 commit comments

Comments
 (0)