diff --git a/SOURCES/shadow-4.6-gpasswd-fix-password-leak.patch b/SOURCES/shadow-4.6-gpasswd-fix-password-leak.patch new file mode 100644 index 0000000..61bf8c0 --- /dev/null +++ b/SOURCES/shadow-4.6-gpasswd-fix-password-leak.patch @@ -0,0 +1,11 @@ +diff -up shadow-4.9/src/gpasswd.c.gpasswd-fix-password-leak shadow-4.9/src/gpasswd.c +--- shadow-4.9/src/gpasswd.c.gpasswd-fix-password-leak 2023-07-12 09:38:32.062546006 +0200 ++++ shadow-4.9/src/gpasswd.c 2023-07-12 09:42:33.194154548 +0200 +@@ -857,6 +857,7 @@ static void change_passwd (struct group + strzero (cp); + cp = getpass (_("Re-enter new password: ")); + if (NULL == cp) { ++ memzero (pass, sizeof pass); + exit (1); + } + diff --git a/SOURCES/shadow-4.3.1-selinux-perms.patch b/SOURCES/shadow-4.6-selinux-perms.patch similarity index 85% rename from SOURCES/shadow-4.3.1-selinux-perms.patch rename to SOURCES/shadow-4.6-selinux-perms.patch index 8550150..977f3c9 100644 --- a/SOURCES/shadow-4.3.1-selinux-perms.patch +++ b/SOURCES/shadow-4.6-selinux-perms.patch @@ -1,7 +1,6 @@ -Index: shadow-4.5/src/chgpasswd.c -=================================================================== ---- shadow-4.5.orig/src/chgpasswd.c -+++ shadow-4.5/src/chgpasswd.c +diff -up shadow-4.8/src/chgpasswd.c.selinux-perms shadow-4.8/src/chgpasswd.c +--- shadow-4.8/src/chgpasswd.c.selinux-perms 2019-12-01 18:02:43.000000000 +0100 ++++ shadow-4.8/src/chgpasswd.c 2020-01-13 10:21:44.558107260 +0100 @@ -39,6 +39,13 @@ #include #include @@ -16,7 +15,7 @@ Index: shadow-4.5/src/chgpasswd.c #ifdef ACCT_TOOLS_SETUID #ifdef USE_PAM #include "pam_defs.h" -@@ -76,6 +83,9 @@ static bool sgr_locked = false; +@@ -80,6 +87,9 @@ static bool sgr_locked = false; #endif static bool gr_locked = false; @@ -26,7 +25,7 @@ Index: shadow-4.5/src/chgpasswd.c /* local function prototypes */ static void fail_exit (int code); static /*@noreturn@*/void usage (int status); -@@ -300,6 +310,63 @@ static void check_perms (void) +@@ -334,6 +344,63 @@ static void check_perms (void) #endif /* ACCT_TOOLS_SETUID */ } @@ -90,7 +89,7 @@ Index: shadow-4.5/src/chgpasswd.c /* * open_files - lock and open the group databases */ -@@ -393,6 +460,7 @@ int main (int argc, char **argv) +@@ -427,6 +494,7 @@ int main (int argc, char **argv) const struct group *gr; struct group newgr; @@ -98,7 +97,17 @@ Index: shadow-4.5/src/chgpasswd.c int errors = 0; int line = 0; -@@ -408,8 +476,33 @@ int main (int argc, char **argv) +@@ -436,12 +504,37 @@ int main (int argc, char **argv) + (void) bindtextdomain (PACKAGE, LOCALEDIR); + (void) textdomain (PACKAGE); + ++#ifdef WITH_SELINUX ++ selinux_check_root (); ++#endif ++ + process_root_flag ("-R", argc, argv); + + process_flags (argc, argv); OPENLOG ("chgpasswd"); @@ -125,13 +134,7 @@ Index: shadow-4.5/src/chgpasswd.c + check_perms (); -+#ifdef WITH_SELINUX -+ selinux_check_root (); -+#endif -+ #ifdef SHADOWGRP - is_shadow_grp = sgr_file_present (); - #endif @@ -536,6 +629,15 @@ int main (int argc, char **argv) newgr.gr_passwd = cp; } @@ -148,10 +151,9 @@ Index: shadow-4.5/src/chgpasswd.c /* * The updated group file entry is then put back and will * be written to the group file later, after all the -Index: shadow-4.5/src/chpasswd.c -=================================================================== ---- shadow-4.5.orig/src/chpasswd.c -+++ shadow-4.5/src/chpasswd.c +diff -up shadow-4.8/src/chpasswd.c.selinux-perms shadow-4.8/src/chpasswd.c +--- shadow-4.8/src/chpasswd.c.selinux-perms 2019-12-01 18:02:43.000000000 +0100 ++++ shadow-4.8/src/chpasswd.c 2020-01-13 10:21:44.558107260 +0100 @@ -39,6 +39,13 @@ #include #include @@ -166,7 +168,7 @@ Index: shadow-4.5/src/chpasswd.c #ifdef USE_PAM #include "pam_defs.h" #endif /* USE_PAM */ -@@ -297,6 +304,63 @@ static void check_perms (void) +@@ -332,6 +339,63 @@ static void check_perms (void) #endif /* USE_PAM */ } @@ -230,7 +232,18 @@ Index: shadow-4.5/src/chpasswd.c /* * open_files - lock and open the password databases */ -@@ -405,8 +469,16 @@ int main (int argc, char **argv) +@@ -428,6 +492,10 @@ int main (int argc, char **argv) + (void) bindtextdomain (PACKAGE, LOCALEDIR); + (void) textdomain (PACKAGE); + ++#ifdef WITH_SELINUX ++ selinux_check_root (); ++#endif ++ + process_root_flag ("-R", argc, argv); + + process_flags (argc, argv); +@@ -440,6 +508,10 @@ int main (int argc, char **argv) OPENLOG ("chpasswd"); @@ -240,13 +253,7 @@ Index: shadow-4.5/src/chpasswd.c + check_perms (); -+#ifdef WITH_SELINUX -+ selinux_check_root (); -+#endif -+ #ifdef USE_PAM - if (!use_pam) - #endif /* USE_PAM */ @@ -566,6 +638,11 @@ int main (int argc, char **argv) newpw.pw_passwd = cp; } diff --git a/SOURCES/shadow-4.6-skip-over-reserved-ids.patch b/SOURCES/shadow-4.6-skip-over-reserved-ids.patch new file mode 100644 index 0000000..efce55a --- /dev/null +++ b/SOURCES/shadow-4.6-skip-over-reserved-ids.patch @@ -0,0 +1,214 @@ +From baae5b4a06c905d9f52ed1f922a0d7d0625d11cf Mon Sep 17 00:00:00 2001 +From: Martin Kletzander +Date: Wed, 1 Feb 2023 15:36:41 +0100 +Subject: [PATCH] find_new_[gu]id(): Skip over IDs that are reserved for legacy + reasons + +Some programs don't support `(uint16_t) -1` or `(uint32_t) -1` as user +or group IDs. This is because `-1` is used as an error code or as an +unspecified ID, e.g. in `chown(2)` parameters, and in the past, `gid_t` +and `uid_t` have changed width. For legacy reasons, those values have +been kept reserved in programs today (for example systemd does this; see +the documentation in the link below). + +This should not be confused with catching overflow in the ID values, +since that is already caught by our ERANGE checks. This is about not +using reserved values that have been reserved for legacy reasons. + +Link: +Reviewed-by: Alejandro Colomar +Signed-off-by: Martin Kletzander +--- + libmisc/find_new_gid.c | 38 ++++++++++++++++++++++++++++---------- + libmisc/find_new_uid.c | 38 ++++++++++++++++++++++++++++---------- + 2 files changed, 56 insertions(+), 20 deletions(-) + +diff --git a/libmisc/find_new_gid.c b/libmisc/find_new_gid.c +index 70ba95a2..da1d8d55 100644 +--- a/libmisc/find_new_gid.c ++++ b/libmisc/find_new_gid.c +@@ -98,6 +98,7 @@ static int get_ranges (bool sys_group, gid_t *min_id, gid_t *max_id, + * + * On success, return 0 + * If the ID is in use, return EEXIST ++ * If the ID might clash with -1, return EINVAL + * If the ID is outside the range, return ERANGE + * In other cases, return errno from getgrgid() + */ +@@ -111,6 +112,11 @@ static int check_gid (const gid_t gid, + return ERANGE; + } + ++ /* Check for compatibility with 16b and 32b gid_t error codes */ ++ if (gid == UINT16_MAX || gid == UINT32_MAX) { ++ return EINVAL; ++ } ++ + /* + * Check whether we already detected this GID + * using the gr_next() loop +@@ -182,10 +188,10 @@ int find_new_gid (bool sys_group, + * gr_locate_gid() found the GID in an as-yet uncommitted + * entry. We'll proceed below and auto-set a GID. + */ +- } else if (result == EEXIST || result == ERANGE) { ++ } else if (result == EEXIST || result == ERANGE || result == EINVAL) { + /* + * Continue on below. At this time, we won't +- * treat these two cases differently. ++ * treat these three cases differently. + */ + } else { + /* +@@ -296,8 +302,11 @@ int find_new_gid (bool sys_group, + *gid = id; + free (used_gids); + return 0; +- } else if (result == EEXIST) { +- /* This GID is in use, we'll continue to the next */ ++ } else if (result == EEXIST || result == EINVAL) { ++ /* ++ * This GID is in use or unusable, we'll ++ * continue to the next. ++ */ + } else { + /* + * An unexpected error occurred. +@@ -339,8 +348,11 @@ int find_new_gid (bool sys_group, + *gid = id; + free (used_gids); + return 0; +- } else if (result == EEXIST) { +- /* This GID is in use, we'll continue to the next */ ++ } else if (result == EEXIST || result == EINVAL) { ++ /* ++ * This GID is in use or unusable, we'll ++ * continue to the next. ++ */ + } else { + /* + * An unexpected error occurred. +@@ -399,8 +411,11 @@ int find_new_gid (bool sys_group, + *gid = id; + free (used_gids); + return 0; +- } else if (result == EEXIST) { +- /* This GID is in use, we'll continue to the next */ ++ } else if (result == EEXIST || result == EINVAL) { ++ /* ++ * This GID is in use or unusable, we'll ++ * continue to the next. ++ */ + } else { + /* + * An unexpected error occurred. +@@ -442,8 +457,11 @@ int find_new_gid (bool sys_group, + *gid = id; + free (used_gids); + return 0; +- } else if (result == EEXIST) { +- /* This GID is in use, we'll continue to the next */ ++ } else if (result == EEXIST || result == EINVAL) { ++ /* ++ * This GID is in use or unusable, we'll ++ * continue to the next. ++ */ + } else { + /* + * An unexpected error occurred. +diff --git a/libmisc/find_new_uid.c b/libmisc/find_new_uid.c +index 6b71dfe5..09885236 100644 +--- a/libmisc/find_new_uid.c ++++ b/libmisc/find_new_uid.c +@@ -98,6 +98,7 @@ static int get_ranges (bool sys_user, uid_t *min_id, uid_t *max_id, + * + * On success, return 0 + * If the ID is in use, return EEXIST ++ * If the ID might clash with -1, return EINVAL + * If the ID is outside the range, return ERANGE + * In other cases, return errno from getpwuid() + */ +@@ -111,6 +112,11 @@ static int check_uid(const uid_t uid, + return ERANGE; + } + ++ /* Check for compatibility with 16b and 32b uid_t error codes */ ++ if (uid == UINT16_MAX || uid == UINT32_MAX) { ++ return EINVAL; ++ } ++ + /* + * Check whether we already detected this UID + * using the pw_next() loop +@@ -182,10 +188,10 @@ int find_new_uid(bool sys_user, + * pw_locate_uid() found the UID in an as-yet uncommitted + * entry. We'll proceed below and auto-set an UID. + */ +- } else if (result == EEXIST || result == ERANGE) { ++ } else if (result == EEXIST || result == ERANGE || result == EINVAL) { + /* + * Continue on below. At this time, we won't +- * treat these two cases differently. ++ * treat these three cases differently. + */ + } else { + /* +@@ -296,8 +302,11 @@ int find_new_uid(bool sys_user, + *uid = id; + free (used_uids); + return 0; +- } else if (result == EEXIST) { +- /* This UID is in use, we'll continue to the next */ ++ } else if (result == EEXIST || result == EINVAL) { ++ /* ++ * This GID is in use or unusable, we'll ++ * continue to the next. ++ */ + } else { + /* + * An unexpected error occurred. +@@ -339,8 +348,11 @@ int find_new_uid(bool sys_user, + *uid = id; + free (used_uids); + return 0; +- } else if (result == EEXIST) { +- /* This UID is in use, we'll continue to the next */ ++ } else if (result == EEXIST || result == EINVAL) { ++ /* ++ * This GID is in use or unusable, we'll ++ * continue to the next. ++ */ + } else { + /* + * An unexpected error occurred. +@@ -399,8 +411,11 @@ int find_new_uid(bool sys_user, + *uid = id; + free (used_uids); + return 0; +- } else if (result == EEXIST) { +- /* This UID is in use, we'll continue to the next */ ++ } else if (result == EEXIST || result == EINVAL) { ++ /* ++ * This GID is in use or unusable, we'll ++ * continue to the next. ++ */ + } else { + /* + * An unexpected error occurred. +@@ -442,8 +457,11 @@ int find_new_uid(bool sys_user, + *uid = id; + free (used_uids); + return 0; +- } else if (result == EEXIST) { +- /* This UID is in use, we'll continue to the next */ ++ } else if (result == EEXIST || result == EINVAL) { ++ /* ++ * This GID is in use or unusable, we'll ++ * continue to the next. ++ */ + } else { + /* + * An unexpected error occurred. +-- +2.40.1 + diff --git a/SOURCES/shadow-4.6-useradd-check-if-subid-range-exists.patch b/SOURCES/shadow-4.6-useradd-check-if-subid-range-exists.patch new file mode 100644 index 0000000..de44ace --- /dev/null +++ b/SOURCES/shadow-4.6-useradd-check-if-subid-range-exists.patch @@ -0,0 +1,20 @@ +diff -up shadow-4.6/src/useradd.c.useradd-check-if-subid-range-exists shadow-4.6/src/useradd.c +--- shadow-4.6/src/useradd.c.useradd-check-if-subid-range-exists 2023-05-17 10:39:41.457826153 +0200 ++++ shadow-4.6/src/useradd.c 2023-05-17 10:41:30.937036772 +0200 +@@ -2019,14 +2019,14 @@ static void usr_update (void) + fail_exit (E_PW_UPDATE); + } + #ifdef ENABLE_SUBIDS +- if (is_sub_uid && ++ if (is_sub_uid && !local_sub_uid_assigned(user_name) && + (sub_uid_add(user_name, sub_uid_start, sub_uid_count) == 0)) { + fprintf (stderr, + _("%s: failed to prepare the new %s entry\n"), + Prog, sub_uid_dbname ()); + fail_exit (E_SUB_UID_UPDATE); + } +- if (is_sub_gid && ++ if (is_sub_gid && !local_sub_gid_assigned(user_name) && + (sub_gid_add(user_name, sub_gid_start, sub_gid_count) == 0)) { + fprintf (stderr, + _("%s: failed to prepare the new %s entry\n"), diff --git a/SPECS/shadow-utils.spec b/SPECS/shadow-utils.spec index 566ab17..11c1134 100644 --- a/SPECS/shadow-utils.spec +++ b/SPECS/shadow-utils.spec @@ -1,7 +1,7 @@ Summary: Utilities for managing accounts and shadow password files Name: shadow-utils Version: 4.6 -Release: 17%{?dist} +Release: 19%{?dist} Epoch: 2 URL: http://pkg-shadow.alioth.debian.org/ Source0: https://github.com/shadow-maint/shadow/releases/download/v%{version}/shadow-%{version}.tar.xz @@ -29,7 +29,7 @@ Patch21: shadow-4.6-move-home.patch Patch22: shadow-4.6-audit-update.patch Patch23: shadow-4.5-usermod-unlock.patch Patch24: shadow-4.2.1-no-lock-dos.patch -Patch28: shadow-4.3.1-selinux-perms.patch +Patch28: shadow-4.6-selinux-perms.patch Patch29: shadow-4.2.1-null-tm.patch Patch31: shadow-4.6-getenforce.patch Patch32: shadow-4.5-crypt_h.patch @@ -94,6 +94,12 @@ Patch62: shadow-4.6-getsubids.patch Patch63: shadow-4.6-groupdel-fix-sigsegv-when-passwd-does-not-exist.patch # https://github.com/shadow-maint/shadow/commit/3ec32f9975f262073f8fbdecd2bfaee4a1d3db48 Patch64: shadow-4.9-subordinateio-compare-owner-ID.patch +# https://github.com/shadow-maint/shadow/commit/e0524e813a3bae2891b33a66f35876841c11cee7 +Patch65: shadow-4.6-useradd-check-if-subid-range-exists.patch +# https://github.com/shadow-maint/shadow/commit/baae5b4a06c905d9f52ed1f922a0d7d0625d11cf +Patch66: shadow-4.6-skip-over-reserved-ids.patch +# https://github.com/shadow-maint/shadow/commit/65c88a43a23c2391dcc90c0abda3e839e9c57904 +Patch67: shadow-4.6-gpasswd-fix-password-leak.patch License: BSD and GPLv2+ Group: System Environment/Base @@ -194,6 +200,9 @@ Development files for shadow-utils-subid. %patch62 -p1 -b .getsubids %patch63 -p1 -b .groupdel-fix-sigsegv-when-passwd-does-not-exist %patch64 -p1 -b .subordinateio-compare-owner-ID +%patch65 -p1 -b .useradd-check-if-subid-range-exists +%patch66 -p1 -b .skip-over-reserved-ids +%patch67 -p1 -b .gpasswd-fix-password-leak iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 cp -f doc/HOWTO.utf8 doc/HOWTO @@ -364,6 +373,14 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la %{_libdir}/libsubid.so %changelog +* Wed Jul 12 2023 Iker Pedrosa - 2:4.6-19 +- gpasswd: fix password leak. Resolves: #2215947 + +* Wed May 17 2023 Iker Pedrosa - 2:4.6-18 +- Update patch to close label to reset libselinux state. Resolves: #1984740 +- useradd: check if subid range exists for user. Resolves: #2012929 +- find_new_[gu]id: Skip over IDs that are reserved for legacy reasons. Resolves: #1994269 + * Thu Jul 21 2022 Iker Pedrosa - 2:4.6-17 - subordinateio: also compare the owner ID. Resolves: #2093311 - Fix release sources