From 939980ec11b7d880814da936742d0653403e5a40 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Thu, 13 Feb 2020 11:48:40 +0100 Subject: [PATCH] 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 --- .../util/internal/PlatformDependent.java | 82 +++++++++++-------- 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/common/src/main/java/io/netty/util/internal/PlatformDependent.java b/common/src/main/java/io/netty/util/internal/PlatformDependent.java index 85d6aaf593f..d830e9132df 100644 --- a/common/src/main/java/io/netty/util/internal/PlatformDependent.java +++ b/common/src/main/java/io/netty/util/internal/PlatformDependent.java @@ -49,7 +49,6 @@ import java.util.Locale; import java.util.Queue; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.atomic.AtomicLong; import java.util.regex.Matcher; @@ -113,7 +112,10 @@ public final class PlatformDependent { private static final long DIRECT_MEMORY_LIMIT; private static final Cleaner CLEANER; 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; private static final Cleaner NOOP = buffer -> { @@ -187,45 +189,55 @@ public final class PlatformDependent { "instability."); } - // For specifications, see https://www.freedesktop.org/software/systemd/man/os-release.html - final String[] OS_RELEASE_FILES = {"/etc/os-release", "/usr/lib/os-release"}; - final String LINUX_ID_PREFIX = "ID="; - final String LINUX_ID_LIKE_PREFIX = "ID_LIKE="; - Set allowedClassifiers = new HashSet(Arrays.asList(ALLOWED_LINUX_OS_CLASSIFIERS)); - allowedClassifiers = Collections.unmodifiableSet(allowedClassifiers); - Set availableClassifiers = new LinkedHashSet(); - - for (String osReleaseFileName : OS_RELEASE_FILES) { + final Set allowedClassifiers = Collections.unmodifiableSet( + new HashSet(Arrays.asList(ALLOWED_LINUX_OS_CLASSIFIERS))); + final Set availableClassifiers = new LinkedHashSet(); + for (final String osReleaseFileName : OS_RELEASE_FILES) { final File file = new File(osReleaseFileName); - if (file.exists()) { - BufferedReader reader = null; + boolean found = AccessController.doPrivileged((PrivilegedAction) () -> { try { - reader = new BufferedReader( - new InputStreamReader( - new FileInputStream(file), CharsetUtil.UTF_8)); - - String line; - while ((line = reader.readLine()) != null) { - if (line.startsWith(LINUX_ID_PREFIX)) { - String id = normalizeOsReleaseVariableValue(line.substring(LINUX_ID_PREFIX.length())); - addClassifier(allowedClassifiers, availableClassifiers, id); - } else if (line.startsWith(LINUX_ID_LIKE_PREFIX)) { - line = normalizeOsReleaseVariableValue(line.substring(LINUX_ID_LIKE_PREFIX.length())); - addClassifier(allowedClassifiers, availableClassifiers, line.split("[ ]+")); - } - } - } catch (IOException ignored) { - // Ignore - } finally { - if (reader != null) { + if (file.exists()) { + BufferedReader reader = null; try { - reader.close(); - } catch (IOException ignored) { - // Ignore + reader = new BufferedReader( + new InputStreamReader( + new FileInputStream(file), CharsetUtil.UTF_8)); + + String line; + while ((line = reader.readLine()) != null) { + if (line.startsWith(LINUX_ID_PREFIX)) { + String id = normalizeOsReleaseVariableValue( + line.substring(LINUX_ID_PREFIX.length())); + addClassifier(allowedClassifiers, availableClassifiers, id); + } else if (line.startsWith(LINUX_ID_LIKE_PREFIX)) { + line = normalizeOsReleaseVariableValue( + line.substring(LINUX_ID_LIKE_PREFIX.length())); + addClassifier(allowedClassifiers, availableClassifiers, line.split("[ ]+")); + } + } + } catch (SecurityException e) { + logger.debug("Unable to read {}", osReleaseFileName, e); + } catch (IOException e) { + logger.debug("Error while reading content of {}", osReleaseFileName, e); + } finally { + if (reader != null) { + try { + reader.close(); + } catch (IOException ignored) { + // Ignore + } + } } + // 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); } - // specification states we should only fall back if /etc/os-release does not exist + return false; + }); + + if (found) { break; } }