Guard systemd library lookup from unreadable directories (#108931)

When scanning the library path we may come across directories that are
unreadable. If that happens, the recursive walk of the library path
directories will throw a fatal IOException. This commit guards the walk
of the library paths to first check for readability of each directory we
are about to traverse.
This commit is contained in:
Ryan Ernst 2024-05-23 05:50:55 -07:00 committed by GitHub
parent ef646436ce
commit 02083d6f11
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 35 additions and 7 deletions

View file

@ -0,0 +1,5 @@
pr: 108931
summary: Guard systemd library lookup from unreadable directories
area: Infra/Core
type: bug
issues: []

View file

@ -16,9 +16,13 @@ import java.lang.foreign.Arena;
import java.lang.foreign.FunctionDescriptor; import java.lang.foreign.FunctionDescriptor;
import java.lang.foreign.MemorySegment; import java.lang.foreign.MemorySegment;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.nio.file.FileVisitResult;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -61,17 +65,36 @@ class JdkSystemdLibrary implements SystemdLibrary {
// so we must manually check the library path to find what we need. // so we must manually check the library path to find what we need.
final Path libsystemd = Paths.get("libsystemd.so.0"); final Path libsystemd = Paths.get("libsystemd.so.0");
final String libpath = System.getProperty("java.library.path"); final String libpath = System.getProperty("java.library.path");
return Arrays.stream(libpath.split(":")).map(Paths::get).filter(Files::exists).flatMap(p -> { final List<String> foundPaths = new ArrayList<>();
Arrays.stream(libpath.split(":")).map(Paths::get).filter(Files::exists).forEach(rootPath -> {
try { try {
return Files.find( Files.walkFileTree(rootPath, new SimpleFileVisitor<>() {
p, @Override
Integer.MAX_VALUE, public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
(fp, attrs) -> (attrs.isDirectory() == false && fp.getFileName().equals(libsystemd)) if (Files.isReadable(dir)) {
); return FileVisitResult.CONTINUE;
}
return FileVisitResult.SKIP_SUBTREE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
if (file.getFileName().equals(libsystemd)) {
foundPaths.add(file.toAbsolutePath().toString());
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) { } catch (IOException e) {
throw new UncheckedIOException(e); throw new UncheckedIOException(e);
} }
}).map(p -> p.toAbsolutePath().toString()).toList(); });
return foundPaths;
} }
private static final MethodHandle sd_notify$mh = downcallHandle("sd_notify", FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS)); private static final MethodHandle sd_notify$mh = downcallHandle("sd_notify", FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS));