Skip to content

Commit 094bb7e

Browse files
committed
better logging / handling of links
1 parent 91221e3 commit 094bb7e

File tree

2 files changed

+48
-36
lines changed

2 files changed

+48
-36
lines changed

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

Lines changed: 1 addition & 12 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;
@@ -71,7 +70,6 @@
7170
import java.nio.file.FileStore;
7271
import java.nio.file.FileVisitOption;
7372
import java.nio.file.FileVisitor;
74-
import java.nio.file.Files;
7573
import java.nio.file.LinkOption;
7674
import java.nio.file.OpenOption;
7775
import java.nio.file.Path;
@@ -2760,16 +2758,7 @@ public void checkPathToRealPath(Class<?> callerClass, Path that, LinkOption... o
27602758
followLinks = false;
27612759
}
27622760
}
2763-
if (followLinks) {
2764-
try {
2765-
Path symbolicLink = Files.readSymbolicLink(that);
2766-
policyManager.checkFileRead(callerClass, that, symbolicLink);
2767-
return;
2768-
} catch (IOException | UnsupportedOperationException e) {
2769-
// that is not a link, or unrelated IOException or unsupported
2770-
}
2771-
}
2772-
policyManager.checkFileRead(callerClass, that);
2761+
policyManager.checkFileRead(callerClass, that, followLinks);
27732762
}
27742763

27752764
@Override

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

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@
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;
38+
import java.nio.file.Files;
3739
import java.nio.file.Path;
3840
import java.util.ArrayList;
39-
import java.util.Arrays;
4041
import java.util.HashSet;
4142
import java.util.List;
4243
import java.util.Map;
@@ -325,31 +326,53 @@ private static boolean isPathOnDefaultFilesystem(Path path) {
325326
return true;
326327
}
327328

328-
public void checkFileRead(Class<?> callerClass, Path... paths) {
329-
for (var path : paths) {
330-
if (isPathOnDefaultFilesystem(path) == false) {
331-
return;
332-
}
333-
var requestingClass = requestingClass(callerClass);
334-
if (isTriviallyAllowed(requestingClass)) {
335-
return;
336-
}
329+
public void checkFileRead(Class<?> callerClass, Path path) {
330+
checkFileRead(callerClass, path, false);
331+
}
337332

338-
ModuleEntitlements entitlements = getEntitlements(requestingClass);
339-
if (entitlements.fileAccess().canRead(path) == false) {
340-
logger.info(entitlements.fileAccess().toDebugString());
341-
notEntitled(
342-
Strings.format(
343-
"Not entitled: component [%s], module [%s], class [%s], entitlement [file], operation [read], path [%s]",
344-
entitlements.componentName(),
345-
requestingClass.getModule().getName(),
346-
requestingClass,
347-
Arrays.stream(paths).map(FileAccessTree::normalizePath).collect(Collectors.joining(", "))
348-
),
349-
callerClass
350-
);
333+
public void checkFileRead(Class<?> callerClass, Path path, boolean followLinks) {
334+
if (isPathOnDefaultFilesystem(path) == false) {
335+
return;
336+
}
337+
var requestingClass = requestingClass(callerClass);
338+
if (isTriviallyAllowed(requestingClass)) {
339+
return;
340+
}
341+
342+
ModuleEntitlements entitlements = getEntitlements(requestingClass);
343+
344+
Path realPath = null, symbolicLinkPath = null;
345+
boolean canRead = entitlements.fileAccess().canRead(path);
346+
347+
if (canRead && followLinks) {
348+
try {
349+
realPath = path.toRealPath();
350+
} catch (IOException e) {}
351+
try {
352+
symbolicLinkPath = Files.readSymbolicLink(path);
353+
canRead = entitlements.fileAccess.canRead(symbolicLinkPath);
354+
} catch (IOException e) {}
355+
356+
if (canRead == false) {
357+
logger.warn("Cannot read symbolic link [{} -> {}]: [real path: {}]", path, symbolicLinkPath, realPath);
351358
}
352359
}
360+
361+
if (canRead == false) {
362+
logger.info(entitlements.fileAccess().toDebugString());
363+
notEntitled(
364+
Strings.format(
365+
"Not entitled: component [%s], module [%s], class [%s], entitlement [file], operation [read], path [%s]",
366+
entitlements.componentName(),
367+
requestingClass.getModule().getName(),
368+
requestingClass,
369+
symbolicLinkPath == null
370+
? FileAccessTree.normalizePath(path)
371+
: FileAccessTree.normalizePath(path) + " -> " + FileAccessTree.normalizePath(symbolicLinkPath)
372+
),
373+
callerClass
374+
);
375+
}
353376
}
354377

355378
@SuppressForbidden(reason = "Explicitly checking File apis")
@@ -612,7 +635,7 @@ Optional<Class<?>> findRequestingClass(Stream<Class<?>> classes) {
612635
/**
613636
* @return true if permission is granted regardless of the entitlement
614637
*/
615-
private static boolean isTriviallyAllowed(Class<?> requestingClass) {
638+
protected static boolean isTriviallyAllowed(Class<?> requestingClass) {
616639
if (logger.isTraceEnabled()) {
617640
logger.trace("Stack trace for upcoming trivially-allowed check", new Exception());
618641
}

0 commit comments

Comments
 (0)