From 33e83df4c31ddcb788729d2ed420ac9b6685c1e0 Mon Sep 17 00:00:00 2001 From: Duane Griffin Date: Wed, 4 Jun 2025 05:28:58 +1200 Subject: [PATCH 1/2] [3.13] gh-127081: use `getlogin_r` if available (gh-132751) The `getlogin` function is not thread-safe: replace with `getlogin_r` where available. (cherry picked from commit 1ffe913c2017b44804aca18befd45689df06c069) Co-authored-by: Duane Griffin --- ...-04-21-01-03-15.gh-issue-127081.WXRliX.rst | 2 ++ Modules/posixmodule.c | 18 ++++++++++ configure | 33 +++++++++++++++++++ configure.ac | 14 +++++++- pyconfig.h.in | 13 ++++++++ 5 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2025-04-21-01-03-15.gh-issue-127081.WXRliX.rst diff --git a/Misc/NEWS.d/next/Library/2025-04-21-01-03-15.gh-issue-127081.WXRliX.rst b/Misc/NEWS.d/next/Library/2025-04-21-01-03-15.gh-issue-127081.WXRliX.rst new file mode 100644 index 00000000000000..63fed60ced03c5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-04-21-01-03-15.gh-issue-127081.WXRliX.rst @@ -0,0 +1,2 @@ +Fix libc thread safety issues with :mod:`os` by replacing ``getlogin`` with +``getlogin_r`` re-entrant version. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 601145e561d136..8d5139887b1d0a 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -9464,6 +9464,24 @@ os_getlogin_impl(PyObject *module) } else result = PyErr_SetFromWindowsErr(GetLastError()); +#elif defined (HAVE_GETLOGIN_R) +# if defined (HAVE_MAXLOGNAME) + char name[MAXLOGNAME + 1]; +# elif defined (HAVE_UT_NAMESIZE) + char name[UT_NAMESIZE + 1]; +# else + char name[256]; +# endif + int err = getlogin_r(name, sizeof(name)); + if (err) { + int old_errno = errno; + errno = -err; + posix_error(); + errno = old_errno; + } + else { + result = PyUnicode_DecodeFSDefault(name); + } #else char *name; int old_errno = errno; diff --git a/configure b/configure index 1cd1f690f7b9c1..87d4d90e541a96 100755 --- a/configure +++ b/configure @@ -18180,6 +18180,12 @@ if test "x$ac_cv_func_getlogin" = xyes then : printf "%s\n" "#define HAVE_GETLOGIN 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getlogin_r" "ac_cv_func_getlogin_r" +if test "x$ac_cv_func_getlogin_r" = xyes +then : + printf "%s\n" "#define HAVE_GETLOGIN_R 1" >>confdefs.h + fi ac_fn_c_check_func "$LINENO" "getpeername" "ac_cv_func_getpeername" if test "x$ac_cv_func_getpeername" = xyes @@ -21887,6 +21893,33 @@ fi +ac_fn_check_decl "$LINENO" "MAXLOGNAME" "ac_cv_have_decl_MAXLOGNAME" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_MAXLOGNAME" = xyes +then : + +printf "%s\n" "#define HAVE_MAXLOGNAME 1" >>confdefs.h + +fi + +ac_fn_check_decl "$LINENO" "UT_NAMESIZE" "ac_cv_have_decl_UT_NAMESIZE" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_UT_NAMESIZE" = xyes +then : + ac_have_decl=1 +else case e in #( + e) ac_have_decl=0 ;; +esac +fi +printf "%s\n" "#define HAVE_DECL_UT_NAMESIZE $ac_have_decl" >>confdefs.h +if test $ac_have_decl = 1 +then : + +printf "%s\n" "#define HAVE_UT_NAMESIZE 1" >>confdefs.h + +fi + + # check for openpty, login_tty, and forkpty diff --git a/configure.ac b/configure.ac index 3fcb18922c5330..2a037569e492b2 100644 --- a/configure.ac +++ b/configure.ac @@ -5116,7 +5116,7 @@ AC_CHECK_FUNCS([ \ faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \ fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \ gai_strerror getegid geteuid getgid getgrent getgrgid getgrgid_r \ - getgrnam_r getgrouplist gethostname getitimer getloadavg getlogin \ + getgrnam_r getgrouplist gethostname getitimer getloadavg getlogin getlogin_r \ getpeername getpgid getpid getppid getpriority _getpty \ getpwent getpwnam_r getpwuid getpwuid_r getresgid getresuid getrusage getsid getspent \ getspnam getuid getwd grantpt if_nameindex initgroups kill killpg lchown linkat \ @@ -5400,6 +5400,18 @@ PY_CHECK_FUNC([setgroups], [ #endif ]) +AC_CHECK_DECL([MAXLOGNAME], + [AC_DEFINE([HAVE_MAXLOGNAME], [1], + [Define if you have the 'MAXLOGNAME' constant.])], + [], + [@%:@include ]) + +AC_CHECK_DECLS([UT_NAMESIZE], + [AC_DEFINE([HAVE_UT_NAMESIZE], [1], + [Define if you have the 'HAVE_UT_NAMESIZE' constant.])], + [], + [@%:@include ]) + # check for openpty, login_tty, and forkpty AC_CHECK_FUNCS([openpty], [], diff --git a/pyconfig.h.in b/pyconfig.h.in index 3c16c694c84599..842fe81d41eed5 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -258,6 +258,10 @@ */ #undef HAVE_DECL_TZNAME +/* Define to 1 if you have the declaration of 'UT_NAMESIZE', and to 0 if you + don't. */ +#undef HAVE_DECL_UT_NAMESIZE + /* Define to 1 if you have the device macros. */ #undef HAVE_DEVICE_MACROS @@ -521,6 +525,9 @@ /* Define to 1 if you have the `getlogin' function. */ #undef HAVE_GETLOGIN +/* Define to 1 if you have the 'getlogin_r' function. */ +#undef HAVE_GETLOGIN_R + /* Define to 1 if you have the `getnameinfo' function. */ #undef HAVE_GETNAMEINFO @@ -786,6 +793,9 @@ /* Define this if you have the makedev macro. */ #undef HAVE_MAKEDEV +/* Define if you have the 'MAXLOGNAME' constant. */ +#undef HAVE_MAXLOGNAME + /* Define to 1 if you have the `mbrtowc' function. */ #undef HAVE_MBRTOWC @@ -1539,6 +1549,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UTMP_H +/* Define if you have the 'HAVE_UT_NAMESIZE' constant. */ +#undef HAVE_UT_NAMESIZE + /* Define to 1 if you have the `uuid_create' function. */ #undef HAVE_UUID_CREATE From 4fc5ef0252356d800435698d9245091ce58a03cb Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 3 Jun 2025 17:50:31 +0000 Subject: [PATCH 2/2] make regen-configure --- configure | 5 ++--- pyconfig.h.in | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/configure b/configure index 87d4d90e541a96..519caa8ca741f4 100755 --- a/configure +++ b/configure @@ -21907,9 +21907,8 @@ ac_fn_check_decl "$LINENO" "UT_NAMESIZE" "ac_cv_have_decl_UT_NAMESIZE" "#include if test "x$ac_cv_have_decl_UT_NAMESIZE" = xyes then : ac_have_decl=1 -else case e in #( - e) ac_have_decl=0 ;; -esac +else $as_nop + ac_have_decl=0 fi printf "%s\n" "#define HAVE_DECL_UT_NAMESIZE $ac_have_decl" >>confdefs.h if test $ac_have_decl = 1 diff --git a/pyconfig.h.in b/pyconfig.h.in index 842fe81d41eed5..a698453dc924bc 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -258,7 +258,7 @@ */ #undef HAVE_DECL_TZNAME -/* Define to 1 if you have the declaration of 'UT_NAMESIZE', and to 0 if you +/* Define to 1 if you have the declaration of `UT_NAMESIZE', and to 0 if you don't. */ #undef HAVE_DECL_UT_NAMESIZE @@ -525,7 +525,7 @@ /* Define to 1 if you have the `getlogin' function. */ #undef HAVE_GETLOGIN -/* Define to 1 if you have the 'getlogin_r' function. */ +/* Define to 1 if you have the `getlogin_r' function. */ #undef HAVE_GETLOGIN_R /* Define to 1 if you have the `getnameinfo' function. */