8344235: Revisit SecurityManager usage in java.logging after JEP 486 and JEP 491 integration

Reviewed-by: jpai
This commit is contained in:
Daniel Fuchs 2024-11-21 11:54:28 +00:00
parent 18df6fd5ba
commit a62279ca0a
17 changed files with 202 additions and 903 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,9 +25,6 @@
package jdk.internal.logger; package jdk.internal.logger;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
@ -131,15 +128,8 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
@Override @Override
public Thread newThread(Runnable r) { public Thread newThread(Runnable r) {
ExecutorService owner = getExecutor(); ExecutorService owner = getExecutor();
@SuppressWarnings("removal") Thread thread = InnocuousThread.newThread(new BootstrapMessageLoggerTask(owner, r));
Thread thread = AccessController.doPrivileged(new PrivilegedAction<Thread>() { thread.setName("BootstrapMessageLoggerTask-" + thread.getName());
@Override
public Thread run() {
Thread t = InnocuousThread.newThread(new BootstrapMessageLoggerTask(owner, r));
t.setName("BootstrapMessageLoggerTask-"+t.getName());
return t;
}
}, null, new RuntimePermission("enableContextClassLoaderOverride"));
thread.setDaemon(true); thread.setDaemon(true);
return thread; return thread;
} }
@ -269,8 +259,6 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
// the parameters etc... we need to store the context of the // the parameters etc... we need to store the context of the
// caller who logged the message - so that we can reuse it when // caller who logged the message - so that we can reuse it when
// we finally log the message. // we finally log the message.
@SuppressWarnings("removal")
final AccessControlContext acc;
// The next event in the queue // The next event in the queue
LogEvent next; LogEvent next;
@ -279,7 +267,6 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
private LogEvent(BootstrapLogger bootstrap, Level level, private LogEvent(BootstrapLogger bootstrap, Level level,
ResourceBundle bundle, String msg, ResourceBundle bundle, String msg,
Throwable thrown, Object[] params) { Throwable thrown, Object[] params) {
this.acc = AccessController.getContext();
this.timeMillis = System.currentTimeMillis(); this.timeMillis = System.currentTimeMillis();
this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis); this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis);
this.level = level; this.level = level;
@ -298,7 +285,6 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
private LogEvent(BootstrapLogger bootstrap, Level level, private LogEvent(BootstrapLogger bootstrap, Level level,
Supplier<String> msgSupplier, Supplier<String> msgSupplier,
Throwable thrown, Object[] params) { Throwable thrown, Object[] params) {
this.acc = AccessController.getContext();
this.timeMillis = System.currentTimeMillis(); this.timeMillis = System.currentTimeMillis();
this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis); this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis);
this.level = level; this.level = level;
@ -319,7 +305,6 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
String sourceClass, String sourceMethod, String sourceClass, String sourceMethod,
ResourceBundle bundle, String msg, ResourceBundle bundle, String msg,
Throwable thrown, Object[] params) { Throwable thrown, Object[] params) {
this.acc = AccessController.getContext();
this.timeMillis = System.currentTimeMillis(); this.timeMillis = System.currentTimeMillis();
this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis); this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis);
this.level = null; this.level = null;
@ -340,7 +325,6 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
String sourceClass, String sourceMethod, String sourceClass, String sourceMethod,
Supplier<String> msgSupplier, Supplier<String> msgSupplier,
Throwable thrown, Object[] params) { Throwable thrown, Object[] params) {
this.acc = AccessController.getContext();
this.timeMillis = System.currentTimeMillis(); this.timeMillis = System.currentTimeMillis();
this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis); this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis);
this.level = null; this.level = null;
@ -444,20 +428,12 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
Objects.requireNonNull(level), Objects.requireNonNull(level),
Objects.requireNonNull(msgSupplier), null, null); Objects.requireNonNull(msgSupplier), null, null);
} }
@SuppressWarnings("removal")
static void log(LogEvent log, Logger logger) { static void log(LogEvent log, Logger logger) {
final SecurityManager sm = System.getSecurityManager();
// not sure we can actually use lambda here. We may need to create // not sure we can actually use lambda here. We may need to create
// an anonymous class. Although if we reach here, then it means // an anonymous class. Although if we reach here, then it means
// the VM is booted. // the VM is booted.
if (sm == null || log.acc == null) {
BootstrapExecutors.submit(() -> log.log(logger)); BootstrapExecutors.submit(() -> log.log(logger));
} else {
BootstrapExecutors.submit(() ->
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
log.log(logger); return null;
}, log.acc));
}
} }
// non default methods from PlatformLogger.Bridge interface // non default methods from PlatformLogger.Bridge interface
@ -510,20 +486,9 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
Objects.requireNonNull(level), sourceClass, Objects.requireNonNull(level), sourceClass,
sourceMethod, msgSupplier, thrown, null); sourceMethod, msgSupplier, thrown, null);
} }
@SuppressWarnings("removal")
static void log(LogEvent log, PlatformLogger.Bridge logger) { static void log(LogEvent log, PlatformLogger.Bridge logger) {
final SecurityManager sm = System.getSecurityManager();
if (sm == null || log.acc == null) {
BootstrapExecutors.submit(() -> log.log(logger)); BootstrapExecutors.submit(() -> log.log(logger));
} else {
// not sure we can actually use lambda here. We may need to create
// an anonymous class. Although if we reach here, then it means
// the VM is booted.
BootstrapExecutors.submit(() ->
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
log.log(logger); return null;
}, log.acc));
}
} }
static void log(LogEvent event) { static void log(LogEvent event) {
@ -897,11 +862,9 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
// We do not want this field to get initialized if VM.isBooted() is false. // We do not want this field to get initialized if VM.isBooted() is false.
@SuppressWarnings("removal") @SuppressWarnings("removal")
private static final class DetectBackend { private static final class DetectBackend {
static final LoggingBackend detectedBackend; static final LoggingBackend detectedBackend = detectBackend();
static {
detectedBackend = AccessController.doPrivileged(new PrivilegedAction<LoggingBackend>() { static LoggingBackend detectBackend() {
@Override
public LoggingBackend run() {
final Iterator<LoggerFinder> iterator = final Iterator<LoggerFinder> iterator =
ServiceLoader.load(LoggerFinder.class, ClassLoader.getSystemClassLoader()) ServiceLoader.load(LoggerFinder.class, ClassLoader.getSystemClassLoader())
.iterator(); .iterator();
@ -926,9 +889,6 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
return LoggingBackend.NONE; return LoggingBackend.NONE;
} }
} }
});
}
} }
// We will use a temporary SurrogateLogger if // We will use a temporary SurrogateLogger if

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -36,8 +36,6 @@ import java.util.Objects;
import java.lang.System.LoggerFinder; import java.lang.System.LoggerFinder;
import java.lang.System.Logger; import java.lang.System.Logger;
import java.lang.ref.ReferenceQueue; import java.lang.ref.ReferenceQueue;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collection; import java.util.Collection;
import java.util.ResourceBundle; import java.util.ResourceBundle;
@ -70,7 +68,7 @@ import java.util.ResourceBundle;
* that provides the necessary configuration. * that provides the necessary configuration.
* *
* @apiNote Programmers are not expected to call this class directly. * @apiNote Programmers are not expected to call this class directly.
* Instead they should rely on the static methods defined by {@link * Instead, they should rely on the static methods defined by {@link
* java.lang.System java.lang.System} or {@link sun.util.logging.PlatformLogger * java.lang.System java.lang.System} or {@link sun.util.logging.PlatformLogger
* sun.util.logging.PlatformLogger}. * sun.util.logging.PlatformLogger}.
* *
@ -81,30 +79,12 @@ import java.util.ResourceBundle;
*/ */
public class DefaultLoggerFinder extends LoggerFinder { public class DefaultLoggerFinder extends LoggerFinder {
static final RuntimePermission LOGGERFINDER_PERMISSION =
new RuntimePermission("loggerFinder");
/** /**
* Creates a new instance of DefaultLoggerFinder. * Creates a new instance of DefaultLoggerFinder.
* @throws SecurityException if the calling code does not have the
* {@code RuntimePermission("loggerFinder")}
*/ */
protected DefaultLoggerFinder() { protected DefaultLoggerFinder() {
this(checkPermission());
} }
private DefaultLoggerFinder(Void unused) {
// nothing to do.
}
private static Void checkPermission() {
@SuppressWarnings("removal")
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGERFINDER_PERMISSION);
}
return null;
}
// SharedLoggers is a default cache of loggers used when JUL is not // SharedLoggers is a default cache of loggers used when JUL is not
// present - in that case we use instances of SimpleConsoleLogger which // present - in that case we use instances of SimpleConsoleLogger which
@ -139,23 +119,14 @@ public class DefaultLoggerFinder extends LoggerFinder {
static final SharedLoggers application = new SharedLoggers(); static final SharedLoggers application = new SharedLoggers();
} }
@SuppressWarnings("removal")
public static boolean isSystem(Module m) { public static boolean isSystem(Module m) {
return AccessController.doPrivileged(new PrivilegedAction<>() {
@Override
public Boolean run() {
// returns true if moduleCL is the platform class loader
// or one of its ancestors.
return VM.isSystemDomainLoader(m.getClassLoader()); return VM.isSystemDomainLoader(m.getClassLoader());
} }
});
}
@Override @Override
public final Logger getLogger(String name, Module module) { public final Logger getLogger(String name, Module module) {
Objects.requireNonNull(name, "name"); Objects.requireNonNull(name, "name");
Objects.requireNonNull(module, "module"); Objects.requireNonNull(module, "module");
checkPermission();
return demandLoggerFor(name, module); return demandLoggerFor(name, module);
} }
@ -176,11 +147,8 @@ public class DefaultLoggerFinder extends LoggerFinder {
* @param name The name of the logger. * @param name The name of the logger.
* @param module The module on behalf of which the logger is created. * @param module The module on behalf of which the logger is created.
* @return A {@link Logger logger} suitable for the application usage. * @return A {@link Logger logger} suitable for the application usage.
* @throws SecurityException if the calling code does not have the
* {@code RuntimePermission("loggerFinder")}.
*/ */
protected Logger demandLoggerFor(String name, Module module) { protected Logger demandLoggerFor(String name, Module module) {
checkPermission();
if (isSystem(module)) { if (isSystem(module)) {
return SharedLoggers.system.get(SimpleConsoleLogger::makeSimpleLogger, name); return SharedLoggers.system.get(SimpleConsoleLogger::makeSimpleLogger, name);
} else { } else {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,8 +25,6 @@
package jdk.internal.logger; package jdk.internal.logger;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.lang.System.LoggerFinder; import java.lang.System.LoggerFinder;
import java.lang.System.Logger; import java.lang.System.Logger;
@ -44,9 +42,6 @@ import sun.util.logging.PlatformLogger;
*/ */
public final class LazyLoggers { public final class LazyLoggers {
static final RuntimePermission LOGGERFINDER_PERMISSION =
new RuntimePermission("loggerFinder");
private LazyLoggers() { private LazyLoggers() {
throw new InternalError(); throw new InternalError();
} }
@ -341,7 +336,6 @@ public final class LazyLoggers {
// Do not expose this outside of this package. // Do not expose this outside of this package.
private static volatile LoggerFinder provider; private static volatile LoggerFinder provider;
@SuppressWarnings("removal")
private static LoggerFinder accessLoggerFinder() { private static LoggerFinder accessLoggerFinder() {
LoggerFinder prov = provider; LoggerFinder prov = provider;
if (prov == null) { if (prov == null) {
@ -350,10 +344,7 @@ public final class LazyLoggers {
// the result. // the result.
// This is just an optimization to avoid the cost of calling // This is just an optimization to avoid the cost of calling
// doPrivileged every time. // doPrivileged every time.
final SecurityManager sm = System.getSecurityManager(); prov = LoggerFinder.getLoggerFinder();
prov = sm == null ? LoggerFinder.getLoggerFinder() :
AccessController.doPrivileged(
(PrivilegedAction<LoggerFinder>)LoggerFinder::getLoggerFinder);
if (prov instanceof TemporaryLoggerFinder) return prov; if (prov instanceof TemporaryLoggerFinder) return prov;
provider = prov; provider = prov;
} }
@ -403,16 +394,8 @@ public final class LazyLoggers {
* @param module module on behalf of which the logger is created * @param module module on behalf of which the logger is created
* @return The logger returned by the LoggerFinder. * @return The logger returned by the LoggerFinder.
*/ */
@SuppressWarnings("removal")
static Logger getLoggerFromFinder(String name, Module module) { static Logger getLoggerFromFinder(String name, Module module) {
final SecurityManager sm = System.getSecurityManager();
if (sm == null) {
return accessLoggerFinder().getLogger(name, module); return accessLoggerFinder().getLogger(name, module);
} else {
return AccessController.doPrivileged((PrivilegedAction<Logger>)
() -> {return accessLoggerFinder().getLogger(name, module);},
null, LOGGERFINDER_PERMISSION);
}
} }
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,12 +24,8 @@
*/ */
package jdk.internal.logger; package jdk.internal.logger;
import java.io.FilePermission;
import java.lang.System.Logger; import java.lang.System.Logger;
import java.lang.System.LoggerFinder; import java.lang.System.LoggerFinder;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.util.Iterator; import java.util.Iterator;
import java.util.Locale; import java.util.Locale;
import java.util.ServiceConfigurationError; import java.util.ServiceConfigurationError;
@ -37,9 +33,6 @@ import java.util.ServiceLoader;
import java.util.function.BooleanSupplier; import java.util.function.BooleanSupplier;
import jdk.internal.vm.annotation.Stable; import jdk.internal.vm.annotation.Stable;
import sun.security.util.SecurityConstants;
import sun.security.action.GetBooleanAction;
import sun.security.action.GetPropertyAction;
/** /**
* Helper class used to load the {@link java.lang.System.LoggerFinder}. * Helper class used to load the {@link java.lang.System.LoggerFinder}.
@ -47,13 +40,6 @@ import sun.security.action.GetPropertyAction;
public final class LoggerFinderLoader { public final class LoggerFinderLoader {
private static volatile System.LoggerFinder service; private static volatile System.LoggerFinder service;
private static final Object lock = new int[0]; private static final Object lock = new int[0];
static final Permission CLASSLOADER_PERMISSION =
SecurityConstants.GET_CLASSLOADER_PERMISSION;
static final Permission READ_PERMISSION =
new FilePermission("<<ALL FILES>>",
SecurityConstants.FILE_READ_ACTION);
public static final RuntimePermission LOGGERFINDER_PERMISSION =
new RuntimePermission("loggerFinder");
// This is used to control how the LoggerFinderLoader handles // This is used to control how the LoggerFinderLoader handles
// errors when instantiating the LoggerFinder provider. // errors when instantiating the LoggerFinder provider.
@ -63,7 +49,7 @@ public final class LoggerFinderLoader {
// DEBUG => Do not fail, use plain default (simple logger) implementation, // DEBUG => Do not fail, use plain default (simple logger) implementation,
// prints warning and exception stack trace on console. // prints warning and exception stack trace on console.
// QUIET => Do not fail and stay silent. // QUIET => Do not fail and stay silent.
private static enum ErrorPolicy { ERROR, WARNING, DEBUG, QUIET }; private static enum ErrorPolicy { ERROR, WARNING, DEBUG, QUIET }
// This class is static and cannot be instantiated. // This class is static and cannot be instantiated.
private LoggerFinderLoader() { private LoggerFinderLoader() {
@ -107,8 +93,7 @@ public final class LoggerFinderLoader {
// Get configuration error policy // Get configuration error policy
private static ErrorPolicy configurationErrorPolicy() { private static ErrorPolicy configurationErrorPolicy() {
String errorPolicy = String errorPolicy = System.getProperty("jdk.logger.finder.error");
GetPropertyAction.privilegedGetProperty("jdk.logger.finder.error");
if (errorPolicy == null || errorPolicy.isEmpty()) { if (errorPolicy == null || errorPolicy.isEmpty()) {
return ErrorPolicy.WARNING; return ErrorPolicy.WARNING;
} }
@ -122,25 +107,12 @@ public final class LoggerFinderLoader {
// Whether multiple provider should be considered as an error. // Whether multiple provider should be considered as an error.
// This is further submitted to the configuration error policy. // This is further submitted to the configuration error policy.
private static boolean ensureSingletonProvider() { private static boolean ensureSingletonProvider() {
return GetBooleanAction.privilegedGetProperty return Boolean.getBoolean("jdk.logger.finder.singleton");
("jdk.logger.finder.singleton");
} }
@SuppressWarnings("removal")
private static Iterator<System.LoggerFinder> findLoggerFinderProviders() { private static Iterator<System.LoggerFinder> findLoggerFinderProviders() {
final Iterator<System.LoggerFinder> iterator; return ServiceLoader.load(System.LoggerFinder.class,
if (System.getSecurityManager() == null) {
iterator = ServiceLoader.load(System.LoggerFinder.class,
ClassLoader.getSystemClassLoader()).iterator(); ClassLoader.getSystemClassLoader()).iterator();
} else {
final PrivilegedAction<Iterator<System.LoggerFinder>> pa =
() -> ServiceLoader.load(System.LoggerFinder.class,
ClassLoader.getSystemClassLoader()).iterator();
iterator = AccessController.doPrivileged(pa, null,
LOGGERFINDER_PERMISSION, CLASSLOADER_PERMISSION,
READ_PERMISSION);
}
return iterator;
} }
public static final class TemporaryLoggerFinder extends LoggerFinder { public static final class TemporaryLoggerFinder extends LoggerFinder {
@ -219,25 +191,10 @@ public final class LoggerFinderLoader {
return result; return result;
} }
@SuppressWarnings("removal")
private static System.LoggerFinder loadDefaultImplementation() { private static System.LoggerFinder loadDefaultImplementation() {
final SecurityManager sm = System.getSecurityManager(); final Iterator<DefaultLoggerFinder> iterator =
final Iterator<DefaultLoggerFinder> iterator;
if (sm == null) {
iterator = ServiceLoader.loadInstalled(DefaultLoggerFinder.class).iterator();
} else {
// We use limited do privileged here - the minimum set of
// permissions required to 'see' the META-INF/services resources
// seems to be CLASSLOADER_PERMISSION and READ_PERMISSION.
// Note that do privileged is required because
// otherwise the SecurityManager will prevent the ServiceLoader
// from seeing the installed provider.
PrivilegedAction<Iterator<DefaultLoggerFinder>> pa = () ->
ServiceLoader.loadInstalled(DefaultLoggerFinder.class).iterator(); ServiceLoader.loadInstalled(DefaultLoggerFinder.class).iterator();
iterator = AccessController.doPrivileged(pa, null,
LOGGERFINDER_PERMISSION, CLASSLOADER_PERMISSION,
READ_PERMISSION);
}
DefaultLoggerFinder result = null; DefaultLoggerFinder result = null;
try { try {
// Iterator iterates with the access control context stored // Iterator iterates with the access control context stored
@ -256,11 +213,6 @@ public final class LoggerFinderLoader {
} }
public static System.LoggerFinder getLoggerFinder() { public static System.LoggerFinder getLoggerFinder() {
@SuppressWarnings("removal")
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGERFINDER_PERMISSION);
}
return service(); return service();
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,8 +29,6 @@ import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.lang.StackWalker.StackFrame; import java.lang.StackWalker.StackFrame;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.Optional; import java.util.Optional;
import java.util.MissingResourceException; import java.util.MissingResourceException;
@ -39,7 +37,6 @@ import java.util.function.Function;
import java.lang.System.Logger; import java.lang.System.Logger;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.function.Supplier; import java.util.function.Supplier;
import sun.security.action.GetPropertyAction;
import sun.util.logging.PlatformLogger; import sun.util.logging.PlatformLogger;
import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration; import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration;
@ -56,8 +53,7 @@ public class SimpleConsoleLogger extends LoggerConfiguration
PlatformLogger.toPlatformLevel(DEFAULT_LEVEL); PlatformLogger.toPlatformLevel(DEFAULT_LEVEL);
static Level getDefaultLevel() { static Level getDefaultLevel() {
String levelName = GetPropertyAction String levelName = System.getProperty("jdk.system.logger.level", "INFO");
.privilegedGetProperty("jdk.system.logger.level", "INFO");
try { try {
return Level.valueOf(levelName); return Level.valueOf(levelName);
} catch (IllegalArgumentException iae) { } catch (IllegalArgumentException iae) {
@ -202,18 +198,9 @@ public class SimpleConsoleLogger extends LoggerConfiguration
/* /*
* CallerFinder is a stateful predicate. * CallerFinder is a stateful predicate.
*/ */
@SuppressWarnings("removal")
static final class CallerFinder implements Predicate<StackWalker.StackFrame> { static final class CallerFinder implements Predicate<StackWalker.StackFrame> {
private static final StackWalker WALKER; private static final StackWalker WALKER =
static { StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
final PrivilegedAction<StackWalker> action = new PrivilegedAction<>() {
@Override
public StackWalker run() {
return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
}
};
WALKER = AccessController.doPrivileged(action);
}
/** /**
* Returns StackFrame of the caller's frame. * Returns StackFrame of the caller's frame.
@ -439,8 +426,7 @@ public class SimpleConsoleLogger extends LoggerConfiguration
// Make it easier to wrap Logger... // Make it easier to wrap Logger...
private static final String[] skips; private static final String[] skips;
static { static {
String additionalPkgs = String additionalPkgs = System.getProperty("jdk.logger.packages");
GetPropertyAction.privilegedGetProperty("jdk.logger.packages");
skips = additionalPkgs == null ? new String[0] : additionalPkgs.split(","); skips = additionalPkgs == null ? new String[0] : additionalPkgs.split(",");
} }
@ -499,7 +485,7 @@ public class SimpleConsoleLogger extends LoggerConfiguration
// jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java // jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java
// to fail - because that test has a testcase which somehow references // to fail - because that test has a testcase which somehow references
// PlatformLogger and counts the number of generated lambda classes. // PlatformLogger and counts the number of generated lambda classes.
String format = GetPropertyAction.privilegedGetProperty(key); String format = System.getProperty(key);
if (format == null && defaultPropertyGetter != null) { if (format == null && defaultPropertyGetter != null) {
format = defaultPropertyGetter.apply(key); format = defaultPropertyGetter.apply(key);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -78,7 +78,7 @@ public class ConsoleHandler extends StreamHandler {
// configure with specific defaults for ConsoleHandler // configure with specific defaults for ConsoleHandler
super(Level.INFO, new SimpleFormatter(), null); super(Level.INFO, new SimpleFormatter(), null);
setOutputStreamPrivileged(System.err); setOutputStream(System.err);
} }
/** /**

View File

@ -43,8 +43,6 @@ import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException; import java.nio.file.NoSuchFileException;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
@ -267,7 +265,6 @@ public class FileHandler extends StreamHandler {
* @throws NullPointerException if pattern property is an empty String. * @throws NullPointerException if pattern property is an empty String.
*/ */
public FileHandler() throws IOException { public FileHandler() throws IOException {
checkPermission();
configure(); configure();
// pattern will have been set by configure. check that it's not // pattern will have been set by configure. check that it's not
// empty. // empty.
@ -293,10 +290,9 @@ public class FileHandler extends StreamHandler {
* @throws IllegalArgumentException if pattern is an empty string * @throws IllegalArgumentException if pattern is an empty string
*/ */
public FileHandler(String pattern) throws IOException { public FileHandler(String pattern) throws IOException {
if (pattern.length() < 1 ) { if (pattern.isEmpty()) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
checkPermission();
configure(); configure();
this.pattern = pattern; this.pattern = pattern;
this.limit = 0; this.limit = 0;
@ -323,10 +319,9 @@ public class FileHandler extends StreamHandler {
* @throws IllegalArgumentException if pattern is an empty string * @throws IllegalArgumentException if pattern is an empty string
*/ */
public FileHandler(String pattern, boolean append) throws IOException { public FileHandler(String pattern, boolean append) throws IOException {
if (pattern.length() < 1 ) { if (pattern.isEmpty()) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
checkPermission();
configure(); configure();
this.pattern = pattern; this.pattern = pattern;
this.limit = 0; this.limit = 0;
@ -357,10 +352,9 @@ public class FileHandler extends StreamHandler {
* @throws IllegalArgumentException if pattern is an empty string * @throws IllegalArgumentException if pattern is an empty string
*/ */
public FileHandler(String pattern, int limit, int count) throws IOException { public FileHandler(String pattern, int limit, int count) throws IOException {
if (limit < 0 || count < 1 || pattern.length() < 1) { if (limit < 0 || count < 1 || pattern.isEmpty()) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
checkPermission();
configure(); configure();
this.pattern = pattern; this.pattern = pattern;
this.limit = limit; this.limit = limit;
@ -425,10 +419,9 @@ public class FileHandler extends StreamHandler {
*/ */
public FileHandler(String pattern, long limit, int count, boolean append) public FileHandler(String pattern, long limit, int count, boolean append)
throws IOException { throws IOException {
if (limit < 0 || count < 1 || pattern.length() < 1) { if (limit < 0 || count < 1 || pattern.isEmpty()) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
checkPermission();
configure(); configure();
this.pattern = pattern; this.pattern = pattern;
this.limit = limit; this.limit = limit;
@ -451,7 +444,6 @@ public class FileHandler extends StreamHandler {
*/ */
private void openFiles() throws IOException { private void openFiles() throws IOException {
LogManager manager = LogManager.getLogManager(); LogManager manager = LogManager.getLogManager();
manager.checkPermission();
if (count < 1) { if (count < 1) {
throw new IllegalArgumentException("file count = " + count); throw new IllegalArgumentException("file count = " + count);
} }
@ -481,7 +473,7 @@ public class FileHandler extends StreamHandler {
// Now try to lock that filename. // Now try to lock that filename.
// Because some systems (e.g., Solaris) can only do file locks // Because some systems (e.g., Solaris) can only do file locks
// between processes (and not within a process), we first check // between processes (and not within a process), we first check
// if we ourself already have the file locked. // if we ourselves already have the file locked.
synchronized(locks) { synchronized(locks) {
if (locks.contains(lockFileName)) { if (locks.contains(lockFileName)) {
// We already own this lock, for a different FileHandler // We already own this lock, for a different FileHandler
@ -616,7 +608,7 @@ public class FileHandler extends StreamHandler {
* @param generation the generation number to distinguish rotated logs * @param generation the generation number to distinguish rotated logs
* @param unique a unique number to resolve conflicts * @param unique a unique number to resolve conflicts
* @return the generated File * @return the generated File
* @throws IOException * @throws IOException if an I/O error occurs
*/ */
private File generate(String pattern, int generation, int unique) private File generate(String pattern, int generation, int unique)
throws IOException throws IOException
@ -696,7 +688,7 @@ public class FileHandler extends StreamHandler {
if (unique > 0 && !sawu) { if (unique > 0 && !sawu) {
word = word.append('.').append(unique); word = word.append('.').append(unique);
} }
if (word.length() > 0) { if (!word.isEmpty()) {
String n = word.toString(); String n = word.toString();
Path p = prev == null ? Paths.get(n) : prev.resolveSibling(n); Path p = prev == null ? Paths.get(n) : prev.resolveSibling(n);
result = result == null ? p : result.resolve(p); result = result == null ? p : result.resolve(p);
@ -714,21 +706,7 @@ public class FileHandler extends StreamHandler {
/** /**
* Rotate the set of output files * Rotate the set of output files
*/ */
private void rotate() { private synchronized void rotate() {
if (tryUseLock()) {
try {
rotate0();
} finally {
unlock();
}
} else {
synchronized (this) {
rotate0();
}
}
}
private void rotate0() {
Level oldLevel = getLevel(); Level oldLevel = getLevel();
setLevel(Level.OFF); setLevel(Level.OFF);
@ -761,40 +739,14 @@ public class FileHandler extends StreamHandler {
* silently ignored and is not published * silently ignored and is not published
*/ */
@Override @Override
public void publish(LogRecord record) { public synchronized void publish(LogRecord record) {
if (tryUseLock()) {
try {
publish0(record);
} finally {
unlock();
}
} else {
synchronized (this) {
publish0(record);
}
}
}
@SuppressWarnings("removal")
private void publish0(LogRecord record) {
if (!isLoggable(record)) { if (!isLoggable(record)) {
return; return;
} }
super.publish(record); super.publish(record);
flush(); flush();
if (limit > 0 && (meter.written >= limit || meter.written < 0)) { if (limit > 0 && (meter.written >= limit || meter.written < 0)) {
// We performed access checks in the "init" method to make sure
// we are only initialized from trusted code. So we assume
// it is OK to write the target files, even if we are
// currently being called from untrusted code.
// So it is safe to raise privilege here.
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
rotate(); rotate();
return null;
}
});
} }
} }
@ -802,21 +754,7 @@ public class FileHandler extends StreamHandler {
* Close all the files. * Close all the files.
*/ */
@Override @Override
public void close() { public synchronized void close() {
if (tryUseLock()) {
try {
close0();
} finally {
unlock();
}
} else {
synchronized (this) {
close0();
}
}
}
private void close0() throws SecurityException {
super.close(); super.close();
// Unlock any lock file. // Unlock any lock file.
if (lockFileName == null) { if (lockFileName == null) {

View File

@ -28,9 +28,6 @@ package java.util.logging;
import java.util.Objects; import java.util.Objects;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.concurrent.locks.ReentrantLock;
/** /**
* A {@code Handler} object takes log messages from a {@code Logger} and * A {@code Handler} object takes log messages from a {@code Logger} and
@ -52,6 +49,8 @@ import java.util.concurrent.locks.ReentrantLock;
public abstract class Handler { public abstract class Handler {
private static final int offValue = Level.OFF.intValue(); private static final int offValue = Level.OFF.intValue();
// ensure log manager is initialized
private final LogManager manager = LogManager.getLogManager(); private final LogManager manager = LogManager.getLogManager();
// We're using volatile here to avoid synchronizing getters, which // We're using volatile here to avoid synchronizing getters, which
@ -66,7 +65,6 @@ public abstract class Handler {
private volatile Level logLevel = Level.ALL; private volatile Level logLevel = Level.ALL;
private volatile ErrorManager errorManager = new ErrorManager(); private volatile ErrorManager errorManager = new ErrorManager();
private volatile String encoding; private volatile String encoding;
private final ReentrantLock lock;
/** /**
* Default constructor. The resulting {@code Handler} has a log * Default constructor. The resulting {@code Handler} has a log
@ -74,19 +72,7 @@ public abstract class Handler {
* {@code Filter}. A default {@code ErrorManager} instance is installed * {@code Filter}. A default {@code ErrorManager} instance is installed
* as the {@code ErrorManager}. * as the {@code ErrorManager}.
*/ */
protected Handler() { protected Handler() { }
lock = initLocking();
}
private ReentrantLock initLocking() {
Class<?> clazz = this.getClass();
ClassLoader loader = clazz.getClassLoader();
if (loader != null && loader != ClassLoader.getPlatformClassLoader()) {
return null;
} else {
return new ReentrantLock();
}
}
/** /**
* Package-private constructor for chaining from subclass constructors * Package-private constructor for chaining from subclass constructors
@ -100,7 +86,6 @@ public abstract class Handler {
* nor found in LogManager configuration properties * nor found in LogManager configuration properties
* @param specifiedFormatter if not null, this is the formatter to configure * @param specifiedFormatter if not null, this is the formatter to configure
*/ */
@SuppressWarnings("removal")
Handler(Level defaultLevel, Formatter defaultFormatter, Handler(Level defaultLevel, Formatter defaultFormatter,
Formatter specifiedFormatter) { Formatter specifiedFormatter) {
this(); this();
@ -115,9 +100,6 @@ public abstract class Handler {
: specifiedFormatter; : specifiedFormatter;
final String encoding = manager.getStringProperty(cname + ".encoding", null); final String encoding = manager.getStringProperty(cname + ".encoding", null);
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
setLevel(level); setLevel(level);
setFilter(filter); setFilter(filter);
setFormatter(formatter); setFormatter(formatter);
@ -131,18 +113,6 @@ public abstract class Handler {
// assert false; // assert false;
} }
} }
return null;
}
}, null, LogManager.controlPermission);
}
boolean tryUseLock() {
if (lock == null) return false;
lock.lock();
return true;
}
void unlock() {
lock.unlock();
} }
/** /**
@ -183,22 +153,7 @@ public abstract class Handler {
* *
* @param newFormatter the {@code Formatter} to use (may not be null) * @param newFormatter the {@code Formatter} to use (may not be null)
*/ */
public void setFormatter(Formatter newFormatter) { public synchronized void setFormatter(Formatter newFormatter) {
if (tryUseLock()) {
try {
setFormatter0(newFormatter);
} finally {
unlock();
}
} else {
synchronized (this) {
setFormatter0(newFormatter);
}
}
}
private void setFormatter0(Formatter newFormatter) throws SecurityException {
checkPermission();
formatter = Objects.requireNonNull(newFormatter); formatter = Objects.requireNonNull(newFormatter);
} }
@ -221,24 +176,8 @@ public abstract class Handler {
* @throws UnsupportedEncodingException if the named encoding is * @throws UnsupportedEncodingException if the named encoding is
* not supported. * not supported.
*/ */
public void setEncoding(String encoding) public synchronized void setEncoding(String encoding)
throws java.io.UnsupportedEncodingException { throws java.io.UnsupportedEncodingException {
if (tryUseLock()) {
try {
setEncoding0(encoding);
} finally {
unlock();
}
} else {
synchronized (this) {
setEncoding0(encoding);
}
}
}
private void setEncoding0(String encoding)
throws SecurityException, java.io.UnsupportedEncodingException {
checkPermission();
if (encoding != null) { if (encoding != null) {
try { try {
if(!java.nio.charset.Charset.isSupported(encoding)) { if(!java.nio.charset.Charset.isSupported(encoding)) {
@ -270,22 +209,7 @@ public abstract class Handler {
* *
* @param newFilter a {@code Filter} object (may be null) * @param newFilter a {@code Filter} object (may be null)
*/ */
public void setFilter(Filter newFilter) { public synchronized void setFilter(Filter newFilter) {
if (tryUseLock()) {
try {
setFilter0(newFilter);
} finally {
unlock();
}
} else {
synchronized (this) {
setFilter0(newFilter);
}
}
}
private void setFilter0(Filter newFilter) throws SecurityException {
checkPermission();
filter = newFilter; filter = newFilter;
} }
@ -306,22 +230,7 @@ public abstract class Handler {
* *
* @param em the new ErrorManager * @param em the new ErrorManager
*/ */
public void setErrorManager(ErrorManager em) { public synchronized void setErrorManager(ErrorManager em) {
if (tryUseLock()) {
try {
setErrorManager0(em);
} finally {
unlock();
}
} else {
synchronized (this) {
setErrorManager0(em);
}
}
}
private void setErrorManager0(ErrorManager em) {
checkPermission();
if (em == null) { if (em == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
@ -334,7 +243,6 @@ public abstract class Handler {
* @return the ErrorManager for this Handler * @return the ErrorManager for this Handler
*/ */
public ErrorManager getErrorManager() { public ErrorManager getErrorManager() {
checkPermission();
return errorManager; return errorManager;
} }
@ -366,25 +274,10 @@ public abstract class Handler {
* *
* @param newLevel the new value for the log level * @param newLevel the new value for the log level
*/ */
public void setLevel(Level newLevel) { public synchronized void setLevel(Level newLevel) {
if (tryUseLock()) {
try {
setLevel0(newLevel);
} finally {
unlock();
}
} else {
synchronized (this) {
setLevel0(newLevel);
}
}
}
private void setLevel0(Level newLevel) throws SecurityException {
if (newLevel == null) { if (newLevel == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
checkPermission();
logLevel = newLevel; logLevel = newLevel;
} }
@ -426,10 +319,4 @@ public abstract class Handler {
return filter.isLoggable(record); return filter.isLoggable(record);
} }
// Package-private support method for security checks.
// We check that the caller has appropriate security privileges
// to update Handler state and if not throw a SecurityException.
void checkPermission() throws SecurityException {
manager.checkPermission();
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,8 +29,6 @@ import java.io.Serial;
import java.lang.ref.Reference; import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue; import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -620,9 +618,7 @@ public class Level implements java.io.Serializable {
} }
private static void registerWithClassLoader(Level customLevel) { private static void registerWithClassLoader(Level customLevel) {
PrivilegedAction<ClassLoader> pa = customLevel.getClass()::getClassLoader; final ClassLoader cl = customLevel.getClass().getClassLoader();
@SuppressWarnings("removal")
final ClassLoader cl = AccessController.doPrivileged(pa);
CUSTOM_LEVEL_CLV.computeIfAbsent(cl, (c, v) -> new ArrayList<>()) CUSTOM_LEVEL_CLV.computeIfAbsent(cl, (c, v) -> new ArrayList<>())
.add(customLevel); .add(customLevel);
} }

View File

@ -27,7 +27,6 @@ package java.util.logging;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import java.security.*;
import java.lang.ref.ReferenceQueue; import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -39,8 +38,6 @@ import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import jdk.internal.access.JavaAWTAccess;
import jdk.internal.access.SharedSecrets;
import sun.util.logging.internal.LoggingProviderImpl; import sun.util.logging.internal.LoggingProviderImpl;
import static jdk.internal.logger.DefaultLoggerFinder.isSystem; import static jdk.internal.logger.DefaultLoggerFinder.isSystem;
@ -218,11 +215,9 @@ public class LogManager {
Collections.synchronizedMap(new IdentityHashMap<>()); Collections.synchronizedMap(new IdentityHashMap<>());
// The global LogManager object // The global LogManager object
@SuppressWarnings("removal") private static final LogManager manager = initLogManager();
private static final LogManager manager = AccessController.doPrivileged(
new PrivilegedAction<LogManager>() { private static LogManager initLogManager() {
@Override
public LogManager run() {
LogManager mgr = null; LogManager mgr = null;
String cname = null; String cname = null;
try { try {
@ -248,9 +243,8 @@ public class LogManager {
mgr = new LogManager(); mgr = new LogManager();
} }
return mgr; return mgr;
} }
});
// This private class is used as a shutdown hook. // This private class is used as a shutdown hook.
// It does a "reset" to close all open handlers. // It does a "reset" to close all open handlers.
@ -290,11 +284,6 @@ public class LogManager {
* retrieved by calling LogManager.getLogManager. * retrieved by calling LogManager.getLogManager.
*/ */
protected LogManager() { protected LogManager() {
this(checkSubclassPermissions());
}
private LogManager(Void checked) {
// Add a shutdown hook to close the global handlers. // Add a shutdown hook to close the global handlers.
try { try {
Runtime.getRuntime().addShutdownHook(new Cleaner()); Runtime.getRuntime().addShutdownHook(new Cleaner());
@ -304,20 +293,6 @@ public class LogManager {
} }
} }
private static Void checkSubclassPermissions() {
@SuppressWarnings("removal")
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// These permission will be checked in the LogManager constructor,
// in order to register the Cleaner() thread as a shutdown hook.
// Check them here to avoid the penalty of constructing the object
// etc...
sm.checkPermission(new RuntimePermission("shutdownHooks"));
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
return null;
}
/** /**
* Lazy initialization: if this instance of manager is the global * Lazy initialization: if this instance of manager is the global
* manager then this method will read the initial configuration and * manager then this method will read the initial configuration and
@ -380,9 +355,6 @@ public class LogManager {
// We use initializedCalled to break the recursion. // We use initializedCalled to break the recursion.
initializedCalled = true; initializedCalled = true;
try { try {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
assert rootLogger == null; assert rootLogger == null;
assert initializedCalled && !initializationDone; assert initializedCalled && !initializationDone;
@ -405,15 +377,11 @@ public class LogManager {
// Adding the global Logger. // Adding the global Logger.
// Do not call Logger.getGlobal() here as this might trigger // Do not call Logger.getGlobal() here as this might trigger
// subtle inter-dependency issues. // subtle inter-dependency issues.
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation") final Logger global = Logger.global;
final Logger global = Logger.global;
// Make sure the global logger will be registered in the // Make sure the global logger will be registered in the
// global manager // global manager
owner.addLogger(global); owner.addLogger(global);
return null;
}
});
} finally { } finally {
initializationDone = true; initializationDone = true;
} }
@ -461,29 +429,6 @@ public class LogManager {
// Loggers are isolated from each AppContext. // Loggers are isolated from each AppContext.
private LoggerContext getUserContext() { private LoggerContext getUserContext() {
LoggerContext context = null; LoggerContext context = null;
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
JavaAWTAccess javaAwtAccess = SharedSecrets.getJavaAWTAccess();
if (sm != null && javaAwtAccess != null) {
// for each applet, it has its own LoggerContext isolated from others
final Object ecx = javaAwtAccess.getAppletContext();
if (ecx != null) {
synchronized (javaAwtAccess) {
// find the AppContext of the applet code
// will be null if we are in the main app context.
if (contextsMap == null) {
contextsMap = new WeakHashMap<>();
}
context = contextsMap.get(ecx);
if (context == null) {
// Create a new LoggerContext for the applet.
context = new LoggerContext();
contextsMap.put(ecx, context);
}
}
}
}
// for standalone app, return userContext // for standalone app, return userContext
return context != null ? context : userContext; return context != null ? context : userContext;
} }
@ -552,7 +497,6 @@ public class LogManager {
return demandSystemLogger(name, resourceBundleName, module); return demandSystemLogger(name, resourceBundleName, module);
} }
@SuppressWarnings("removal")
Logger demandSystemLogger(String name, String resourceBundleName, Module module) { Logger demandSystemLogger(String name, String resourceBundleName, Module module) {
// Add a system logger in the system context's namespace // Add a system logger in the system context's namespace
final Logger sysLogger = getSystemContext() final Logger sysLogger = getSystemContext()
@ -578,14 +522,7 @@ public class LogManager {
// LogManager will set the sysLogger's handlers via LogManager.addLogger method. // LogManager will set the sysLogger's handlers via LogManager.addLogger method.
if (logger != sysLogger) { if (logger != sysLogger) {
// if logger already exists we merge the two logger configurations. // if logger already exists we merge the two logger configurations.
final Logger l = logger; logger.mergeWithSystemLogger(sysLogger);
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
l.mergeWithSystemLogger(sysLogger);
return null;
}
});
} }
return sysLogger; return sysLogger;
} }
@ -801,7 +738,7 @@ public class LogManager {
// the logger's level is already initialized // the logger's level is already initialized
Level level = owner.getLevelProperty(name + ".level", null); Level level = owner.getLevelProperty(name + ".level", null);
if (level != null && !logger.isLevelInitialized()) { if (level != null && !logger.isLevelInitialized()) {
doSetLevel(logger, level); logger.setLevel(level);
} }
// instantiation of the handler is done in the LogManager.addLogger // instantiation of the handler is done in the LogManager.addLogger
@ -826,7 +763,7 @@ public class LogManager {
} }
if (parent != null) { if (parent != null) {
doSetParent(logger, parent); logger.setParent(parent);
} }
// Walk over the children and tell them we are their new parent. // Walk over the children and tell them we are their new parent.
node.walkAndSetParent(logger); node.walkAndSetParent(logger);
@ -855,22 +792,15 @@ public class LogManager {
// If logger.getUseParentHandlers() returns 'true' and any of the logger's // If logger.getUseParentHandlers() returns 'true' and any of the logger's
// parents have levels or handlers defined, make sure they are instantiated. // parents have levels or handlers defined, make sure they are instantiated.
@SuppressWarnings("removal")
private void processParentHandlers(final Logger logger, final String name, private void processParentHandlers(final Logger logger, final String name,
Predicate<Logger> visited) { Predicate<Logger> visited) {
final LogManager owner = getOwner(); final LogManager owner = getOwner();
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
if (logger != owner.rootLogger) { if (logger != owner.rootLogger) {
boolean useParent = owner.getBooleanProperty(name + ".useParentHandlers", true); boolean useParent = owner.getBooleanProperty(name + ".useParentHandlers", true);
if (!useParent) { if (!useParent) {
logger.setUseParentHandlers(false); logger.setUseParentHandlers(false);
} }
} }
return null;
}
});
int ix = 1; int ix = 1;
for (;;) { for (;;) {
@ -898,7 +828,7 @@ public class LogManager {
return root; return root;
} }
LogNode node = root; LogNode node = root;
while (name.length() > 0) { while (!name.isEmpty()) {
int ix = name.indexOf('.'); int ix = name.indexOf('.');
String head; String head;
if (ix > 0) { if (ix > 0) {
@ -961,21 +891,10 @@ public class LogManager {
} }
// Add new per logger handlers. // Add new per logger handlers.
// We need to raise privilege here. All our decisions will
// be made based on the logging configuration, which can
// only be modified by trusted code.
@SuppressWarnings("removal")
private void loadLoggerHandlers(final Logger logger, final String name, private void loadLoggerHandlers(final Logger logger, final String name,
final String handlersPropertyName) final String handlersPropertyName) {
{
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
setLoggerHandlers(logger, name, handlersPropertyName, setLoggerHandlers(logger, name, handlersPropertyName,
createLoggerHandlers(name, handlersPropertyName)); createLoggerHandlers(name, handlersPropertyName));
return null;
}
});
} }
private void setLoggerHandlers(final Logger logger, final String name, private void setLoggerHandlers(final Logger logger, final String name,
@ -1228,45 +1147,6 @@ public class LogManager {
&& configurationLock.isHeldByCurrentThread(); && configurationLock.isHeldByCurrentThread();
} }
// Private method to set a level on a logger.
// If necessary, we raise privilege before doing the call.
@SuppressWarnings("removal")
private static void doSetLevel(final Logger logger, final Level level) {
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
// There is no security manager, so things are easy.
logger.setLevel(level);
return;
}
// There is a security manager. Raise privilege before
// calling setLevel.
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
logger.setLevel(level);
return null;
}});
}
// Private method to set a parent on a logger.
// If necessary, we raise privilege before doing the setParent call.
@SuppressWarnings("removal")
private static void doSetParent(final Logger logger, final Logger parent) {
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
// There is no security manager, so things are easy.
logger.setParent(parent);
return;
}
// There is a security manager. Raise privilege before
// calling setParent.
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
logger.setParent(parent);
return null;
}});
}
/** /**
* Method to find a named logger. * Method to find a named logger.
@ -1350,7 +1230,6 @@ public class LogManager {
* @throws IOException if there are IO problems reading the configuration. * @throws IOException if there are IO problems reading the configuration.
*/ */
public void readConfiguration() throws IOException { public void readConfiguration() throws IOException {
checkPermission();
// if a configuration class is specified, load it and use it. // if a configuration class is specified, load it and use it.
String cname = System.getProperty("java.util.logging.config.class"); String cname = System.getProperty("java.util.logging.config.class");
@ -1383,7 +1262,7 @@ public class LogManager {
} }
} }
String getConfigurationFileName() throws IOException { String getConfigurationFileName() {
String fname = System.getProperty("java.util.logging.config.file"); String fname = System.getProperty("java.util.logging.config.file");
if (fname == null) { if (fname == null) {
fname = System.getProperty("java.home"); fname = System.getProperty("java.home");
@ -1413,7 +1292,6 @@ public class LogManager {
*/ */
public void reset() { public void reset() {
checkPermission();
List<CloseOnReset> persistent; List<CloseOnReset> persistent;
@ -1518,7 +1396,7 @@ public class LogManager {
String word = hands.substring(ix, end); String word = hands.substring(ix, end);
ix = end+1; ix = end+1;
word = word.trim(); word = word.trim();
if (word.length() == 0) { if (word.isEmpty()) {
continue; continue;
} }
result.add(word); result.add(word);
@ -1553,7 +1431,6 @@ public class LogManager {
* {@linkplain java.util.Properties properties file} format. * {@linkplain java.util.Properties properties file} format.
*/ */
public void readConfiguration(InputStream ins) throws IOException { public void readConfiguration(InputStream ins) throws IOException {
checkPermission();
// We don't want reset() and readConfiguration() to run // We don't want reset() and readConfiguration() to run
// in parallel. // in parallel.
@ -1857,7 +1734,6 @@ public class LogManager {
*/ */
public void updateConfiguration(Function<String, BiFunction<String,String,String>> mapper) public void updateConfiguration(Function<String, BiFunction<String,String,String>> mapper)
throws IOException { throws IOException {
checkPermission();
ensureLogManagerInitialized(); ensureLogManagerInitialized();
drainLoggerRefQueueBounded(); drainLoggerRefQueueBounded();
@ -2054,7 +1930,6 @@ public class LogManager {
public void updateConfiguration(InputStream ins, public void updateConfiguration(InputStream ins,
Function<String, BiFunction<String,String,String>> mapper) Function<String, BiFunction<String,String,String>> mapper)
throws IOException { throws IOException {
checkPermission();
ensureLogManagerInitialized(); ensureLogManagerInitialized();
drainLoggerRefQueueBounded(); drainLoggerRefQueueBounded();
@ -2410,16 +2285,6 @@ public class LogManager {
} }
} }
static final Permission controlPermission =
new LoggingPermission("control", null);
void checkPermission() {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(controlPermission);
}
/** /**
* Does nothing. * Does nothing.
* *
@ -2456,7 +2321,7 @@ public class LogManager {
if (logger == null) { if (logger == null) {
node.walkAndSetParent(parent); node.walkAndSetParent(parent);
} else { } else {
doSetParent(logger, parent); logger.setParent(parent);
} }
} }
} }
@ -2590,19 +2455,8 @@ public class LogManager {
*/ */
public LogManager addConfigurationListener(Runnable listener) { public LogManager addConfigurationListener(Runnable listener) {
final Runnable r = Objects.requireNonNull(listener); final Runnable r = Objects.requireNonNull(listener);
checkPermission();
@SuppressWarnings("removal")
final SecurityManager sm = System.getSecurityManager();
@SuppressWarnings("removal")
final AccessControlContext acc =
sm == null ? null : AccessController.getContext();
final PrivilegedAction<Void> pa =
acc == null ? null : () -> { r.run() ; return null; };
@SuppressWarnings("removal")
final Runnable pr =
acc == null ? r : () -> AccessController.doPrivileged(pa, acc);
// Will do nothing if already registered. // Will do nothing if already registered.
listeners.putIfAbsent(r, pr); listeners.putIfAbsent(r, r);
return this; return this;
} }
@ -2618,7 +2472,6 @@ public class LogManager {
*/ */
public void removeConfigurationListener(Runnable listener) { public void removeConfigurationListener(Runnable listener) {
final Runnable key = Objects.requireNonNull(listener); final Runnable key = Objects.requireNonNull(listener);
checkPermission();
listeners.remove(key); listeners.remove(key);
} }
@ -2652,8 +2505,7 @@ public class LogManager {
* behalf of system and application classes. * behalf of system and application classes.
*/ */
private static final class LoggingProviderAccess private static final class LoggingProviderAccess
implements LoggingProviderImpl.LogManagerAccess, implements LoggingProviderImpl.LogManagerAccess {
PrivilegedAction<Void> {
private LoggingProviderAccess() { private LoggingProviderAccess() {
} }
@ -2684,11 +2536,6 @@ public class LogManager {
} }
Objects.requireNonNull(name); Objects.requireNonNull(name);
Objects.requireNonNull(module); Objects.requireNonNull(module);
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(controlPermission);
}
if (isSystem(module)) { if (isSystem(module)) {
return manager.demandSystemLogger(name, return manager.demandSystemLogger(name,
Logger.SYSTEM_LOGGER_RB_NAME, module); Logger.SYSTEM_LOGGER_RB_NAME, module);
@ -2697,23 +2544,15 @@ public class LogManager {
} }
} }
@Override private void init() {
public Void run() {
LoggingProviderImpl.setLogManagerAccess(INSTANCE); LoggingProviderImpl.setLogManagerAccess(INSTANCE);
return null;
} }
static final LoggingProviderAccess INSTANCE = new LoggingProviderAccess(); static final LoggingProviderAccess INSTANCE = new LoggingProviderAccess();
} }
static { static {
initStatic(); LoggingProviderAccess.INSTANCE.init();
}
@SuppressWarnings("removal")
private static void initStatic() {
AccessController.doPrivileged(LoggingProviderAccess.INSTANCE, null,
controlPermission);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -28,8 +28,6 @@ import java.time.Instant;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.io.*; import java.io.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.time.Clock; import java.time.Clock;
import java.util.function.Predicate; import java.util.function.Predicate;
import static jdk.internal.logger.SurrogateLogger.isFilteredFrame; import static jdk.internal.logger.SurrogateLogger.isFilteredFrame;
@ -767,14 +765,10 @@ public class LogRecord implements java.io.Serializable {
/* /*
* CallerFinder is a stateful predicate. * CallerFinder is a stateful predicate.
*/ */
@SuppressWarnings("removal")
static final class CallerFinder implements Predicate<StackWalker.StackFrame> { static final class CallerFinder implements Predicate<StackWalker.StackFrame> {
private static final StackWalker WALKER; private static final StackWalker WALKER =
static { StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
final PrivilegedAction<StackWalker> action =
() -> StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
WALKER = AccessController.doPrivileged(action);
}
/** /**
* Returns StackFrame of the caller's frame. * Returns StackFrame of the caller's frame.

View File

@ -26,8 +26,6 @@
package java.util.logging; package java.util.logging;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.Locale; import java.util.Locale;
@ -579,7 +577,7 @@ public class Logger {
// should never come here // should never come here
throw new InternalError("invalid logger merge"); throw new InternalError("invalid logger merge");
} }
checkPermission(); ensureManagerInitialized();
final ConfigurationData cfg = config; final ConfigurationData cfg = config;
if (cfg != system.config) { if (cfg != system.config) {
config = cfg.merge(system); config = cfg.merge(system);
@ -614,13 +612,12 @@ public class Logger {
this.manager = manager; this.manager = manager;
} }
private void checkPermission() throws SecurityException { private void ensureManagerInitialized() {
if (!anonymous) { if (!anonymous) {
if (manager == null) { if (manager == null) {
// Complete initialization of the global Logger. // Complete initialization of the global Logger.
manager = LogManager.getLogManager(); manager = LogManager.getLogManager();
} }
manager.checkPermission();
} }
} }
@ -633,17 +630,8 @@ public class Logger {
// These system loggers only set the resource bundle to the given // These system loggers only set the resource bundle to the given
// resource bundle name (rather than the default system resource bundle). // resource bundle name (rather than the default system resource bundle).
private static class SystemLoggerHelper { private static class SystemLoggerHelper {
static boolean disableCallerCheck = getBooleanProperty("sun.util.logging.disableCallerCheck"); static boolean disableCallerCheck =
private static boolean getBooleanProperty(final String key) { Boolean.getBoolean("sun.util.logging.disableCallerCheck");
@SuppressWarnings("removal")
String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
@Override
public String run() {
return System.getProperty(key);
}
});
return Boolean.parseBoolean(s);
}
} }
private static Logger demandLogger(String name, String resourceBundleName, Class<?> caller) { private static Logger demandLogger(String name, String resourceBundleName, Class<?> caller) {
@ -930,7 +918,7 @@ public class Logger {
* @param newFilter a filter object (may be null) * @param newFilter a filter object (may be null)
*/ */
public void setFilter(Filter newFilter) { public void setFilter(Filter newFilter) {
checkPermission(); ensureManagerInitialized();
config.setFilter(newFilter); config.setFilter(newFilter);
} }
@ -1990,7 +1978,7 @@ public class Logger {
* @param newLevel the new value for the log level (may be null) * @param newLevel the new value for the log level (may be null)
*/ */
public void setLevel(Level newLevel) { public void setLevel(Level newLevel) {
checkPermission(); ensureManagerInitialized();
synchronized (treeLock) { synchronized (treeLock) {
config.setLevelObject(newLevel); config.setLevelObject(newLevel);
updateEffectiveLevel(); updateEffectiveLevel();
@ -2047,7 +2035,7 @@ public class Logger {
*/ */
public void addHandler(Handler handler) { public void addHandler(Handler handler) {
Objects.requireNonNull(handler); Objects.requireNonNull(handler);
checkPermission(); ensureManagerInitialized();
config.addHandler(handler); config.addHandler(handler);
} }
@ -2059,7 +2047,7 @@ public class Logger {
* @param handler a logging Handler * @param handler a logging Handler
*/ */
public void removeHandler(Handler handler) { public void removeHandler(Handler handler) {
checkPermission(); ensureManagerInitialized();
if (handler == null) { if (handler == null) {
return; return;
} }
@ -2091,7 +2079,7 @@ public class Logger {
* logger's parent. * logger's parent.
*/ */
public void setUseParentHandlers(boolean useParentHandlers) { public void setUseParentHandlers(boolean useParentHandlers) {
checkPermission(); ensureManagerInitialized();
config.setUseParentHandlers(useParentHandlers); config.setUseParentHandlers(useParentHandlers);
} }
@ -2187,11 +2175,8 @@ public class Logger {
try { try {
// We are called by an unnamed module: try with the // We are called by an unnamed module: try with the
// unnamed module class loader: // unnamed module class loader:
PrivilegedAction<ClassLoader> getModuleClassLoader = ClassLoader moduleCL = callerModule.getClassLoader();
() -> callerModule.getClassLoader();
@SuppressWarnings("removal")
ClassLoader moduleCL =
AccessController.doPrivileged(getModuleClassLoader);
// moduleCL can be null if the logger is created by a class // moduleCL can be null if the logger is created by a class
// appended to the bootclasspath. // appended to the bootclasspath.
// If moduleCL is null we would use cl, but we already tried // If moduleCL is null we would use cl, but we already tried
@ -2267,7 +2252,7 @@ public class Logger {
setCallerModuleRef(callerModule); setCallerModuleRef(callerModule);
if (isSystemLogger && (callerModule != null && !isSystem(callerModule))) { if (isSystemLogger && (callerModule != null && !isSystem(callerModule))) {
checkPermission(); ensureManagerInitialized();
} }
if (name.equals(SYSTEM_LOGGER_RB_NAME)) { if (name.equals(SYSTEM_LOGGER_RB_NAME)) {
@ -2300,7 +2285,7 @@ public class Logger {
* @since 1.8 * @since 1.8
*/ */
public void setResourceBundle(ResourceBundle bundle) { public void setResourceBundle(ResourceBundle bundle) {
checkPermission(); ensureManagerInitialized();
// Will throw NPE if bundle is null. // Will throw NPE if bundle is null.
final String baseName = bundle.getBaseBundleName(); final String baseName = bundle.getBaseBundleName();
@ -2359,11 +2344,7 @@ public class Logger {
throw new NullPointerException(); throw new NullPointerException();
} }
// check permission for all loggers, including anonymous loggers ensureManagerInitialized();
if (manager == null) {
manager = LogManager.getLogManager();
}
manager.checkPermission();
doSetParent(parent); doSetParent(parent);
} }

View File

@ -26,7 +26,6 @@
package java.util.logging; package java.util.logging;
import java.security.*;
/** /**
* This class is for logging permissions. Currently there is only one * This class is for logging permissions. Currently there is only one

View File

@ -178,21 +178,7 @@ public class MemoryHandler extends Handler {
* silently ignored and is not published * silently ignored and is not published
*/ */
@Override @Override
public void publish(LogRecord record) { public synchronized void publish(LogRecord record) {
if (tryUseLock()) {
try {
publish0(record);
} finally {
unlock();
}
} else {
synchronized (this) {
publish0(record);
}
}
}
private void publish0(LogRecord record) {
if (!isLoggable(record)) { if (!isLoggable(record)) {
return; return;
} }
@ -214,21 +200,7 @@ public class MemoryHandler extends Handler {
* <p> * <p>
* The buffer is then cleared. * The buffer is then cleared.
*/ */
public void push() { public synchronized void push() {
if (tryUseLock()) {
try {
push0();
} finally {
unlock();
}
} else {
synchronized (this) {
push0();
}
}
}
private void push0() {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
int ix = (start+i)%buffer.length; int ix = (start+i)%buffer.length;
LogRecord record = buffer[ix]; LogRecord record = buffer[ix];
@ -267,25 +239,10 @@ public class MemoryHandler extends Handler {
* *
* @param newLevel the new value of the {@code pushLevel} * @param newLevel the new value of the {@code pushLevel}
*/ */
public void setPushLevel(Level newLevel) { public synchronized void setPushLevel(Level newLevel) {
if (tryUseLock()) {
try {
setPushLevel0(newLevel);
} finally {
unlock();
}
} else {
synchronized (this) {
setPushLevel0(newLevel);
}
}
}
private void setPushLevel0(Level newLevel) throws SecurityException {
if (newLevel == null) { if (newLevel == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
checkPermission();
pushLevel = newLevel; pushLevel = newLevel;
} }

View File

@ -146,28 +146,14 @@ public class SocketHandler extends StreamHandler {
sock = new Socket(host, port); sock = new Socket(host, port);
OutputStream out = sock.getOutputStream(); OutputStream out = sock.getOutputStream();
BufferedOutputStream bout = new BufferedOutputStream(out); BufferedOutputStream bout = new BufferedOutputStream(out);
setOutputStreamPrivileged(bout); setOutputStream(bout);
} }
/** /**
* Close this output stream. * Close this output stream.
*/ */
@Override @Override
public void close() { public synchronized void close() {
if (tryUseLock()) {
try {
close0();
} finally {
unlock();
}
} else {
synchronized (this) {
close0();
}
}
}
private void close0() throws SecurityException {
super.close(); super.close();
if (sock != null) { if (sock != null) {
try { try {
@ -186,21 +172,7 @@ public class SocketHandler extends StreamHandler {
* silently ignored and is not published * silently ignored and is not published
*/ */
@Override @Override
public void publish(LogRecord record) { public synchronized void publish(LogRecord record) {
if (tryUseLock()) {
try {
publish0(record);
} finally {
unlock();
}
} else {
synchronized (this) {
publish0(record);
}
}
}
private void publish0(LogRecord record) {
if (!isLoggable(record)) { if (!isLoggable(record)) {
return; return;
} }

View File

@ -27,8 +27,6 @@
package java.util.logging; package java.util.logging;
import java.io.*; import java.io.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Objects; import java.util.Objects;
/** /**
@ -99,7 +97,7 @@ public class StreamHandler extends Handler {
// configure with default level but use specified formatter // configure with default level but use specified formatter
super(Level.INFO, null, Objects.requireNonNull(formatter)); super(Level.INFO, null, Objects.requireNonNull(formatter));
setOutputStreamPrivileged(out); setOutputStream(out);
} }
/** /**
@ -120,21 +118,7 @@ public class StreamHandler extends Handler {
* *
* @param out New output stream. May not be null. * @param out New output stream. May not be null.
*/ */
protected void setOutputStream(OutputStream out) { protected synchronized void setOutputStream(OutputStream out) {
if (tryUseLock()) {
try {
setOutputStream0(out);
} finally {
unlock();
}
} else {
synchronized (this) {
setOutputStream0(out);
}
}
}
private void setOutputStream0(OutputStream out) throws SecurityException {
if (out == null) { if (out == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
@ -167,22 +151,8 @@ public class StreamHandler extends Handler {
* not supported. * not supported.
*/ */
@Override @Override
public void setEncoding(String encoding) public synchronized void setEncoding(String encoding)
throws java.io.UnsupportedEncodingException { throws java.io.UnsupportedEncodingException {
if (tryUseLock()) {
try {
setEncoding0(encoding);
} finally {
unlock();
}
} else {
synchronized (this) {
setEncoding0(encoding);
}
}
}
private void setEncoding0(String encoding)
throws SecurityException, java.io.UnsupportedEncodingException {
super.setEncoding(encoding); super.setEncoding(encoding);
if (output == null) { if (output == null) {
return; return;
@ -214,21 +184,7 @@ public class StreamHandler extends Handler {
* silently ignored and is not published * silently ignored and is not published
*/ */
@Override @Override
public void publish(LogRecord record) { public synchronized void publish(LogRecord record) {
if (tryUseLock()) {
try {
publish0(record);
} finally {
unlock();
}
} else {
synchronized (this) {
publish0(record);
}
}
}
private void publish0(LogRecord record) {
if (!isLoggable(record)) { if (!isLoggable(record)) {
return; return;
} }
@ -280,21 +236,7 @@ public class StreamHandler extends Handler {
* Flush any buffered messages. * Flush any buffered messages.
*/ */
@Override @Override
public void flush() { public synchronized void flush() {
if (tryUseLock()) {
try {
flush0();
} finally {
unlock();
}
} else {
synchronized (this) {
flush0();
}
}
}
private void flush0() {
Writer writer = this.writer; Writer writer = this.writer;
if (writer != null) { if (writer != null) {
try { try {
@ -307,8 +249,7 @@ public class StreamHandler extends Handler {
} }
} }
private void flushAndClose() throws SecurityException { private void flushAndClose() {
checkPermission();
Writer writer = this.writer; Writer writer = this.writer;
if (writer != null) { if (writer != null) {
try { try {
@ -338,30 +279,8 @@ public class StreamHandler extends Handler {
* "tail" string. * "tail" string.
*/ */
@Override @Override
public void close() { public synchronized void close() {
if (tryUseLock()) {
try {
flushAndClose(); flushAndClose();
} finally {
unlock();
}
} else {
synchronized (this) {
flushAndClose();
}
}
} }
// Package-private support for setting OutputStream
// with elevated privilege.
@SuppressWarnings("removal")
final void setOutputStreamPrivileged(final OutputStream out) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
setOutputStream(out);
return null;
}
}, null, LogManager.controlPermission);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,8 +26,6 @@
package sun.util.logging.internal; package sun.util.logging.internal;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.lang.System.LoggerFinder; import java.lang.System.LoggerFinder;
@ -35,7 +33,6 @@ import java.lang.System.Logger;
import java.util.Objects; import java.util.Objects;
import java.util.logging.LogManager; import java.util.logging.LogManager;
import jdk.internal.logger.DefaultLoggerFinder; import jdk.internal.logger.DefaultLoggerFinder;
import java.util.logging.LoggingPermission;
import sun.util.logging.PlatformLogger; import sun.util.logging.PlatformLogger;
import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration; import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration;
@ -77,15 +74,9 @@ import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration;
* *
*/ */
public final class LoggingProviderImpl extends DefaultLoggerFinder { public final class LoggingProviderImpl extends DefaultLoggerFinder {
static final RuntimePermission LOGGERFINDER_PERMISSION =
new RuntimePermission("loggerFinder");
private static final LoggingPermission LOGGING_CONTROL_PERMISSION =
new LoggingPermission("control", null);
/** /**
* Creates a new instance of LoggingProviderImpl. * Creates a new instance of LoggingProviderImpl.
* @throws SecurityException if the calling code does not have the
* {@code RuntimePermission("loggerFinder")}.
*/ */
public LoggingProviderImpl() { public LoggingProviderImpl() {
} }
@ -147,13 +138,13 @@ public final class LoggingProviderImpl extends DefaultLoggerFinder {
} }
@Override @Override
public void log(sun.util.logging.PlatformLogger.Level level, Supplier<String> msgSuppier) { public void log(sun.util.logging.PlatformLogger.Level level, Supplier<String> msgSupplier) {
julLogger.log(toJUL(level), msgSuppier); julLogger.log(toJUL(level), msgSupplier);
} }
@Override @Override
public void log(sun.util.logging.PlatformLogger.Level level, Throwable thrown, Supplier<String> msgSuppier) { public void log(sun.util.logging.PlatformLogger.Level level, Throwable thrown, Supplier<String> msgSupplier) {
julLogger.log(toJUL(level), thrown, msgSuppier); julLogger.log(toJUL(level), thrown, msgSupplier);
} }
@Override @Override
@ -403,18 +394,10 @@ public final class LoggingProviderImpl extends DefaultLoggerFinder {
* @param module the module for which the logger should be created. * @param module the module for which the logger should be created.
* @return a Logger suitable for use in the given module. * @return a Logger suitable for use in the given module.
*/ */
@SuppressWarnings("removal")
private static java.util.logging.Logger demandJULLoggerFor(final String name, private static java.util.logging.Logger demandJULLoggerFor(final String name,
Module module) { Module module) {
final LogManager manager = LogManager.getLogManager(); final LogManager manager = LogManager.getLogManager();
final SecurityManager sm = System.getSecurityManager();
if (sm == null) {
return logManagerAccess.demandLoggerFor(manager, name, module); return logManagerAccess.demandLoggerFor(manager, name, module);
} else {
final PrivilegedAction<java.util.logging.Logger> pa =
() -> logManagerAccess.demandLoggerFor(manager, name, module);
return AccessController.doPrivileged(pa, null, LOGGING_CONTROL_PERMISSION);
}
} }
/** /**
@ -425,16 +408,9 @@ public final class LoggingProviderImpl extends DefaultLoggerFinder {
* corresponding java.util.logging.Logger backend}. * corresponding java.util.logging.Logger backend}.
* *
* @return {@inheritDoc} * @return {@inheritDoc}
* @throws SecurityException if the calling code doesn't have the
* {@code RuntimePermission("loggerFinder")}.
*/ */
@Override @Override
protected Logger demandLoggerFor(String name, Module module) { protected Logger demandLoggerFor(String name, Module module) {
@SuppressWarnings("removal")
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGERFINDER_PERMISSION);
}
return JULWrapper.of(demandJULLoggerFor(name,module)); return JULWrapper.of(demandJULLoggerFor(name,module));
} }
@ -445,25 +421,17 @@ public final class LoggingProviderImpl extends DefaultLoggerFinder {
// Hook for tests // Hook for tests
public static LogManagerAccess getLogManagerAccess() { public static LogManagerAccess getLogManagerAccess() {
@SuppressWarnings("removal") // Triggers initialization of logManagerAccess if not set.
final SecurityManager sm = System.getSecurityManager(); LogManagerAccess logManagerAccess = LoggingProviderImpl.logManagerAccess;
if (sm != null) {
sm.checkPermission(LOGGING_CONTROL_PERMISSION);
}
// Triggers initialization of accessJulLogger if not set.
if (logManagerAccess == null) LogManager.getLogManager(); if (logManagerAccess == null) LogManager.getLogManager();
logManagerAccess = LoggingProviderImpl.logManagerAccess;
return logManagerAccess; return logManagerAccess;
} }
private static volatile LogManagerAccess logManagerAccess; private static volatile LogManagerAccess logManagerAccess;
public static void setLogManagerAccess(LogManagerAccess accesLoggers) { public static void setLogManagerAccess(LogManagerAccess accessLoggers) {
@SuppressWarnings("removal") logManagerAccess = accessLoggers;
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(LOGGING_CONTROL_PERMISSION);
}
logManagerAccess = accesLoggers;
} }
} }