8075545: Add permission check for locale service provider implementations
Reviewed-by: mchung, alanb
--- a/jdk/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java Wed Apr 29 10:25:53 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java Wed Apr 29 11:03:56 2015 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -140,11 +140,24 @@
*/
public abstract class LocaleServiceProvider {
+ private static Void checkPermission() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new RuntimePermission("localeServiceProvider"));
+ }
+ return null;
+ }
+ private LocaleServiceProvider(Void ignore) { }
+
/**
- * Sole constructor. (For invocation by subclass constructors, typically
- * implicit.)
+ * Initializes a new locale service provider.
+ *
+ * @throws SecurityException
+ * If a security manager has been installed and it denies
+ * {@link RuntimePermission RuntimePermission("localeServiceProvider")}
*/
protected LocaleServiceProvider() {
+ this(checkPermission());
}
/**
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/AuxLocaleProviderAdapter.java Wed Apr 29 10:25:53 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/AuxLocaleProviderAdapter.java Wed Apr 29 11:03:56 2015 -0700
@@ -25,6 +25,8 @@
package sun.util.locale.provider;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.text.spi.BreakIteratorProvider;
import java.text.spi.CollatorProvider;
import java.text.spi.DateFormatProvider;
@@ -177,7 +179,9 @@
* A dummy locale service provider that indicates there is no
* provider available
*/
- private static final NullProvider NULL_PROVIDER = new NullProvider();
+ private static final NullProvider NULL_PROVIDER = AccessController.doPrivileged(
+ (PrivilegedAction<NullProvider>) () -> new NullProvider());
+
private static class NullProvider extends LocaleServiceProvider {
@Override
public Locale[] getAvailableLocales() {
--- a/jdk/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java Wed Apr 29 10:25:53 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java Wed Apr 29 11:03:56 2015 -0700
@@ -26,7 +26,7 @@
package sun.util.locale.provider;
import java.security.AccessController;
-import java.security.PrivilegedActionException;
+import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.text.spi.BreakIteratorProvider;
import java.text.spi.CollatorProvider;
@@ -133,8 +133,12 @@
@Override
public BreakIteratorProvider getBreakIteratorProvider() {
if (breakIteratorProvider == null) {
- BreakIteratorProvider provider = new BreakIteratorProviderImpl(getAdapterType(),
- getLanguageTagSet("FormatData"));
+ BreakIteratorProvider provider = AccessController.doPrivileged(
+ (PrivilegedAction<BreakIteratorProvider>) () ->
+ new BreakIteratorProviderImpl(
+ getAdapterType(),
+ getLanguageTagSet("FormatData")));
+
synchronized (this) {
if (breakIteratorProvider == null) {
breakIteratorProvider = provider;
@@ -147,8 +151,12 @@
@Override
public CollatorProvider getCollatorProvider() {
if (collatorProvider == null) {
- CollatorProvider provider = new CollatorProviderImpl(getAdapterType(),
- getLanguageTagSet("CollationData"));
+ CollatorProvider provider = AccessController.doPrivileged(
+ (PrivilegedAction<CollatorProvider>) () ->
+ new CollatorProviderImpl(
+ getAdapterType(),
+ getLanguageTagSet("CollationData")));
+
synchronized (this) {
if (collatorProvider == null) {
collatorProvider = provider;
@@ -161,8 +169,12 @@
@Override
public DateFormatProvider getDateFormatProvider() {
if (dateFormatProvider == null) {
- DateFormatProvider provider = new DateFormatProviderImpl(getAdapterType(),
- getLanguageTagSet("FormatData"));
+ DateFormatProvider provider = AccessController.doPrivileged(
+ (PrivilegedAction<DateFormatProvider>) () ->
+ new DateFormatProviderImpl(
+ getAdapterType(),
+ getLanguageTagSet("FormatData")));
+
synchronized (this) {
if (dateFormatProvider == null) {
dateFormatProvider = provider;
@@ -175,8 +187,12 @@
@Override
public DateFormatSymbolsProvider getDateFormatSymbolsProvider() {
if (dateFormatSymbolsProvider == null) {
- DateFormatSymbolsProvider provider = new DateFormatSymbolsProviderImpl(getAdapterType(),
- getLanguageTagSet("FormatData"));
+ DateFormatSymbolsProvider provider = AccessController.doPrivileged(
+ (PrivilegedAction<DateFormatSymbolsProvider>) () ->
+ new DateFormatSymbolsProviderImpl(
+ getAdapterType(),
+ getLanguageTagSet("FormatData")));
+
synchronized (this) {
if (dateFormatSymbolsProvider == null) {
dateFormatSymbolsProvider = provider;
@@ -189,7 +205,12 @@
@Override
public DecimalFormatSymbolsProvider getDecimalFormatSymbolsProvider() {
if (decimalFormatSymbolsProvider == null) {
- DecimalFormatSymbolsProvider provider = new DecimalFormatSymbolsProviderImpl(getAdapterType(), getLanguageTagSet("FormatData"));
+ DecimalFormatSymbolsProvider provider = AccessController.doPrivileged(
+ (PrivilegedAction<DecimalFormatSymbolsProvider>) () ->
+ new DecimalFormatSymbolsProviderImpl(
+ getAdapterType(),
+ getLanguageTagSet("FormatData")));
+
synchronized (this) {
if (decimalFormatSymbolsProvider == null) {
decimalFormatSymbolsProvider = provider;
@@ -202,8 +223,12 @@
@Override
public NumberFormatProvider getNumberFormatProvider() {
if (numberFormatProvider == null) {
- NumberFormatProvider provider = new NumberFormatProviderImpl(getAdapterType(),
- getLanguageTagSet("FormatData"));
+ NumberFormatProvider provider = AccessController.doPrivileged(
+ (PrivilegedAction<NumberFormatProvider>) () ->
+ new NumberFormatProviderImpl(
+ getAdapterType(),
+ getLanguageTagSet("FormatData")));
+
synchronized (this) {
if (numberFormatProvider == null) {
numberFormatProvider = provider;
@@ -219,8 +244,12 @@
@Override
public CurrencyNameProvider getCurrencyNameProvider() {
if (currencyNameProvider == null) {
- CurrencyNameProvider provider = new CurrencyNameProviderImpl(getAdapterType(),
- getLanguageTagSet("CurrencyNames"));
+ CurrencyNameProvider provider = AccessController.doPrivileged(
+ (PrivilegedAction<CurrencyNameProvider>) () ->
+ new CurrencyNameProviderImpl(
+ getAdapterType(),
+ getLanguageTagSet("CurrencyNames")));
+
synchronized (this) {
if (currencyNameProvider == null) {
currencyNameProvider = provider;
@@ -233,8 +262,12 @@
@Override
public LocaleNameProvider getLocaleNameProvider() {
if (localeNameProvider == null) {
- LocaleNameProvider provider = new LocaleNameProviderImpl(getAdapterType(),
- getLanguageTagSet("LocaleNames"));
+ LocaleNameProvider provider = AccessController.doPrivileged(
+ (PrivilegedAction<LocaleNameProvider>) () ->
+ new LocaleNameProviderImpl(
+ getAdapterType(),
+ getLanguageTagSet("LocaleNames")));
+
synchronized (this) {
if (localeNameProvider == null) {
localeNameProvider = provider;
@@ -247,8 +280,12 @@
@Override
public TimeZoneNameProvider getTimeZoneNameProvider() {
if (timeZoneNameProvider == null) {
- TimeZoneNameProvider provider = new TimeZoneNameProviderImpl(getAdapterType(),
- getLanguageTagSet("TimeZoneNames"));
+ TimeZoneNameProvider provider = AccessController.doPrivileged(
+ (PrivilegedAction<TimeZoneNameProvider>) () ->
+ new TimeZoneNameProviderImpl(
+ getAdapterType(),
+ getLanguageTagSet("TimeZoneNames")));
+
synchronized (this) {
if (timeZoneNameProvider == null) {
timeZoneNameProvider = provider;
@@ -261,9 +298,12 @@
@Override
public CalendarDataProvider getCalendarDataProvider() {
if (calendarDataProvider == null) {
- CalendarDataProvider provider;
- provider = new CalendarDataProviderImpl(getAdapterType(),
- getLanguageTagSet("CalendarData"));
+ CalendarDataProvider provider = AccessController.doPrivileged(
+ (PrivilegedAction<CalendarDataProvider>) () ->
+ new CalendarDataProviderImpl(
+ getAdapterType(),
+ getLanguageTagSet("CalendarData")));
+
synchronized (this) {
if (calendarDataProvider == null) {
calendarDataProvider = provider;
@@ -276,9 +316,12 @@
@Override
public CalendarNameProvider getCalendarNameProvider() {
if (calendarNameProvider == null) {
- CalendarNameProvider provider;
- provider = new CalendarNameProviderImpl(getAdapterType(),
- getLanguageTagSet("FormatData"));
+ CalendarNameProvider provider = AccessController.doPrivileged(
+ (PrivilegedAction<CalendarNameProvider>) () ->
+ new CalendarNameProviderImpl(
+ getAdapterType(),
+ getLanguageTagSet("FormatData")));
+
synchronized (this) {
if (calendarNameProvider == null) {
calendarNameProvider = provider;
@@ -294,8 +337,12 @@
@Override
public CalendarProvider getCalendarProvider() {
if (calendarProvider == null) {
- CalendarProvider provider = new CalendarProviderImpl(getAdapterType(),
- getLanguageTagSet("CalendarData"));
+ CalendarProvider provider = AccessController.doPrivileged(
+ (PrivilegedAction<CalendarProvider>) () ->
+ new CalendarProviderImpl(
+ getAdapterType(),
+ getLanguageTagSet("CalendarData")));
+
synchronized (this) {
if (calendarProvider == null) {
calendarProvider = provider;
@@ -319,6 +366,7 @@
}
// ResourceBundleBasedAdapter method implementation
+
@Override
public LocaleData getLocaleData() {
if (localeData == null) {
@@ -449,4 +497,4 @@
}
return locales;
}
- }
+}
--- a/jdk/test/java/util/PluggableLocale/ExecTest.sh Wed Apr 29 10:25:53 2015 -0700
+++ b/jdk/test/java/util/PluggableLocale/ExecTest.sh Wed Apr 29 11:03:56 2015 -0700
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
# Parameters:
# providersToTest: [foo|bar|foobar]
# java class name: <class name>
-# providersInExtDir: [true|false]
+# java security policy file: (Optional. Installs security manager if exists)
if [ "${TESTSRC}" = "" ]
then
@@ -113,8 +113,14 @@
exit $result
fi
+# security options
+if [ "$3" != "" ]
+then
+ SECURITYOPTS="-Djava.security.manager -Djava.security.policy=${TESTSRC}${FS}$3"
+fi
+
# run
-RUNCMD="${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -classpath ${CLASSPATHARG} $2 "
+RUNCMD="${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} ${SECURITYOPTS} -classpath ${CLASSPATHARG} $2 "
echo ${RUNCMD}
${RUNCMD}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/PluggableLocale/PermissionTest.java Wed Apr 29 11:03:56 2015 -0700
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/*
+ *
+ */
+public class PermissionTest{
+
+ // Make sure provider impls can be instantiated under a security manager.ZZ
+ com.foo.BreakIteratorProviderImpl breakIP = new com.foo.BreakIteratorProviderImpl();
+ com.foo.CollatorProviderImpl collatorP = new com.foo.CollatorProviderImpl();
+ com.foo.DateFormatProviderImpl dateFP = new com.foo.DateFormatProviderImpl();
+ com.foo.DateFormatSymbolsProviderImpl dateFSP = new com.foo.DateFormatSymbolsProviderImpl();
+ com.foo.DecimalFormatSymbolsProviderImpl decimalFSP = new com.foo.DecimalFormatSymbolsProviderImpl();
+ com.foo.NumberFormatProviderImpl numberFP = new com.foo.NumberFormatProviderImpl();
+ com.bar.CurrencyNameProviderImpl currencyNP = new com.bar.CurrencyNameProviderImpl();
+ com.bar.CurrencyNameProviderImpl2 currencyNP2 = new com.bar.CurrencyNameProviderImpl2();
+ com.bar.LocaleNameProviderImpl localeNP = new com.bar.LocaleNameProviderImpl();
+ com.bar.TimeZoneNameProviderImpl tzNP = new com.bar.TimeZoneNameProviderImpl();
+ com.bar.GenericTimeZoneNameProviderImpl tzGenNP = new com.bar.GenericTimeZoneNameProviderImpl();
+ com.bar.CalendarDataProviderImpl calDataP = new com.bar.CalendarDataProviderImpl();
+ com.bar.CalendarNameProviderImpl calNameP = new com.bar.CalendarNameProviderImpl();
+
+ public static void main(String[] s) {
+ new PermissionTest();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/PluggableLocale/PermissionTest.sh Wed Apr 29 11:03:56 2015 -0700
@@ -0,0 +1,31 @@
+#!/bin/sh
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+#
+# @test
+# @bug 8075545
+# @summary Check whether RuntimePermission("localeServiceProvider") is
+# handled correctly
+# @run shell ExecTest.sh foobar PermissionTest
+# @run shell/fail ExecTest.sh foobar PermissionTest dummy
+# @run shell ExecTest.sh foobar PermissionTest localeServiceProvider.policy
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/PluggableLocale/localeServiceProvider.policy Wed Apr 29 11:03:56 2015 -0700
@@ -0,0 +1,3 @@
+grant {
+ permission java.lang.RuntimePermission "localeServiceProvider";
+};