Open
fix(cve): 修复 CVE-2026-54411 在 pam 中的漏洞 #184
fix(cve): 修复 CVE-2026-54411 在 pam 中的漏洞 #184
Open
infra_teamAdd on Jun 15
Total: 3 files changed+95-1
@@ -0,0 +1,56 @@
1+--- Linux-PAM-1.5.3/libpam/include/pam_inline.h 2023-05-08 07:06:47.000000000 +0800
2++++ /tmp/pam_inline_h.fixed 2026-06-15 02:17:32.954821748 +0800
3+@@ -175,4 +175,53 @@
4+ return i;
5+ }
6+
7++static inline int
8++pam_consttime_streq(const char *userinput, const char *secret) {
9++ volatile const char *u = userinput, *s = secret;
10++ volatile int ret = 0;
11++
12++ do {
13++ ret |= *u ^ *s;
14++
15++ s += !!*s;
16++ } while (*u++ != '\0');
17++
18++ return ret == 0;
19++}
20++
21++/*
22++ * Compare two memory regions in constant time.
23++ * This is useful for comparing non-null-terminated data,
24++ * such as dbm key/value data.
25++ * Returns 1 if equal, 0 otherwise.
26++ */
27++static inline int
28++pam_consttime_memeq(const volatile void *a, const volatile void *b, size_t len) {
29++ volatile int ret = 0;
30++ for (size_t i = 0; i < len; i++) {
31++ ret |= ((const volatile unsigned char *)a)[i] ^ ((const volatile unsigned char *)b)[i];
32++ }
33++ return ret == 0;
34++}
35++
36++/*
37++ * Compare two memory regions in constant time, ignoring case.
38++ * This is useful for comparing non-null-terminated data,
39++ * such as dbm key/value data, in a case-insensitive manner.
40++ * Returns 1 if equal (ignoring case), 0 otherwise.
41++ */
42++static inline int
43++pam_consttime_memeq_icase(const volatile void *a, const volatile void *b, size_t len) {
44++ volatile int ret = 0;
45++ for (size_t i = 0; i < len; i++) {
46++ unsigned char ca = ((const volatile unsigned char *)a)[i];
47++ unsigned char cb = ((const volatile unsigned char *)b)[i];
48++ /* Convert to lowercase for comparison */
49++ ca = (ca >= 'A' && ca <= 'Z') ? (ca - 'A' + 'a') : ca;
50++ cb = (cb >= 'A' && cb <= 'Z') ? (cb - 'A' + 'a') : cb;
51++ ret |= ca ^ cb;
52++ }
53++ return ret == 0;
54++}
55++
56+ #endif /* PAM_INLINE_H */
@@ -0,0 +1,33 @@
1+--- Linux-PAM-1.5.3/modules/pam_userdb/pam_userdb.c 2023-05-08 07:06:47.000000000 +0800
2++++ /tmp/pam_userdb_c.fixed 2026-06-15 02:17:32.957821792 +0800
3+@@ -261,9 +261,9 @@
4+ if (strlen(pass) != (size_t)data.dsize) {
5+ compare = 1; /* wrong password len -> wrong password */
6+ } else if (ctrl & PAM_ICASE_ARG) {
7+- compare = strncasecmp(data.dptr, pass, data.dsize);
8++ compare = pam_consttime_memeq_icase(data.dptr, pass, data.dsize) ? 0 : 1;
9+ } else {
10+- compare = strncmp(data.dptr, pass, data.dsize);
11++ compare = pam_consttime_memeq(data.dptr, pass, data.dsize) ? 0 : 1;
12+ }
13+
14+ if (cryptmode && pam_str_skip_icase_prefix(cryptmode, "none") == NULL
15+@@ -310,14 +310,14 @@
16+ if ((size_t)key.dsize == strlen(user) + 1 + strlen(pass)) {
17+ if (ctrl & PAM_ICASE_ARG) {
18+ /* compare the password portion (case insensitive)*/
19+- compare = strncasecmp(key.dptr + strlen(user) + 1,
20++ compare = pam_consttime_memeq_icase(key.dptr + strlen(user) + 1,
21+ pass,
22+- strlen(pass));
23++ strlen(pass)) ? 0 : 1;
24+ } else {
25+ /* compare the password portion (case sensitive) */
26+- compare = strncmp(key.dptr + strlen(user) + 1,
27++ compare = pam_consttime_memeq(key.dptr + strlen(user) + 1,
28+ pass,
29+- strlen(pass));
30++ strlen(pass)) ? 0 : 1;
31+ }
32+ }
33+ }
@@ -4,7 +4,7 @@
4%define _pamconfdir %{_sysconfdir}/pam.d4%define _pamconfdir %{_sysconfdir}/pam.d
5Name: pam5Name: pam
6Version: 1.5.36Version: 1.5.3
7-Release: 137+Release: 14
8Summary: Pluggable Authentication Modules for Linux8Summary: Pluggable Authentication Modules for Linux
9License: BSD-3-Clause AND GPL-2.0-or-later9License: BSD-3-Clause AND GPL-2.0-or-later
10URL: http://www.linux-pam.org/10URL: http://www.linux-pam.org/
@@ -61,6 +61,8 @@ Patch39: backport-libpam-fix-integer-overflow-when-parsing-configs.patch
61Patch40: backport-libpam-fix-_pam_mkargv-return-value-on-error-path.patch61Patch40: backport-libpam-fix-_pam_mkargv-return-value-on-error-path.patch
62Patch41: backport-Fix-build-if-crypt_r-isn-t-available.patch62Patch41: backport-Fix-build-if-crypt_r-isn-t-available.patch
63Patch42: backport-modules-zero-out-crypt_r-3-data-before-usage.patch63Patch42: backport-modules-zero-out-crypt_r-3-data-before-usage.patch
64+Patch43: backport-CVE-2026-54411-01-pam_inline.h.patch
65+Patch44: backport-CVE-2026-54411-02-pam_userdb.c.patch
64 66 
65Patch9000:change-ndbm-to-gdbm.patch67Patch9000:change-ndbm-to-gdbm.patch
66Patch9001:add-sm3-crypt-support.patch68Patch9001:add-sm3-crypt-support.patch
@@ -200,6 +202,9 @@ rm -fr $RPM_BUILD_ROOT/usr/share/doc/pam
200 202 
201 203 
202%changelog204%changelog
205+* Mon Jun 15 2026 infra_team <zhaiwenjie1@huawei.com> - 1.5.3-14
206+- fix CVE-2026-54411: timing attack vulnerability in pam_userdb password comparison
207+ 
203* Tue Apr 14 2026 hugel <2712504175@qq.com> - 1.5.3-13208* Tue Apr 14 2026 hugel <2712504175@qq.com> - 1.5.3-13
204- backport upstream patches209- backport upstream patches
205 210