From 100975d1ce6d9bbfef0720c1cb3a4fc0bc7f8b78 Mon Sep 17 00:00:00 2001 From: yunjia_w Date: Mon, 19 Jun 2023 15:44:03 +0800 Subject: [PATCH] backport some patches Signed-off-by: yunjia_w --- backport-Read-whole-line-in-yes_or_no.patch | 67 +++++++++ ...mmonio-free-removed-database-entries.patch | 39 ++++++ ...-run_parts-for-groupadd-and-groupdel.patch | 127 ++++++++++++++++++ ...onnect-to-free-libsemanage-internals.patch | 76 +++++++++++ shadow.spec | 9 +- 5 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 backport-Read-whole-line-in-yes_or_no.patch create mode 100644 backport-commonio-free-removed-database-entries.patch create mode 100644 backport-run_parts-for-groupadd-and-groupdel.patch create mode 100644 backport-semanage-disconnect-to-free-libsemanage-internals.patch diff --git a/backport-Read-whole-line-in-yes_or_no.patch b/backport-Read-whole-line-in-yes_or_no.patch new file mode 100644 index 0000000..c70a8b8 --- /dev/null +++ b/backport-Read-whole-line-in-yes_or_no.patch @@ -0,0 +1,67 @@ +From 0c83b981053b65c9bab4f1c2e60d004e920f8faf Mon Sep 17 00:00:00 2001 +From: Samanta Navarro +Date: Fri, 27 Jan 2023 11:53:57 +0000 +Subject: [PATCH] Read whole line in yes_or_no + +Do not stop after 79 characters. Read the complete line to avoid +arbitrary limitations. + +Proof of Concept: + +``` +cat > passwd-poc << EOF +root:x:0:0:root:/root:/bin/bash +root:x:0:0:root:/root:/bin/bash +root:x:0:0:root:/root:/bin/bash +EOF +python -c "print(80*'y')" | pwck passwd-poc +``` + +Two lines should still be within the file because we agreed only once +to remove a duplicated line. + +Signed-off-by: Samanta Navarro +Reviewed-by: Alejandro Colomar +Reviewed-by: Serge Hallyn + +Conflict: NA +Reference: https://github.com/shadow-maint/shadow/commit/0c83b981053b65c9bab4f1c2e60d004e920f8faf +--- + libmisc/yesno.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/libmisc/yesno.c b/libmisc/yesno.c +index 1a1a3714..d8847e40 100644 +--- a/libmisc/yesno.c ++++ b/libmisc/yesno.c +@@ -28,7 +28,8 @@ + */ + bool yes_or_no (bool read_only) + { +- char buf[80]; ++ int c; ++ bool result; + + /* + * In read-only mode all questions are answered "no". +@@ -46,11 +47,13 @@ bool yes_or_no (bool read_only) + /* + * Get a line and see what the first character is. + */ ++ c = fgetc(stdin); + /* TODO: use gettext */ +- if (fgets (buf, (int) sizeof buf, stdin) == buf) { +- return buf[0] == 'y' || buf[0] == 'Y'; +- } ++ result = (c == 'y' || c == 'Y'); ++ ++ while (c != '\n' && c != EOF) ++ c = fgetc(stdin); + +- return false; ++ return result; + } + +-- +2.27.0 + diff --git a/backport-commonio-free-removed-database-entries.patch b/backport-commonio-free-removed-database-entries.patch new file mode 100644 index 0000000..13322f7 --- /dev/null +++ b/backport-commonio-free-removed-database-entries.patch @@ -0,0 +1,39 @@ +From a8dd8ce6c9a5f6e69ed4e9fa7b0c0976bb4ba332 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Sat, 1 Apr 2023 13:36:51 +0200 +Subject: [PATCH] commonio: free removed database entries + +Free the actual struct of the removed entry. + +Example userdel report: + + Direct leak of 40 byte(s) in 1 object(s) allocated from: + #0 0x55b230efe857 in reallocarray (./src/userdel+0xda857) + #1 0x55b230f6041f in mallocarray ./lib/./alloc.h:97:9 + #2 0x55b230f6041f in commonio_open ./lib/commonio.c:563:7 + #3 0x55b230f39098 in open_files ./src/userdel.c:555:6 + #4 0x55b230f39098 in main ./src/userdel.c:1189:2 + #5 0x7f9b48c64189 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16 + +Conflict: NA +Reference: https://github.com/shadow-maint/shadow/commit/a8dd8ce6c9a5f6e69ed4e9fa7b0c0976bb4ba332 +--- + lib/commonio.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/lib/commonio.c b/lib/commonio.c +index 40e62298..a0449c83 100644 +--- a/lib/commonio.c ++++ b/lib/commonio.c +@@ -1060,6 +1060,8 @@ int commonio_remove (struct commonio_db *db, const char *name) + db->ops->free (p->eptr); + } + ++ free(p); ++ + return 1; + } + +-- +2.27.0 + diff --git a/backport-run_parts-for-groupadd-and-groupdel.patch b/backport-run_parts-for-groupadd-and-groupdel.patch new file mode 100644 index 0000000..43c175b --- /dev/null +++ b/backport-run_parts-for-groupadd-and-groupdel.patch @@ -0,0 +1,127 @@ +From 4e1f674c41724dd96ad2c3a0c02ac9f6666697ba Mon Sep 17 00:00:00 2001 +From: ed neville +Date: Mon, 27 Mar 2023 20:23:03 +0100 +Subject: [PATCH] run_parts for groupadd and groupdel + +run_parts currently exists in useradd and userdel, this commit mirrors +the functionality with groupadd and groupdel + +Hook for group{add,del} to include killing processes that have group +membership that would no longer exist to avoid membership ID reuse. + +Conflict: NA +Reference: https://github.com/shadow-maint/shadow/commit/4e1f674c41724dd96ad2c3a0c02ac9f6666697ba +--- + .../groupdel-pre.d/01-kill_group_procs.sh | 26 +++++++++++++++++++ + src/groupadd.c | 11 ++++++++ + src/groupdel.c | 11 ++++++++ + 3 files changed, 48 insertions(+) + create mode 100644 etc/shadow-maint/groupdel-pre.d/01-kill_group_procs.sh + +diff --git a/etc/shadow-maint/groupdel-pre.d/01-kill_group_procs.sh b/etc/shadow-maint/groupdel-pre.d/01-kill_group_procs.sh +new file mode 100644 +index 00000000..10db5279 +--- /dev/null ++++ b/etc/shadow-maint/groupdel-pre.d/01-kill_group_procs.sh +@@ -0,0 +1,26 @@ ++#!/bin/sh ++ ++PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ++GROUPID=`awk -F: '$1 == "'"${SUBJECT}"'" { print $3 }' /etc/group` ++ ++if [ "${GROUPID}" = "" ]; then ++ exit 0 ++fi ++ ++for status in /proc/*/status; do ++ # either this isn't a process or its already dead since expanding the list ++ [ -f "$status" ] || continue ++ ++ tbuf=${status%/status} ++ pid=${tbuf#/proc/} ++ case "$pid" in ++ "$$") continue;; ++ [0-9]*) :;; ++ *) continue ++ esac ++ ++ grep -q '^Groups:.*\b'"${GROUPID}"'\b.*' "/proc/$pid/status" || continue ++ ++ kill -9 "$pid" || echo "cannot kill $pid" 1>&2 ++done ++ +diff --git a/src/groupadd.c b/src/groupadd.c +index 31142101..2eda1c68 100644 +--- a/src/groupadd.c ++++ b/src/groupadd.c +@@ -34,6 +34,7 @@ + #include "sgroupio.h" + #endif + #include "shadowlog.h" ++#include "run_part.h" + + /* + * exit status values +@@ -603,6 +604,11 @@ int main (int argc, char **argv) + + check_perms (); + ++ if (run_parts ("/etc/shadow-maint/groupadd-pre.d", group_name, ++ "groupadd")) { ++ exit(1); ++ } ++ + #ifdef SHADOWGRP + is_shadow_grp = sgr_file_present (); + #endif +@@ -621,6 +627,11 @@ int main (int argc, char **argv) + + grp_update (); + close_files (); ++ if (run_parts ("/etc/shadow-maint/groupadd-post.d", group_name, ++ "groupadd")) { ++ exit(1); ++ } ++ + + nscd_flush_cache ("group"); + sssd_flush_cache (SSSD_DB_GROUP); +diff --git a/src/groupdel.c b/src/groupdel.c +index fdccf5e1..bae4367b 100644 +--- a/src/groupdel.c ++++ b/src/groupdel.c +@@ -32,6 +32,7 @@ + #include "sgroupio.h" + #endif + #include "shadowlog.h" ++#include "run_part.h" + /* + * Global variables + */ +@@ -461,6 +462,11 @@ int main (int argc, char **argv) + group_busy (group_id); + } + ++ if (run_parts ("/etc/shadow-maint/groupdel-pre.d", group_name, ++ "groupdel")) { ++ exit(1); ++ } ++ + /* + * Do the hard stuff - open the files, delete the group entries, + * then close and update the files. +@@ -471,6 +477,11 @@ int main (int argc, char **argv) + + close_files (); + ++ if (run_parts ("/etc/shadow-maint/groupdel-post.d", group_name, ++ "groupdel")) { ++ exit(1); ++ } ++ + nscd_flush_cache ("group"); + sssd_flush_cache (SSSD_DB_GROUP); + +-- +2.27.0 + diff --git a/backport-semanage-disconnect-to-free-libsemanage-internals.patch b/backport-semanage-disconnect-to-free-libsemanage-internals.patch new file mode 100644 index 0000000..94a0722 --- /dev/null +++ b/backport-semanage-disconnect-to-free-libsemanage-internals.patch @@ -0,0 +1,76 @@ +From 7078ed1e0b8a197aa9e5103986bce927abef87a4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Sat, 1 Apr 2023 14:11:06 +0200 +Subject: [PATCH] semanage: disconnect to free libsemanage internals + +Destroying the handle does not actually disconnect, see [1]. +Also free the key on user removal. + +[1]: https://github.com/SELinuxProject/selinux/blob/e9072e7d45f4559887d11b518099135cbe564163/libsemanage/src/direct_api.c#L330 + +Example adduser leak: + + Direct leak of 1008 byte(s) in 14 object(s) allocated from: + #0 0x5638f2e782ae in __interceptor_malloc (./src/useradd+0xee2ae) + #1 0x7fb5cfffad09 in dbase_file_init src/database_file.c:170:45 + + Direct leak of 392 byte(s) in 7 object(s) allocated from: + #0 0x5638f2e782ae in __interceptor_malloc (./src/useradd+0xee2ae) + #1 0x7fb5cfffc929 in dbase_policydb_init src/database_policydb.c:187:27 + + Direct leak of 144 byte(s) in 2 object(s) allocated from: + #0 0x5638f2e782ae in __interceptor_malloc (./src/useradd+0xee2ae) + #1 0x7fb5cfffb519 in dbase_join_init src/database_join.c:249:28 + + [...] + +Conflict: NA +Reference: https://github.com/shadow-maint/shadow/commit/7078ed1e0b8a197aa9e5103986bce927abef87a4 +--- + lib/semanage.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/lib/semanage.c b/lib/semanage.c +index 5d336b08..d412186c 100644 +--- a/lib/semanage.c ++++ b/lib/semanage.c +@@ -97,6 +97,8 @@ static semanage_handle_t *semanage_init (void) + return handle; + + fail: ++ if (handle) ++ semanage_disconnect (handle); + semanage_handle_destroy (handle); + return NULL; + } +@@ -156,7 +158,7 @@ done: + + + static int semanage_user_add (semanage_handle_t *handle, +- semanage_seuser_key_t *key, ++ const semanage_seuser_key_t *key, + const char *login_name, + const char *seuser_name) + { +@@ -279,6 +281,8 @@ int set_seuser (const char *login_name, const char *seuser_name) + + done: + semanage_seuser_key_free (key); ++ if (handle) ++ semanage_disconnect (handle); + semanage_handle_destroy (handle); + return ret; + } +@@ -353,6 +357,9 @@ int del_seuser (const char *login_name) + + ret = 0; + done: ++ semanage_seuser_key_free (key); ++ if (handle) ++ semanage_disconnect (handle); + semanage_handle_destroy (handle); + return ret; + } +-- +2.27.0 + diff --git a/shadow.spec b/shadow.spec index e448a63..5a952d0 100644 --- a/shadow.spec +++ b/shadow.spec @@ -1,6 +1,6 @@ Name: shadow Version: 4.13 -Release: 4 +Release: 5 Epoch: 2 License: BSD and GPLv2+ Summary: Tools for managing accounts and shadow password files @@ -26,6 +26,10 @@ Patch6: backport-Explicitly-override-only-newlines.patch Patch7: backport-Prevent-out-of-boundary-access.patch Patch8: backport-Added-control-character-check.patch Patch9: backport-Overhaul-valid_field.patch +Patch10: backport-Read-whole-line-in-yes_or_no.patch +Patch11: backport-commonio-free-removed-database-entries.patch +Patch12: backport-semanage-disconnect-to-free-libsemanage-internals.patch +Patch13: backport-run_parts-for-groupadd-and-groupdel.patch BuildRequires: gcc, libselinux-devel, audit-libs-devel, libsemanage-devel BuildRequires: libacl-devel, libattr-devel @@ -193,6 +197,9 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.{la,a} %{_mandir}/*/* %changelog +* Mon Jun 19 2023 yunjia_w - 2:4.13-5 +- backport patches from upstream + * Thu Apr 20 2023 yunjia_w - 2:4.13-4 - fix CVE-2023-29383