diff --git a/backport-Check-if-crypt_method-null-before-dereferencing.patch b/backport-Check-if-crypt_method-null-before-dereferencing.patch new file mode 100644 index 0000000000000000000000000000000000000000..1aa4bcf664bf48c10f024af1a20fde5492bca00e --- /dev/null +++ b/backport-Check-if-crypt_method-null-before-dereferencing.patch @@ -0,0 +1,31 @@ +From b422e3c31691412f0a5404d09f7b328477e23c48 Mon Sep 17 00:00:00 2001 +From: Skyler Ferrante +Date: Tue, 30 May 2023 15:00:12 -0400 +Subject: [PATCH] Check if crypt_method null before dereferencing + +Make sure crypto_method set before sha-rounds. Only affects newusers. +--- + src/newusers.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/newusers.c b/src/newusers.c +index ae2224fc..d6b7c3c3 100644 +--- a/src/newusers.c ++++ b/src/newusers.c +@@ -662,6 +662,13 @@ static void process_flags (int argc, char **argv) + case 's': + sflg = true; + bad_s = 0; ++ ++ if (!crypt_method){ ++ fprintf(stderr, ++ _("%s: Provide '--crypt-method'\n"), ++ Prog); ++ usage (EXIT_FAILURE); ++ } + #if defined(USE_SHA_CRYPT) + if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) + && (0 == getlong(optarg, &sha_rounds)))) { +-- +2.27.0 + diff --git a/backport-Plug-econf-memory-leaks.patch b/backport-Plug-econf-memory-leaks.patch new file mode 100644 index 0000000000000000000000000000000000000000..b12ca1f4042a884c81023aa5ceea323e3915c86e --- /dev/null +++ b/backport-Plug-econf-memory-leaks.patch @@ -0,0 +1,42 @@ +From 8175b1532e4bb1951264e8a6ee5f484137e5306c Mon Sep 17 00:00:00 2001 +From: Tobias Stoeckmann +Date: Thu, 18 May 2023 17:25:35 +0200 +Subject: [PATCH] Plug econf memory leaks + +You can see the memory leaks with address sanitizer if shadow is +compiled with `--enable-vendordir=/usr/etc`. + +How to reproduce: + +1. Prepare a custom shell file as root +``` +mkdir -p /etc/shells.d +echo /bin/myshell > /etc/shells.d/custom +``` + +2. Run chsh as regular user +``` +chsh +``` + +Signed-off-by: Tobias Stoeckmann +--- + lib/getdef.c | 2 ++ + 1 files changed, 2 insertions(+) + +diff --git a/lib/getdef.c b/lib/getdef.c +index a2a7e484..763d847a 100644 +--- a/lib/getdef.c ++++ b/lib/getdef.c +@@ -522,6 +522,8 @@ static void def_load (void) + * syslog. The tools will just use their default values. + */ + (void)putdef_str (keys[i], value); ++ ++ free(value); + } + + econf_free (keys); +-- +2.27.0 + diff --git a/backport-chgpasswd-fix-segfault-in-command-line-options.patch b/backport-chgpasswd-fix-segfault-in-command-line-options.patch new file mode 100644 index 0000000000000000000000000000000000000000..4c9359edfebb024ac6204f23ac4dc552efb3631d --- /dev/null +++ b/backport-chgpasswd-fix-segfault-in-command-line-options.patch @@ -0,0 +1,36 @@ +From 53a17c1742a4b5fcf9280fd6dd85fc77588535c2 Mon Sep 17 00:00:00 2001 +From: Jeffrey Bencteux +Date: Wed, 21 Jun 2023 15:12:43 +0200 +Subject: [PATCH] chgpasswd: fix segfault in command-line options + +Using the --sha-rounds option without first giving a crypt method via the --crypt-method option results in comparisons with a NULL pointer and thus make chgpasswd segfault: + +$ chgpasswd -s 1 +zsh: segmentation fault chgpasswd -s 1 + +Current patch add a sanity check before these comparisons to ensure there is a defined encryption method. +--- + src/chgpasswd.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/chgpasswd.c b/src/chgpasswd.c +index fe4055d8..7b773e2f 100644 +--- a/src/chgpasswd.c ++++ b/src/chgpasswd.c +@@ -186,6 +186,13 @@ static void process_flags (int argc, char **argv) + case 's': + sflg = true; + bad_s = 0; ++ ++ if (!crypt_method) { ++ fprintf (stderr, ++ _("%s: no crypt method defined\n"), ++ Prog); ++ usage (E_USAGE); ++ } + #if defined(USE_SHA_CRYPT) + if ( ( ((0 == strcmp (crypt_method, "SHA256")) || (0 == strcmp (crypt_method, "SHA512"))) + && (0 == getlong(optarg, &sha_rounds)))) { +-- +2.27.0 + diff --git a/backport-chsh-Verify-that-login-shell-path-is-absolute.patch b/backport-chsh-Verify-that-login-shell-path-is-absolute.patch new file mode 100644 index 0000000000000000000000000000000000000000..8f24d6f0cb26573e12d1a236421b8f3d221072ea --- /dev/null +++ b/backport-chsh-Verify-that-login-shell-path-is-absolute.patch @@ -0,0 +1,31 @@ +From 7321ceaf69a7028a04056e548d861b291634c2d0 Mon Sep 17 00:00:00 2001 +From: Samanta Navarro +Date: Thu, 18 May 2023 11:58:19 +0000 +Subject: [PATCH] chsh: Verify that login shell path is absolute + +The getusershell implementation of musl returns every line within the +/etc/shells file, which even includes comments. Only consider absolute +paths for login shells. + +Signed-off-by: Samanta Navarro +--- + src/chsh.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/chsh.c b/src/chsh.c +index 639ff630..d6eca6e3 100644 +--- a/src/chsh.c ++++ b/src/chsh.c +@@ -574,7 +574,8 @@ int main (int argc, char **argv) + fail_exit (1); + } + if ( !amroot +- && ( is_restricted_shell (loginsh) ++ && ( loginsh[0] != '/' ++ || is_restricted_shell (loginsh) + || (access (loginsh, X_OK) != 0))) { + fprintf (stderr, _("%s: %s is an invalid shell\n"), Prog, loginsh); + fail_exit (1); +-- +2.27.0 + diff --git a/backport-def_load-avoid-NULL-deref.patch b/backport-def_load-avoid-NULL-deref.patch new file mode 100644 index 0000000000000000000000000000000000000000..7fd2ecb07fddb939aab57f100e21f0e407a696c9 --- /dev/null +++ b/backport-def_load-avoid-NULL-deref.patch @@ -0,0 +1,35 @@ +From 419cf1f1c4721829c4d68c9e5fee112a5da5890f Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Fri, 19 May 2023 14:49:04 -0500 +Subject: [PATCH] def_load: avoid NULL deref + +If econf_getStringValue() fails, it will return an error and +set value to NULL. Look for the error and avoid dereferencing +value in that case. + +Signed-off-by: Serge Hallyn +--- + lib/getdef.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/lib/getdef.c b/lib/getdef.c +index 39cd62d5..8075821b 100644 +--- a/lib/getdef.c ++++ b/lib/getdef.c +@@ -505,7 +505,12 @@ static void def_load (void) + for (size_t i = 0; i < key_number; i++) { + char *value; + +- econf_getStringValue(defs_file, NULL, keys[i], &value); ++ error = econf_getStringValue(defs_file, NULL, keys[i], &value); ++ if (error) { ++ SYSLOG ((LOG_CRIT, "failed reading key %zu from econf [%s]", ++ i, econf_errString(error))); ++ exit (EXIT_FAILURE); ++ } + + /* + * Store the value in def_table. +-- +2.27.0 + diff --git a/backport-gpasswd-1-Fix-password-leak.patch b/backport-gpasswd-1-Fix-password-leak.patch new file mode 100644 index 0000000000000000000000000000000000000000..a2d5158f00b6889f677573e687c1397222250728 --- /dev/null +++ b/backport-gpasswd-1-Fix-password-leak.patch @@ -0,0 +1,142 @@ +From 65c88a43a23c2391dcc90c0abda3e839e9c57904 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Sat, 10 Jun 2023 16:20:05 +0200 +Subject: [PATCH] gpasswd(1): Fix password leak + +How to trigger this password leak? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When gpasswd(1) asks for the new password, it asks twice (as is usual +for confirming the new password). Each of those 2 password prompts +uses agetpass() to get the password. If the second agetpass() fails, +the first password, which has been copied into the 'static' buffer +'pass' via STRFCPY(), wasn't being zeroed. + +agetpass() is defined in <./libmisc/agetpass.c> (around line 91), and +can fail for any of the following reasons: + +- malloc(3) or readpassphrase(3) failure. + + These are going to be difficult to trigger. Maybe getting the system + to the limits of memory utilization at that exact point, so that the + next malloc(3) gets ENOMEM, and possibly even the OOM is triggered. + About readpassphrase(3), ENFILE and EINTR seem the only plausible + ones, and EINTR probably requires privilege or being the same user; + but I wouldn't discard ENFILE so easily, if a process starts opening + files. + +- The password is longer than PASS_MAX. + + The is plausible with physical access. However, at that point, a + keylogger will be a much simpler attack. + +And, the attacker must be able to know when the second password is being +introduced, which is not going to be easy. + +How to read the password after the leak? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Provoking the leak yourself at the right point by entering a very long +password is easy, and inspecting the process stack at that point should +be doable. Try to find some consistent patterns. + +Then, search for those patterns in free memory, right after the victim +leaks their password. + +Once you get the leak, a program should read all the free memory +searching for patterns that gpasswd(1) leaves nearby the leaked +password. + +On 6/10/23 03:14, Seth Arnold wrote: +> An attacker process wouldn't be able to use malloc(3) for this task. +> There's a handful of tools available for userspace to allocate memory: +> +> - brk / sbrk +> - mmap MAP_ANONYMOUS +> - mmap /dev/zero +> - mmap some other file +> - shm_open +> - shmget +> +> Most of these return only pages of zeros to a process. Using mmap of an +> existing file, you can get some of the contents of the file demand-loaded +> into the memory space on the first use. +> +> The MAP_UNINITIALIZED flag only works if the kernel was compiled with +> CONFIG_MMAP_ALLOW_UNINITIALIZED. This is rare. +> +> malloc(3) doesn't zero memory, to our collective frustration, but all the +> garbage in the allocations is from previous allocations in the current +> process. It isn't leftover from other processes. +> +> The avenues available for reading the memory: +> - /dev/mem and /dev/kmem (requires root, not available with Secure Boot) +> - /proc/pid/mem (requires ptrace privileges, mediated by YAMA) +> - ptrace (requires ptrace privileges, mediated by YAMA) +> - causing memory to be swapped to disk, and then inspecting the swap +> +> These all require a certain amount of privileges. + +How to fix it? +~~~~~~~~~~~~~~ + +memzero(), which internally calls explicit_bzero(3), or whatever +alternative the system provides with a slightly different name, will +make sure that the buffer is zeroed in memory, and optimizations are not +allowed to impede this zeroing. + +This is not really 100% effective, since compilers may place copies of +the string somewhere hidden in the stack. Those copies won't get zeroed +by explicit_bzero(3). However, that's arguably a compiler bug, since +compilers should make everything possible to avoid optimizing strings +that are later passed to explicit_bzero(3). But we all know that +sometimes it's impossible to have perfect knowledge in the compiler, so +this is plausible. Nevertheless, there's nothing we can do against such +issues, except minimizing the time such passwords are stored in plain +text. + +Security concerns +~~~~~~~~~~~~~~~~~ + +We believe this isn't easy to exploit. Nevertheless, and since the fix +is trivial, this fix should probably be applied soon, and backported to +all supported distributions, to prevent someone else having more +imagination than us to find a way. + +Affected versions +~~~~~~~~~~~~~~~~~ + +All. Bug introduced in shadow 19990709. That's the second commit in +the git history. + +Fixes: 45c6603cc86c ("[svn-upgrade] Integrating new upstream version, shadow (19990709)") +Reported-by: Alejandro Colomar +Cc: Serge Hallyn +Cc: Iker Pedrosa +Cc: Seth Arnold +Cc: Christian Brauner +Cc: Balint Reczey +Cc: Sam James +Cc: David Runge +Cc: Andreas Jaeger +Cc: <~hallyn/shadow@lists.sr.ht> +Signed-off-by: Alejandro Colomar +--- + src/gpasswd.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/gpasswd.c b/src/gpasswd.c +index 609fe0a4..3b76ff8e 100644 +--- a/src/gpasswd.c ++++ b/src/gpasswd.c +@@ -898,6 +898,7 @@ static void change_passwd (struct group *gr) + strzero (cp); + cp = getpass (_("Re-enter new password: ")); + if (NULL == cp) { ++ memzero (pass, sizeof pass); + exit (1); + } + +-- +2.27.0 + diff --git a/backport-process_prefix_flag-Drop-privileges.patch b/backport-process_prefix_flag-Drop-privileges.patch new file mode 100644 index 0000000000000000000000000000000000000000..2d5d672866640265ae33045cc9e958cd56948aa8 --- /dev/null +++ b/backport-process_prefix_flag-Drop-privileges.patch @@ -0,0 +1,40 @@ +From 812f934e77700afedbf5e929b282f29a47b2d9c6 Mon Sep 17 00:00:00 2001 +From: Samanta Navarro +Date: Thu, 18 May 2023 11:56:17 +0000 +Subject: [PATCH] process_prefix_flag: Drop privileges + +Using --prefix in a setuid binary is quite dangerous. An unprivileged +user could prepare a custom shadow file in home directory. During a data +race the user could exchange directories with links which could lead to +exchange of shadow file in system's /etc directory. + +This could be used for local privilege escalation. + +Signed-off-by: Samanta Navarro +--- + libmisc/prefix_flag.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/libmisc/prefix_flag.c b/libmisc/prefix_flag.c +index 56243f2e..d7acb9ca 100644 +--- a/libmisc/prefix_flag.c ++++ b/libmisc/prefix_flag.c +@@ -85,6 +85,15 @@ extern const char* process_prefix_flag (const char* short_opt, int argc, char ** + + + if (prefix != NULL) { ++ /* Drop privileges */ ++ if ( (setregid (getgid (), getgid ()) != 0) ++ || (setreuid (getuid (), getuid ()) != 0)) { ++ fprintf (shadow_logfd, ++ _("%s: failed to drop privileges (%s)\n"), ++ Prog, strerror (errno)); ++ exit (EXIT_FAILURE); ++ } ++ + if ( prefix[0] == '\0' || !strcmp(prefix, "/")) + return ""; /* if prefix is "/" then we ignore the flag option */ + /* should we prevent symbolic link from being used as a prefix? */ +-- +2.27.0 + diff --git a/backport-usermod-fix-off-by-one-issues.patch b/backport-usermod-fix-off-by-one-issues.patch new file mode 100644 index 0000000000000000000000000000000000000000..51f94186f845b18568c34f8e54ca28ad16a4a63c --- /dev/null +++ b/backport-usermod-fix-off-by-one-issues.patch @@ -0,0 +1,39 @@ +From 7a2b302e68a4f3e324b851c7361e40aa20a86a64 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Thu, 2 Mar 2023 16:18:45 +0100 +Subject: [PATCH] usermod: fix off-by-one issues + +Allocate enough memory for the strings, two slashes and the NUL +terminator. + +Reported-by: Alejandro Colomar +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 77d4ef49..db5d37a4 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -2048,7 +2048,7 @@ static void move_mailbox (void) + if (NULL == maildir) { + return; + } +- len = strlen (prefix) + strlen (maildir) + strlen (user_name) + 2; ++ len = strlen (prefix) + strlen (maildir) + strlen (user_name) + 3; + mailfile = alloca (len); + + /* +@@ -2103,7 +2103,7 @@ static void move_mailbox (void) + (void) close (fd); + + if (lflg) { +- len = strlen (prefix) + strlen (maildir) + strlen (user_newname) + 2; ++ len = strlen (prefix) + strlen (maildir) + strlen (user_newname) + 3; + newmailfile = alloca(len); + if (prefix[0]) { + (void) snprintf (newmailfile, len, "%s/%s/%s", +-- +2.27.0 + diff --git a/shadow.spec b/shadow.spec index cdb7428bd5d822e25fde557f54413db0364be1f1..a614cb2d831cdd11d3d20a67960ab4f0f973a9b3 100644 --- a/shadow.spec +++ b/shadow.spec @@ -1,6 +1,6 @@ Name: shadow Version: 4.9 -Release: 11 +Release: 12 Epoch: 2 License: BSD and GPLv2+ Summary: Tools for managing accounts and shadow password files @@ -59,6 +59,14 @@ Patch39: backport-Read-whole-line-in-yes_or_no.patch Patch40: backport-commonio-free-removed-database-entries.patch Patch41: backport-semanage-disconnect-to-free-libsemanage-internals.patch Patch42: shadow-Remove-encrypted-passwd-for-useradd-gr.patch +Patch43: backport-process_prefix_flag-Drop-privileges.patch +Patch44: backport-chsh-Verify-that-login-shell-path-is-absolute.patch +Patch45: backport-Plug-econf-memory-leaks.patch +Patch46: backport-def_load-avoid-NULL-deref.patch +Patch47: backport-Check-if-crypt_method-null-before-dereferencing.patch +Patch48: backport-usermod-fix-off-by-one-issues.patch +Patch49: backport-gpasswd-1-Fix-password-leak.patch +Patch50: backport-chgpasswd-fix-segfault-in-command-line-options.patch BuildRequires: gcc, libselinux-devel, audit-libs-devel, libsemanage-devel BuildRequires: libacl-devel, libattr-devel @@ -225,6 +233,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_mandir}/*/* %changelog +* Thu Aug 22 2023 wangyunjia - 2:4.9-12 +- backport patches from upstream + * Fri Aug 15 2023 xiongshenglan - 2:4.9-11 - Remove encrypted passwd for useradd-groupadd-groupmod-usermod