7003952: SEC: securely load DLLs and launch executables using fully qualified path
Summary: Enforce full path when specifying library locations.
Reviewed-by: wetmore, ohair
--- a/jdk/make/sun/security/pkcs11/Makefile Thu Apr 21 16:42:06 2011 -0700
+++ b/jdk/make/sun/security/pkcs11/Makefile Tue Apr 26 15:59:51 2011 -0700
@@ -147,7 +147,7 @@
# Rules
#
CLASSDESTDIR = $(TEMPDIR)/classes
-JAVAHFLAGS += -classpath $(CLASSDESTDIR)
+JAVAHFLAGS += -Xbootclasspath/p:$(CLASSDESTDIR)
include $(BUILDDIR)/common/Mapfile-vers.gmk
--- a/jdk/src/share/classes/sun/security/pkcs11/Config.java Thu Apr 21 16:42:06 2011 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs11/Config.java Tue Apr 26 15:59:51 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2011, 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
@@ -653,6 +653,13 @@
}
}
debug(keyword + ": " + lib);
+
+ // Check to see if full path is specified to prevent the DLL
+ // preloading attack
+ if (!(new File(lib)).isAbsolute()) {
+ throw new ConfigurationException(
+ "Absolute path required for library value: " + lib);
+ }
return lib;
}
--- a/jdk/src/share/classes/sun/security/pkcs11/Secmod.java Thu Apr 21 16:42:06 2011 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs11/Secmod.java Tue Apr 26 15:59:51 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, 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
@@ -236,7 +236,8 @@
throw new IllegalStateException(e);
}
if (modules == null) {
- List<Module> modules = (List<Module>)nssGetModuleList(nssHandle);
+ List<Module> modules = (List<Module>)nssGetModuleList(nssHandle,
+ nssLibDir);
this.modules = Collections.unmodifiableList(modules);
}
return modules;
@@ -358,7 +359,7 @@
* A representation of one PKCS#11 slot in a PKCS#11 module.
*/
public static final class Module {
- // name of the native library
+ // path of the native library
final String libraryName;
// descriptive name used by NSS
final String commonName;
@@ -371,8 +372,10 @@
// trust attributes. Used for the KEYSTORE and TRUSTANCHOR modules only
private Map<Bytes,TrustAttributes> trust;
- Module(String libraryName, String commonName, boolean fips, int slot) {
+ Module(String libraryDir, String libraryName, String commonName,
+ boolean fips, int slot) {
ModuleType type;
+
if ((libraryName == null) || (libraryName.length() == 0)) {
// must be softtoken
libraryName = System.mapLibraryName(SOFTTOKEN_LIB_NAME);
@@ -397,7 +400,7 @@
+ "module: " + libraryName + ", " + commonName);
}
}
- this.libraryName = libraryName;
+ this.libraryName = (new File(libraryDir, libraryName)).getPath();
this.commonName = commonName;
this.slot = slot;
this.type = type;
@@ -752,6 +755,6 @@
private static native boolean nssInit(String functionName, long handle, String configDir);
- private static native Object nssGetModuleList(long handle);
+ private static native Object nssGetModuleList(long handle, String libDir);
}
--- a/jdk/src/share/native/sun/security/pkcs11/j2secmod.c Thu Apr 21 16:42:06 2011 -0700
+++ b/jdk/src/share/native/sun/security/pkcs11/j2secmod.c Tue Apr 26 15:59:51 2011 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, 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
@@ -74,7 +74,7 @@
}
JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_Secmod_nssGetModuleList
- (JNIEnv *env, jclass thisClass, jlong jHandle)
+ (JNIEnv *env, jclass thisClass, jlong jHandle, jstring jLibDir)
{
FPTR_GetDBModuleList getModuleList =
(FPTR_GetDBModuleList)findFunction(env, jHandle, "SECMOD_GetDefaultModuleList");
@@ -104,8 +104,8 @@
jList = (*env)->NewObject(env, jListClass, jListConstructor);
jModuleClass = (*env)->FindClass(env, "sun/security/pkcs11/Secmod$Module");
- jModuleConstructor = (*env)->GetMethodID
- (env, jModuleClass, "<init>", "(Ljava/lang/String;Ljava/lang/String;ZI)V");
+ jModuleConstructor = (*env)->GetMethodID(env, jModuleClass, "<init>",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZI)V");
while (list != NULL) {
module = list->module;
@@ -124,7 +124,8 @@
}
jFIPS = module->isFIPS;
for (i = 0; i < module->slotCount; i++ ) {
- jModule = (*env)->NewObject(env, jModuleClass, jModuleConstructor, jDllName, jCommonName, jFIPS, i);
+ jModule = (*env)->NewObject(env, jModuleClass, jModuleConstructor,
+ jLibDir, jDllName, jCommonName, jFIPS, i);
(*env)->CallVoidMethod(env, jList, jAdd, jModule);
}
list = list->next;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/Provider/Absolute.cfg Tue Apr 26 15:59:51 2011 -0700
@@ -0,0 +1,10 @@
+#
+# Configuration file to allow the SunPKCS11 provider to utilize
+# the Solaris Cryptographic Framework, if it is available
+#
+
+name = Absolute
+
+description = SunPKCS11 using a relative path
+
+library = ./libpkcs11.so
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/pkcs11/Provider/Absolute.java Tue Apr 26 15:59:51 2011 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2011, 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 7003952
+ * @summary load DLLs and launch executables using fully qualified path
+ */
+import java.security.*;
+import java.lang.reflect.*;
+import sun.security.pkcs11.*;
+
+public class Absolute {
+
+ public static void main(String[] args) throws Exception {
+ Constructor cons;
+ try {
+ Class clazz = Class.forName("sun.security.pkcs11.SunPKCS11");
+ cons = clazz.getConstructor(new Class[] {String.class});
+ } catch (Exception ex) {
+ System.out.println("Skipping test - no PKCS11 provider available");
+ return;
+ }
+
+ String config =
+ System.getProperty("test.src", ".") + "/Absolute.cfg";
+
+ try {
+ Object obj = cons.newInstance(new Object[] {config});
+ } catch (InvocationTargetException ite) {
+ Throwable cause = ite.getCause();
+ if (cause instanceof ProviderException) {
+ Throwable cause2 = cause.getCause();
+ if ((cause2 == null) ||
+ !cause2.getMessage().startsWith(
+ "Absolute path required for library value:")) {
+ // rethrow
+ throw (ProviderException) cause;
+ }
+ System.out.println("Caught expected Exception: \n" + cause2);
+ }
+ }
+ }
+}