Closed Bug 1263017 Opened 4 years ago Closed 3 years ago

pycurl fails with CKR_DEVICE_ERROR after fork() when NSS was initialized by someone else

Categories

(NSS :: Libraries, defect)

3.19.1
defect
Not set

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: elio.maldonado.batiz, Assigned: rrelyea)

References

Details

Attachments

(1 file, 1 obsolete file)

As originally reported by Martin Milata:

It appears to be impossible to use pycurl in a child process when NSS was previously initialized by something else than (py)curl. Following error is raised:

  A PKCS #11 module returned CKR_DEVICE_ERROR, indicating that a problem has occurred with the token or slot.

We ran into this with koji and koji-containerbuild plugin, provided example executes the same sequence of events. Inserting call to pycurl.global_cleanup() or pycurl.global_init() doesn't seem to help. In this case NSS_InitContext is called when the rpm module is loaded, I haven't tried initializing it any other way so it is possible that this is in fact bug in RPM. Note that this problem is also reproducible on Fedora 23.

Version-Release number of selected component (if applicable):

libcurl-7.29.0-25.el7.x86_64
nss-3.19.1-19.el7_2.x86_64
nss-softokn-3.16.2.3-13.el7_1.x86_64
python-pycurl-7.19.0-17.el7.x86_64
rpm-4.11.3-17.el7.x86_64
rpm-python-4.11.3-17.el7.x86_64

How reproducible: Always.

Steps to Reproduce:

$ cat > reproducer.py
#!/usr/bin/python

import rpm
import pycurl

import os
import sys

def curl_get():
    c = pycurl.Curl()
    c.setopt(c.URL, 'https://google.com/')
    c.setopt(c.WRITEFUNCTION, sys.stdout.write)
    c.perform()
    c.close()

if os.fork():
    print 'parent: waiting'
    os.wait()
    print 'parent: done'
else:
    print 'child: start'
    curl_get()
    print 'child: done'
^D
$ python reproducer.py


Actual results:

parent: waiting
child: start
Traceback (most recent call last):
  File "reproducer.py", line 22, in <module>
    curl_get()
  File "reproducer.py", line 13, in curl_get
    c.perform()
pycurl.error: (35, 'A PKCS #11 module returned CKR_DEVICE_ERROR, indicating that a problem has occurred with the token or slot.')
parent: done

Expected results:

parent: waiting
child: start
(page content)
child: done
parent: done
Bob Relyea 2016-03-15 16:21:36 EDT

There's a function in NSS:

SECMOD_RestartModules()

If you call it after a fork() it will reinitialize all the PKCS #11 modules.

Softoken is following the current PKCS #11 standard (as other PKCS #11 modules will follow). If you are tripping over this in softoken, you will really have issues in an HSM PKCS #11 module (or a smart card).

Calling SECMOD_RestartModules(PR_FALSE) is safe even if you haven't forked. It only restart modules that need a restart because of a fork().

bob
 Bob Relyea 2016-04-07 17:29:26 EDT

> Unless it has some nasty side effects (like invalidating handles of other
> libraries using nss in the same process),

It will invalidate any handles that are open, but only in modules that need to be restarted after the fork(), so those handles aren't accessible anymore anyway. If the module does not need to be restarted, it won't be (thus no handles are invalidated).

I've added it now to NSS_ContextInit() (this the supplied patch).

You can still run into issues if you call any form of NSS_XXXInitXXXX() fork() and then use NSS. I've only added it to the NSS_ContextInit() case because that's what libraries normally call, and they could be in the case where the application initialized NSS then forked (so pretty much every library would have to call SECMOD_RestartModules anyway). Applications call the other forms of NSS_Initialize, which are call 'once' functions, so by definition you can't run into a case where SECMOD_RestartModules() will help. Those application still need to call SECMOD_RestartModules after they fork to get regular NSS calls working again.

bob
This is Bob's patch that soon will be undergoing testing downstram. Will request a review as soon we get positive feedback.
Assignee: nobody → rrelyea
Any update on this?
Bob, is this ready to land?
Flags: needinfo?(rrelyea)
Comment on attachment 8739262 [details] [diff] [review]
force restart modules whenever NSS_InitContext is called

Review of attachment 8739262 [details] [diff] [review]:
-----------------------------------------------------------------

r+ rrelyea
Attachment #8739262 - Flags: review+
yes. I just r+'ed it. You can land it any time.
Flags: needinfo?(rrelyea)
Updated Bob's patch for latest sources. I also made some white space changes, tabs replaced by spaces, to comply with current coding standards. Bob, as you are the author we may need another reviewer.
Attachment #8739262 - Attachment is obsolete: true
Attachment #8804802 - Flags: review?(rrelyea)
Comment on attachment 8804802 [details] [diff] [review]
force restart modules whenever NSS_InitContext is called

IIUC the patch was provided by Bob, this means he cannot r+ his own patch.

The only change in Elio's updated patch is a comment fix.

The explanation in the comment seems reasonable. Given that this has apparently been tested elsewhere, r=kaie
Attachment #8804802 - Flags: review?(rrelyea) → review+
https://hg.mozilla.org/projects/nss/rev/00ca1fbb8c5c
Status: NEW → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED
Target Milestone: --- → 3.28
You need to log in before you can comment on or make changes to this bug.