New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
random.c: Prefer getrandom() over getentropy() to support glibc 2.24 on Linux #73343
Comments
A new getentropy() function was recently added to the glibc: When the Python/random.c file was written (by me), the getentropy() function was only supported on OpenBSD. Later, random.c was modified to *not* use getentropy() on Solaris (Issue bpo-25003). The problem is that py_getentropy() doesn't handle ENOSYS, and so Python fails at startup with a fatal error (Python 3.6): The bug was first reported in Fedora 26 (rawhide): Attached patch (written for the default branch) should fix these issues:
I'm not sure that handling ENOSYS is required, since it's no more used on Linux, but it shouldn't hurt. I don't know if py_getentropy() should also handle EPERM? py_getrandom() catchs errors: EAGAIN, EINTR, EPERM and ENOSYS. With the patch, py_getentropy() catchs ENOSYS error. |
Python 2.7, 3.5, 3.6 and 3.7 are impacted: they should fail on Linux if compiled with a recent glibc which has getentropy(). |
Aside from a couple of outdated comments and the EPERM question, the attached patch looks good to me. Regarding EPERM, I think it would make sense to make py_getrandom and py_getentropy handle that consistently, otherwise I can see future maintainers readily getting confused by the discrepancy. |
New patch (version 2), much larger: it refactors the code, not only fix this specific issue (prefer getrandom() over getentropy()). Changes since getentropy.patch:
I'm not sure that getentropy() can fail with EPERM or EINTR in practice, but it shouldn't harm to handle correctly these errors :-) At least, getentropy() can fail with these errors on Linux since the glibc implements the getentropy() function using the getrandom() syscall (and it's known that getrandom() can fail with these errors). But on Linux, the code now prefers getrandom() over getentropy(). Should we use the new shiny code on all Python versions? Or only fix the reported issue on all Python issues, and use the refactored code in Python default? Note: Python 2.7 still supports VMS. VMS is unsupported in Python 3.3 and the VMS code was removed in Python 3.4 (bpo-16136): see the PEP-11. I suggest to use the same code on all maintained Python versions to ease maintenance. |
New patch looks good to me, and +1 on applying the refactoring to all supported branches. |
Nick: Thanks for the review! Since random.c is critical for security, I would prefer to have at least a review from another core developer. I added Serhiy and Xiang in the nosy list. I'm also looking at you, Christian! ;-) (Christian reused random.c code in the pycrytography project.) |
I'm doing a review now. By the way I did not copy random.c for cryptography. I took bits and pieces out of it. https://github.com/pyca/cryptography/blob/master/src/_cffi_src/openssl/src/osrandom_engine.c and https://github.com/pyca/cryptography/blob/master/src/_cffi_src/openssl/src/osrandom_engine.h |
LGTM. |
New changeset 140f0459fe80 by Victor Stinner in branch 'default': New changeset 69b23952d122 by Victor Stinner in branch 'default': New changeset 46ca697c6f26 by Victor Stinner in branch 'default': New changeset 4c11a01fa881 by Victor Stinner in branch 'default': New changeset 4edd6cbf9abf by Victor Stinner in branch 'default': |
Thanks Nick and Xiang for the review. I splitted again the giant change into small atomic changes, easier to review and understand. Right now, I only applied the change to default (Python 3.7). I will now wait for buildbots before considering backporting the change. |
New changeset f8e24a0a1124 by Victor Stinner in branch '3.6': |
Christian Heimes: "I'm doing a review now." Follow-up on #python-dev (IRC): <Crys> haypo: yes, I looked at the patch and did not see any obvious problem with it. Didn't I tell you? |
random-py35.patch: Patch for the 3.5 branch. My prepared commit message: Copy and then adapt Python/random.c from default branch. Difference between 3.5
It seems like Python 3.5 is close to a release, I prefer to wait after the release to fix this issue. I don't think that many Linux distributions are affected, since the issue only occurs with glibc 2.24 which is very recent. @larry: Do you want this change in Python 3.5.3? The change is quite large. |
New changeset 8125d9a8152b by Victor Stinner in branch '3.5': |
Ah, I was wrong: 3.5 was already open for the next 3.5.4 release, so I pushed my change. Again, I don't think that supporting the glibc 2.24 in Python 3.5 is a bug important enough to post-pone a release. |
I fixed the bug in Python 2.7, 3.5, 3.6 and 3.7 (default). Thanks for the reviews Nick & Christian! |
Nitpick: here you always state that it's about glibc-2.24 but I'm very confident it only started with 2.25. |
Some vendors backport security features to older glibc. |
Why was there no backporting e.g. to 3.4 branch? I thought you implied that 3.3 and 3.4 are unaffected, but our build farm says otherwise, getting a segfault in bin/python3.4m (3.4.6) and printing "Fatal Python error: getentropy() failed" |
Python 3.3 and 3.4 are in security-fix-only mode. Technically this fix does not count as security fix. It's a compatibility fix. |
Thanks, I see now. From my point of view it is related to security, but I/we will deal with it somehow. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: