From 123860270fff5c57e31ae8727d433c1ebf82e015 Mon Sep 17 00:00:00 2001 From: dongyuzhen Date: Tue, 17 Dec 2024 16:16:28 +0800 Subject: [PATCH] fix CVE-2024-10041 (cherry picked from commit 26371643ba0dff0c2f97e2a96c4bca1b8583bfec) --- ...-try-to-set-uid-to-0-for-unix_chkpwd.patch | 79 +++++++++++++++ backport-CVE-2024-10041.patch | 95 +++++++++++++++++++ pam.spec | 7 +- 3 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2024-10041-pam_unix-try-to-set-uid-to-0-for-unix_chkpwd.patch create mode 100644 backport-CVE-2024-10041.patch diff --git a/backport-CVE-2024-10041-pam_unix-try-to-set-uid-to-0-for-unix_chkpwd.patch b/backport-CVE-2024-10041-pam_unix-try-to-set-uid-to-0-for-unix_chkpwd.patch new file mode 100644 index 0000000..761e8a7 --- /dev/null +++ b/backport-CVE-2024-10041-pam_unix-try-to-set-uid-to-0-for-unix_chkpwd.patch @@ -0,0 +1,79 @@ +From b7b96362087414e52524d3d9d9b3faa21e1db620 Mon Sep 17 00:00:00 2001 +From: Tobias Stoeckmann +Date: Wed, 24 Jan 2024 18:57:42 +0100 +Subject: [PATCH] pam_unix: try to set uid to 0 for unix_chkpwd + +The geteuid check does not cover all cases. If a program runs with +elevated capabilities like CAP_SETUID then we can still check +credentials of other users. + +Keep logging for future analysis though. + +Resolves: https://github.com/linux-pam/linux-pam/issues/747 +Fixes: b3020da7da38 ("pam_unix/passverify: always run the helper to obtain shadow password file entries") + +Signed-off-by: Tobias Stoeckmann + +Conflict:NA +Reference:https://github.com/linux-pam/linux-pam/commit/b7b96362087414e52524d3d9d9b3faa21e1db620 +--- + modules/pam_unix/pam_unix_acct.c | 17 +++++++++-------- + modules/pam_unix/support.c | 14 +++++++------- + 2 files changed, 16 insertions(+), 15 deletions(-) + +diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c +index 8f5ed3e..7ffcb9e 100644 +--- a/modules/pam_unix/pam_unix_acct.c ++++ b/modules/pam_unix/pam_unix_acct.c +@@ -110,14 +110,15 @@ int _unix_run_verify_binary(pam_handle_t *pamh, unsigned long long ctrl, + _exit(PAM_AUTHINFO_UNAVAIL); + } + +- if (geteuid() == 0) { +- /* must set the real uid to 0 so the helper will not error +- out if pam is called from setuid binary (su, sudo...) */ +- if (setuid(0) == -1) { +- pam_syslog(pamh, LOG_ERR, "setuid failed: %m"); +- printf("-1\n"); +- fflush(stdout); +- _exit(PAM_AUTHINFO_UNAVAIL); ++ /* must set the real uid to 0 so the helper will not error ++ out if pam is called from setuid binary (su, sudo...) */ ++ if (setuid(0) == -1) { ++ uid_t euid = geteuid(); ++ pam_syslog(pamh, euid == 0 ? LOG_ERR : LOG_DEBUG, "setuid failed: %m"); ++ if (euid == 0) { ++ printf("-1\n"); ++ fflush(stdout); ++ _exit(PAM_AUTHINFO_UNAVAIL); + } + } + +diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c +index 7b62c14..a5c5d77 100644 +--- a/modules/pam_unix/support.c ++++ b/modules/pam_unix/support.c +@@ -513,13 +513,13 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, + _exit(PAM_AUTHINFO_UNAVAIL); + } + +- if (geteuid() == 0) { +- /* must set the real uid to 0 so the helper will not error +- out if pam is called from setuid binary (su, sudo...) */ +- if (setuid(0) == -1) { +- D(("setuid failed")); +- _exit(PAM_AUTHINFO_UNAVAIL); +- } ++ /* must set the real uid to 0 so the helper will not error ++ out if pam is called from setuid binary (su, sudo...) */ ++ if (setuid(0) == -1) { ++ D(("setuid failed")); ++ if (geteuid() == 0) { ++ _exit(PAM_AUTHINFO_UNAVAIL); ++ } + } + + /* exec binary helper */ +-- +2.46.0 + diff --git a/backport-CVE-2024-10041.patch b/backport-CVE-2024-10041.patch new file mode 100644 index 0000000..36b3f5a --- /dev/null +++ b/backport-CVE-2024-10041.patch @@ -0,0 +1,95 @@ +From b3020da7da384d769f27a8713257fbe1001878be Mon Sep 17 00:00:00 2001 +From: "Dmitry V. Levin" +Date: Mon, 1 Jan 2024 12:00:00 +0000 +Subject: [PATCH] pam_unix/passverify: always run the helper to obtain shadow + password file entries + +Initially, when pam_unix.so verified the password, it used to try to +obtain the shadow password file entry for the given user by invoking +getspnam(3), and only when that didn't work and the effective uid +was nonzero, pam_unix.so used to invoke the helper as a fallback. + +When SELinux support was introduced by commit +67aab1ff5515054341a438cf9804e9c9b3a88033, the fallback was extended +also for the case when SELinux was enabled. + +Later, commit f220cace205332a3dc34e7b37a85e7627e097e7d extended the +fallback conditions for the case when pam_modutil_getspnam() failed +with EACCES. + +Since commit 470823c4aacef5cb3b1180be6ed70846b61a3752, the helper is +invoked as a fallback when pam_modutil_getspnam() fails for any reason. + +The ultimate solution for the case when pam_unix.so does not have +permissions to obtain the shadow password file entry is to stop trying +to use pam_modutil_getspnam() and to invoke the helper instead. +Here are two recent examples. + +https://github.com/linux-pam/linux-pam/pull/484 describes a system +configuration where libnss_systemd is enabled along with libnss_files +in the shadow entry of nsswitch.conf, so when libnss_files is unable +to obtain the shadow password file entry for the root user, e.g. when +SELinux is enabled, NSS falls back to libnss_systemd which returns +a synthesized shadow password file entry for the root user, which +in turn locks the root user out. + +https://bugzilla.redhat.com/show_bug.cgi?id=2150155 describes +essentially the same problem in a similar system configuration. + +This commit is the final step in the direction of addressing the issue: +for password verification pam_unix.so now invokes the helper instead of +making the pam_modutil_getspnam() call. + +* modules/pam_unix/passverify.c (get_account_info) [!HELPER_COMPILE]: +Always return PAM_UNIX_RUN_HELPER instead of trying to obtain +the shadow password file entry. + +Complements: https://github.com/linux-pam/linux-pam/pull/386 +Resolves: https://github.com/linux-pam/linux-pam/pull/484 +Link: https://github.com/authselect/authselect/commit/1e78f7e048747024a846fd22d68afc6993734e92 + +Conflict:NA +Reference:https://github.com/linux-pam/linux-pam/commit/b3020da7da384d769f27a8713257fbe1001878be +--- + modules/pam_unix/passverify.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c +index a54785d..009e99c 100644 +--- a/modules/pam_unix/passverify.c ++++ b/modules/pam_unix/passverify.c +@@ -237,20 +237,21 @@ PAMH_ARG_DECL(int get_account_info, + return PAM_UNIX_RUN_HELPER; + #endif + } else if (is_pwd_shadowed(*pwd)) { ++#ifdef HELPER_COMPILE + /* +- * ...and shadow password file entry for this user, ++ * shadow password file entry for this user, + * if shadowing is enabled + */ +- *spwdent = pam_modutil_getspnam(pamh, name); +- if (*spwdent == NULL) { +-#ifndef HELPER_COMPILE +- /* still a chance the user can authenticate */ +- return PAM_UNIX_RUN_HELPER; +-#endif +- return PAM_AUTHINFO_UNAVAIL; +- } +- if ((*spwdent)->sp_pwdp == NULL) ++ *spwdent = getspnam(name); ++ if (*spwdent == NULL || (*spwdent)->sp_pwdp == NULL) + return PAM_AUTHINFO_UNAVAIL; ++#else ++ /* ++ * The helper has to be invoked to deal with ++ * the shadow password file entry. ++ */ ++ return PAM_UNIX_RUN_HELPER; ++#endif + } + } else { + return PAM_USER_UNKNOWN; +-- +2.46.0 + diff --git a/pam.spec b/pam.spec index aaa9174..55dc2a7 100644 --- a/pam.spec +++ b/pam.spec @@ -4,7 +4,7 @@ %define _pamconfdir %{_sysconfdir}/pam.d Name: pam Version: 1.5.2 -Release: 9 +Release: 10 Summary: Pluggable Authentication Modules for Linux License: BSD and GPLv2+ URL: http://www.linux-pam.org/ @@ -25,6 +25,8 @@ Patch2: backport-CVE-2024-22365-pam_namespace-protect_dir-use-O_DIRECTORY-to-pre Patch3: backport-pam_access-handle-hostnames-in-access.conf.patch Patch4: backport-pam_access-make-non-resolveable-hostname-a-debug-out.patch Patch5: backport-CVE-2024-10963.patch +Patch6: backport-CVE-2024-10041.patch +Patch7: backport-CVE-2024-10041-pam_unix-try-to-set-uid-to-0-for-unix_chkpwd.patch Patch9000:change-ndbm-to-gdbm.patch Patch9001:add-sm3-crypt-support.patch @@ -178,6 +180,9 @@ make check %changelog +* Tue Dec 17 2024 dongyuzhen - 1.5.2-10 +- fix CVE-2024-10041 + * Thu Nov 28 2024 hugel - 1.5.2-9 - fix CVE-2024-10963 -- Gitee