# HG changeset patch # User valeriep # Date 1303858791 25200 # Node ID 3fedf261fb4f4785f69e8cef95feba0e95ac4aec # Parent b2295905901a3f22054e011b9bb908bb120b4e08 7003952: SEC: securely load DLLs and launch executables using fully qualified path Summary: Enforce full path when specifying library locations. Reviewed-by: wetmore, ohair diff -r b2295905901a -r 3fedf261fb4f make/sun/security/pkcs11/Makefile --- a/make/sun/security/pkcs11/Makefile Thu Apr 21 16:42:06 2011 -0700 +++ b/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 diff -r b2295905901a -r 3fedf261fb4f src/share/classes/sun/security/pkcs11/Config.java --- a/src/share/classes/sun/security/pkcs11/Config.java Thu Apr 21 16:42:06 2011 -0700 +++ b/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; } diff -r b2295905901a -r 3fedf261fb4f src/share/classes/sun/security/pkcs11/Secmod.java --- a/src/share/classes/sun/security/pkcs11/Secmod.java Thu Apr 21 16:42:06 2011 -0700 +++ b/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 modules = (List)nssGetModuleList(nssHandle); + List modules = (List)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 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); } diff -r b2295905901a -r 3fedf261fb4f src/share/native/sun/security/pkcs11/j2secmod.c --- a/src/share/native/sun/security/pkcs11/j2secmod.c Thu Apr 21 16:42:06 2011 -0700 +++ b/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, "", "(Ljava/lang/String;Ljava/lang/String;ZI)V"); + jModuleConstructor = (*env)->GetMethodID(env, jModuleClass, "", + "(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; diff -r b2295905901a -r 3fedf261fb4f test/sun/security/pkcs11/Provider/Absolute.cfg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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 diff -r b2295905901a -r 3fedf261fb4f test/sun/security/pkcs11/Provider/Absolute.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/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); + } + } + } +}