Last Comment Bug 486716 - Darwin/X11 - No certs, libnssckbi.dylib fails to load
: Darwin/X11 - No certs, libnssckbi.dylib fails to load
Product: Core
Classification: Components
Component: Security: PSM (show other bugs)
: Trunk
: All Mac OS X
-- normal (vote)
: ---
Assigned To: Nobody; OK to take it and work on it
: David Keeler [:keeler] (use needinfo?)
Depends on: 712579
  Show dependency treegraph
Reported: 2009-04-03 10:52 PDT by Jeremy Huddleston
Modified: 2012-01-12 04:07 PST (History)
7 users (show)
See Also:
Crash Signature:
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Description User image Jeremy Huddleston 2009-04-03 10:52:52 PDT
User-Agent:       Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
Build Identifier: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3

Breakpoint 1, 0x01cf8937 in nss_Init (configdir=0x2117dc8 "/Users/jeremy/.mozilla/firefox/5a93rjgb.default", certPrefix=0x1e5da70 "", keyPrefix=0x1e5da70 "", secmodName=0x1e4fed8 "secmod.db", updateDir=0x1e5da70 "", updCertPrefix=0x1e5da70 "", updKeyPrefix=0x1e5da70 "", updateID=0x1e5da70 "", updateName=0x1e5da70 "", readOnly=0, noCertDB=0, noModDB=0, forceOpen=0, noRootInit=0, optimizeSpace=1, noSingleThreadedModules=0, allowAlreadyInitializedModules=0, dontFinalizeModules=0) at nssinit.c:432
432	{
(gdb) n
433	    char *moduleSpec = NULL;
(gdb) n
434	    char *flags = NULL;
(gdb) n
435	    SECStatus rv = SECFailure;
(gdb) n
436	    char *lconfigdir = NULL;
(gdb) n
437	    char *lcertPrefix = NULL;
(gdb) n
438	    char *lkeyPrefix = NULL;
(gdb) n
439	    char *lsecmodName = NULL;
(gdb) n
440	    char *lupdateDir = NULL;
(gdb) n
441	    char *lupdCertPrefix = NULL;
(gdb) c
Reading symbols for shared libraries . done
Reading symbols for shared libraries . done
Reading symbols for shared libraries . done

Breakpoint 2, 0x01cf8877 in nss_FindExternalRoot (dbpath=0x2117dc8 "/Users/jeremy/.mozilla/firefox/5a93rjgb.default", secmodprefix=0x1e4fed8 "secmod.db") at nssinit.c:372
372	{
(gdb) n
373		char *path = NULL;
(gdb) n
374	        char *oldpath = NULL;
(gdb) n
375	        PRBool hasrootcerts = PR_FALSE;
(gdb) n
382	        nss_FindExternalRootPaths(dbpath, secmodprefix, &oldpath, &path);
(gdb) n
383	        if (oldpath) {
(gdb) print oldpath
$1 = 0x0
(gdb) print path
$2 = 0x390baf0 "/Users/jeremy/.mozilla/firefox/5a93rjgb.default/libnssckbi.dylib"
(gdb) n
387	        if (path && !hasrootcerts) {
(gdb) n
388		    (void) SECMOD_AddNewModule("Root Certs",path, 0, 0);
(gdb) s
SECMOD_AddNewModule (moduleName=0x1e4fdac "Root Certs", dllPath=0x390baf0 "/Users/jeremy/.mozilla/firefox/5a93rjgb.default/libnssckbi.dylib", defaultMechanismFlags=0, cipherEnableFlags=0) at pk11util.c:626
626	    return SECMOD_AddNewModuleEx(moduleName, dllPath, defaultMechanismFlags,
(gdb) s
SECMOD_AddNewModuleEx (moduleName=0x1e4fdac "Root Certs", dllPath=0x390baf0 "/Users/jeremy/.mozilla/firefox/5a93rjgb.default/libnssckbi.dylib", defaultMechanismFlags=0, cipherEnableFlags=0, modparms=0x0, nssparms=0x0) at pk11util.c:572
572	    SECStatus result = SECFailure;
(gdb) n
576	    PR_SetErrorText(0, NULL);
(gdb) n
578	    module = SECMOD_CreateModule(dllPath, moduleName, modparms, nssparms);
(gdb) s
SECMOD_CreateModule (library=0x390baf0 "/Users/jeremy/.mozilla/firefox/5a93rjgb.default/libnssckbi.dylib", moduleName=0x1e4fdac "Root Certs", parameters=0x0, nss=0x0) at pk11pars.c:117
117	    SECMODModule *mod = secmod_NewModule();
(gdb) n
120	    char *nssc = (char *)nss;
(gdb) n
121	    if (mod == NULL) return NULL;
(gdb) n
123	    mod->commonName = PORT_ArenaStrdup(mod->arena,moduleName ? moduleName : "");
(gdb) n
124	    if (library) {
(gdb) n
125		mod->dllName = PORT_ArenaStrdup(mod->arena,library);
(gdb) n
128	    if (parameters) {
(gdb) n
131	    mod->internal   = secmod_argHasFlag("flags","internal",nssc);
(gdb) print mod->dllName
$3 = 0x2b25090 "/Users/jeremy/.mozilla/firefox/5a93rjgb.default/libnssckbi.dylib"
(gdb) n
132	    mod->isFIPS     = secmod_argHasFlag("flags","FIPS",nssc);
(gdb) n
133	    mod->isCritical = secmod_argHasFlag("flags","critical",nssc);
(gdb) n
134	    slotParams      = secmod_argGetParamValue("slotParams",nssc);
(gdb) n
135	    mod->slotInfo   = secmod_argParseSlotInfo(mod->arena,slotParams,
(gdb) n
137	    if (slotParams) PORT_Free(slotParams);
139	    mod->trustOrder  = secmod_argReadLong("trustOrder",nssc,
142	    mod->cipherOrder = secmod_argReadLong("cipherOrder",nssc,
145	    mod->isModuleDB   = secmod_argHasFlag("flags","moduleDB",nssc);
146	    mod->moduleDBOnly = secmod_argHasFlag("flags","moduleDBOnly",nssc);
147	    if (mod->moduleDBOnly) mod->isModuleDB = PR_TRUE;
149	    ciphers = secmod_argGetParamValue("ciphers",nssc);
150	    secmod_argSetNewCipherFlags(&mod->ssl[0],ciphers);
151	    if (ciphers) PORT_Free(ciphers);
153	    secmod_PrivateModuleCount++;
155	    return mod;
156	}
SECMOD_AddNewModuleEx (moduleName=0x1e4fdac "Root Certs", dllPath=0x390baf0 "/Users/jeremy/.mozilla/firefox/5a93rjgb.default/libnssckbi.dylib", defaultMechanismFlags=0, cipherEnableFlags=0, modparms=0x0, nssparms=0x0) at pk11util.c:580
580	    if (module == NULL) {
(gdb) n
584	    if (module->dllName != NULL) {
585	        if (module->dllName[0] != 0) {
586	            result = SECMOD_AddModule(module);
(gdb) s
SECMOD_AddModule (newModule=0x2b25010) at pk11util.c:481
481	    if ((oldModule = SECMOD_FindModule(newModule->commonName)) != NULL) {
(gdb) n
487	    rv = SECMOD_LoadPKCS11Module(newModule);
(gdb) s
SECMOD_LoadPKCS11Module (mod=0x2b25010) at pk11load.c:263
263	    PRLibrary *library = NULL;
(gdb) n
264	    CK_C_GetFunctionList entry = NULL;
267	    CK_ULONG slotCount = 0;
269	    PRBool alreadyLoaded = PR_FALSE;
270	    char *disableUnload = NULL;
272	    if (mod->loaded) return SECSuccess;
275	    if (mod->internal) {
308		if (mod->dllName == NULL) {
319		full_name = PORT_Strdup(mod->dllName);
325		library = PR_LoadLibrary(full_name);
(gdb) print full_name
$4 = 0x390bc20 "/Users/jeremy/.mozilla/firefox/5a93rjgb.default/libnssckbi.dylib"
(gdb) s
326		mod->library = (void *)library;
(gdb) n
330		PORT_Free(full_name);
333		if (library == NULL) {
334		    return SECFailure;
(gdb) print library
$5 = (PRLibrary *) 0x0
(gdb) quit
The program is running.  Exit anyway? (y or n) y

Reproducible: Always

The problem is that libnssckbi.dylib is in /opt/local/lib/libnssckbi.dylib . The library being requested is /Users/jeremy/.mozilla/firefox/5a93rjgb.default/libnssckbi.dylib , if I make a symlink from MOZILLA_FIVE_HOME/libnssckbi.dylib to it, it will load.  This is because it follows up the failed load with:

(gdb) c  

Breakpoint 1, PR_LoadLibrary (name=0x390ce40 "/opt/local/lib/firefox-x11/libnssckbi.dylib") at prlink.c:599
599	{
(gdb) bt
#0  PR_LoadLibrary (name=0x390ce40 "/opt/local/lib/firefox-x11/libnssckbi.dylib") at prlink.c:599
#1  0x01d6dce2 in SECMOD_LoadPKCS11Module (mod=0x2b22210) at pk11load.c:325
#2  0x01d7a83e in SECMOD_LoadModule (modulespec=0x390cf78 "name=\"Builtin Roots Module\" library=\"/opt/local/lib/firefox-x11/libnssckbi.dylib\"", parent=0x0, recurse=0) at pk11pars.c:323
#3  0x01d7a9d5 in SECMOD_LoadUserModule (modulespec=0x390cf78 "name=\"Builtin Roots Module\" library=\"/opt/local/lib/firefox-x11/libnssckbi.dylib\"", parent=0x0, recurse=0) at pk11pars.c:391

but when we do --with-system-nss, we need to look where the system nss is and load those as well
Comment 1 User image Hanspeter Niederstrasser 2009-04-05 03:36:44 PDT
I do not see this when an internal libnssckbi.dylib is used (3.1b3, 10.5/intel/X11)
Comment 2 User image Jeremy Huddleston 2009-04-05 03:40:08 PDT
That is correct.  That is because the internal libnssckbi.dylib is installed in MOZILLA_FIVE_HOME.  The system-nss isn't necessarily there (as I mentioned, we use a symlink to workaround this for now).
Comment 3 User image Tyler Downer [:Tyler] 2010-10-06 14:24:47 PDT
This is a mass search for bugs which are in the Firefox General component, are
UNCO, have not been changed for 500 days and have an unspecified version. 

Reporter, can you please update to Firefox 3.6.10 or later, create a fresh profile,, and test again. If you still see the issue, please update this bug. If the issue is gone, please set the status to RESOLVED > WORKSFORME.
Comment 4 User image Jeremy Huddleston 2010-10-06 16:31:31 PDT
yeah, still an issue.
Comment 5 User image Hanspeter Niederstrasser 2011-08-18 03:31:43 PDT
Confirming on trunk m-c built on 10.7/x86_64
Comment 6 User image Kai Engert (:kaie) 2011-08-18 13:10:22 PDT
Out of curiousity, which software installs NSS in a system location on OSX?
Comment 7 User image Kai Engert (:kaie) 2011-08-18 13:11:17 PDT
Actually, this might rather be a PSM issue, because PSM has the code to attempt to detect the ckbi librariy.
Comment 8 User image Kai Engert (:kaie) 2011-08-18 13:14:57 PDT
what happens if you add the system directory (the one that contains the ckbi library) to LD_LIBRARY_PATH (or it's OSX equivalent, I don't what exactly must be used) prior to starting?
Comment 9 User image Kai Engert (:kaie) 2011-08-18 13:21:47 PDT
Talked on IRC.
Given that it works, if you add the directory containing the lib to the library search path (DYLD_LIBRARY_PATH), then there is no bug.

Given that we cannot guess where on the system the lib is installed, there must be a hint, and this is it.

Resolving as invalid.
As a final test, you might include multiple directories in that variable (probably separated by colon dir1:dir2:dir3), and see if that works, too.
Comment 10 User image Jeremy Huddleston 2011-08-24 12:42:41 PDT
Uhm, no.  Setting DYLD_LIBRARY_PATH is bad practice.  This location should be configured at runtime, and you can dlopen() the full path or link to it at build time.
Comment 11 User image Kai Engert (:kaie) 2011-08-24 13:14:51 PDT
Then please tell me:

How does the executable learn from which directory it must load the other NSS system libraries like libnss3 ?
Comment 12 User image Robert Relyea 2011-08-24 13:58:39 PDT
static const char *NameOfNSSLib = SHLIB_PREFIX"nss3."SHLIB_SUFFIX;

path = PR_GetLibraryFilePathname(NameOfNSSLib,

This is essentially how softoken finds freebl. (see mozilla/security/nss/lib/freebl/{loader,genload.c}

Comment 13 User image Wan-Teh Chang 2011-08-24 15:02:08 PDT
Kai: PSM can also just load "libnssckbi.dylib" and rely
on the current dynamic shared library search path.

Jeremy: is /opt/local/lib on the dynamic shared library
search path of MacPorts users?
Comment 14 User image Jeremy Huddleston 2011-08-24 19:39:33 PDT
darwin does not use a shared library search path like linux.  Each library has an id which is its path on the system at run time.  At link time, the linker embeds this id in the linked executable.  At load time, the loaded resolves the link using that path.

dlopen() is expected to take a full path to the library being opened.  It is possible to use a search path, but it is highly frowned upon and not configured by default.
Comment 15 User image Kai Engert (:kaie) 2011-09-13 12:13:42 PDT
I like Bob's proposal from comment 12.
Someone needs to implement it.
Comment 16 User image Wan-Teh Chang 2011-09-13 15:29:59 PDT
Yes, if libnss3.dylib and libnssckbi.dylib are installed in the
same directory, then I agree Bob's proposal in comment 12 is the
right solution.
Comment 17 User image Kai Engert (:kaie) 2012-01-10 11:30:56 PST
Bug 712759 has a patch that implements this strategy.
Comment 18 User image Kai Engert (:kaie) 2012-01-12 04:07:38 PST
This should be fixed by bug 712579.

Note You need to log in before you can comment on or make changes to this bug.