Skip to content

gh-153400: Use kernel-provided __NR_getrandom syscall number - #155762

Open
jjhelmus wants to merge 1 commit into
python:mainfrom
jjhelmus:getrandom_use_NR
Open

gh-153400: Use kernel-provided __NR_getrandom syscall number#155762
jjhelmus wants to merge 1 commit into
python:mainfrom
jjhelmus:getrandom_use_NR

Conversation

@jjhelmus

@jjhelmus jjhelmus commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Replace libc's SYS_getrandom with the kernel-provided __NR_getrandom in configure checks, os.getrandom(), and interpreter entropy handling.

This aligns with other syscall usage in the POSIX module.

This makes os.getrandom() available when building against an older glibc that was itself built with kernel headers lacking the syscall, provided the current kernel headers define __NR_getrandom. This type of build is done in python-build-standalone, astral-sh/python-build-standalone#1188.

Replace libc's SYS_getrandom with the kernel-provided __NR_getrandom
in configure checks, os.getrandom(), and interpreter entropy handling.
@aisk

aisk commented Aug 14, 2026

Copy link
Copy Markdown
Member

Hi, I think this is not a trivial change, so the related issue is required.

@picnixz picnixz changed the title Use kernel-provided __NR_getrandom syscall number gh-153400: Use kernel-provided __NR_getrandom syscall number Aug 14, 2026
@picnixz

picnixz commented Aug 14, 2026

Copy link
Copy Markdown
Member

We changed to use the glibc-provided one in #155518 so I'm nt sure this change is needed anymore but maybe there is a world where neither glibc getrandom() exists nor SYS_getrandom in which case we need to fall back to __NR_getrandom.

cc @vstinner

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the commit message, you can document that __NR_getrandom comes from Linux kernel <unistd.h>, whereas SYS_getrandom comes from glibc <sys/syscall.h>.

Comment thread Python/bootstrap_hash.c
# endif
# if !defined(HAVE_GETRANDOM) && defined(HAVE_GETRANDOM_SYSCALL)
# include <sys/syscall.h> // SYS_getrandom
# include <sys/syscall.h> // __NR_getrandom

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This include should be removed, __NR_getrandom comes from <unistd.h> which is already included above.

__NR_getrandom comes the kernel header files, like /usr/include/asm/unistd_64.h on my Fedora 44. <sys/syscall.h> is the glibc header file which provides SYS_getrandom constant, but this change replace __NR_getrandom with SYS_getrandom.

Comment thread configure.ac
[
AC_LANG_SOURCE([[
#include <stddef.h>
#include <unistd.h>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include <unistd.h> // __NR_getrandom

Comment thread configure.ac
AC_LANG_SOURCE([[
#include <stddef.h>
#include <unistd.h>
#include <sys/syscall.h>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since SYS_getrandom is no longer used, <sys/syscall.h> include can be removed, no?

Comment thread configure.ac
#include <stddef.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/random.h>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include <linux/random.h> // GRND_NONBLOCK

@vstinner

Copy link
Copy Markdown
Member

I don't know how Solaris, FreeBSD and OpenBSD expose their syscall numberes: __NR_getrandom or SYS_getrandom? The PR should be tested on these systems before being merged.

@jjhelmus

Copy link
Copy Markdown
Contributor Author

We changed to use the glibc-provided one in #155518 so I'm nt sure this change is needed anymore but maybe there is a world where neither glibc getrandom() exists nor SYS_getrandom in which case we need to fall back to __NR_getrandom.

This is exactly the case that python-build-standalone is running into on x86-64. The target is glibc 2.17 which does not included getrandom and the Debian package providing it is built against a a kernel that does not include SYS_getrandom. The build uses a modern UAPI kernel heads so __NR_getrandom is available.

@vstinner

Copy link
Copy Markdown
Member

This makes os.getrandom() available when building against an older glibc that was itself built with kernel headers lacking the syscall, provided the current kernel headers define __NR_getrandom.

Do you mean that glibc 2.17 doesn't provide SYS_getrandom macro?

@vstinner

Copy link
Copy Markdown
Member

This is exactly the case that python-build-standalone is running into on x86-64. The target is glibc 2.17 which does not included getrandom and the Debian package providing it is built against a a kernel that does not include SYS_getrandom. The build uses a modern UAPI kernel heads so __NR_getrandom is available.

Which Linux kernel version are you used to build Python?

@jjhelmus

jjhelmus commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

Do you mean that glibc 2.17 doesn't provide SYS_getrandom macro?

Often not, glibc 2.17 was released in 2012. The the getrandom syscall was added to the kernel in 2014 with 3.17.
glibc generates syscall aliases from the kernel headers available when it is build, so if built against <3.17, the SYS_getrandom macro will not be included.

The specifics for python-build-standalone are glibc 2.19 build against kernel 3.16. So no getrandom function nor SYS_getrandom macro. Modern 7.0 UAPI kernel headers are used in the build so __NR_getrandom is available.

Note that the glib 2.17 packages in RHEL 9 and derivates likely include the macro because the syscall list was updated to include calls from the 5.4 kernel.

@vstinner

Copy link
Copy Markdown
Member

Modern 7.0 UAPI kernel headers are used in the build so __NR_getrandom is available.

I don't know "UAPI kernel headers". How do they work?

@picnixz

picnixz commented Aug 14, 2026

Copy link
Copy Markdown
Member

If we want to maximize compatibility I think we should rather check for both SYS_* and __NR_* macros then. Since we're anyway worrying about exotic platforms, we may even have the lack of __NR_* macro and getrandom() syscall and only the SYS_* macro.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants