java.security.AccessControlException: access denied ("java.io.FilePermission" "/etc/os-release" "read") (#10018)

Motivation:

Modifications:

- Wrap the code and execute with an AccessController
- Ignore SecurityException (by just logging it)
- Add some more debug logging

Result:

Fixes https://github.com/netty/netty/issues/10017
This commit is contained in:
Norman Maurer 2020-02-13 11:48:40 +01:00
parent 6980e0de65
commit 0cd4109f64

View File

@ -49,7 +49,6 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Queue; import java.util.Queue;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -113,7 +112,10 @@ public final class PlatformDependent {
private static final long DIRECT_MEMORY_LIMIT; private static final long DIRECT_MEMORY_LIMIT;
private static final Cleaner CLEANER; private static final Cleaner CLEANER;
private static final int UNINITIALIZED_ARRAY_ALLOCATION_THRESHOLD; private static final int UNINITIALIZED_ARRAY_ALLOCATION_THRESHOLD;
// For specifications, see https://www.freedesktop.org/software/systemd/man/os-release.html
private static final String[] OS_RELEASE_FILES = {"/etc/os-release", "/usr/lib/os-release"};
private static final String LINUX_ID_PREFIX = "ID=";
private static final String LINUX_ID_LIKE_PREFIX = "ID_LIKE=";
public static final boolean BIG_ENDIAN_NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; public static final boolean BIG_ENDIAN_NATIVE_ORDER = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
private static final Cleaner NOOP = buffer -> { private static final Cleaner NOOP = buffer -> {
@ -187,16 +189,13 @@ public final class PlatformDependent {
"instability."); "instability.");
} }
// For specifications, see https://www.freedesktop.org/software/systemd/man/os-release.html final Set<String> allowedClassifiers = Collections.unmodifiableSet(
final String[] OS_RELEASE_FILES = {"/etc/os-release", "/usr/lib/os-release"}; new HashSet<String>(Arrays.asList(ALLOWED_LINUX_OS_CLASSIFIERS)));
final String LINUX_ID_PREFIX = "ID="; final Set<String> availableClassifiers = new LinkedHashSet<String>();
final String LINUX_ID_LIKE_PREFIX = "ID_LIKE="; for (final String osReleaseFileName : OS_RELEASE_FILES) {
Set<String> allowedClassifiers = new HashSet<String>(Arrays.asList(ALLOWED_LINUX_OS_CLASSIFIERS));
allowedClassifiers = Collections.unmodifiableSet(allowedClassifiers);
Set<String> availableClassifiers = new LinkedHashSet<String>();
for (String osReleaseFileName : OS_RELEASE_FILES) {
final File file = new File(osReleaseFileName); final File file = new File(osReleaseFileName);
boolean found = AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> {
try {
if (file.exists()) { if (file.exists()) {
BufferedReader reader = null; BufferedReader reader = null;
try { try {
@ -207,15 +206,19 @@ public final class PlatformDependent {
String line; String line;
while ((line = reader.readLine()) != null) { while ((line = reader.readLine()) != null) {
if (line.startsWith(LINUX_ID_PREFIX)) { if (line.startsWith(LINUX_ID_PREFIX)) {
String id = normalizeOsReleaseVariableValue(line.substring(LINUX_ID_PREFIX.length())); String id = normalizeOsReleaseVariableValue(
line.substring(LINUX_ID_PREFIX.length()));
addClassifier(allowedClassifiers, availableClassifiers, id); addClassifier(allowedClassifiers, availableClassifiers, id);
} else if (line.startsWith(LINUX_ID_LIKE_PREFIX)) { } else if (line.startsWith(LINUX_ID_LIKE_PREFIX)) {
line = normalizeOsReleaseVariableValue(line.substring(LINUX_ID_LIKE_PREFIX.length())); line = normalizeOsReleaseVariableValue(
line.substring(LINUX_ID_LIKE_PREFIX.length()));
addClassifier(allowedClassifiers, availableClassifiers, line.split("[ ]+")); addClassifier(allowedClassifiers, availableClassifiers, line.split("[ ]+"));
} }
} }
} catch (IOException ignored) { } catch (SecurityException e) {
// Ignore logger.debug("Unable to read {}", osReleaseFileName, e);
} catch (IOException e) {
logger.debug("Error while reading content of {}", osReleaseFileName, e);
} finally { } finally {
if (reader != null) { if (reader != null) {
try { try {
@ -226,6 +229,15 @@ public final class PlatformDependent {
} }
} }
// specification states we should only fall back if /etc/os-release does not exist // specification states we should only fall back if /etc/os-release does not exist
return true;
}
} catch (SecurityException e) {
logger.debug("Unable to check if {} exists", osReleaseFileName, e);
}
return false;
});
if (found) {
break; break;
} }
} }