From 9ac9ad9e1035a0327c132b16bbbd7b82e1b066bc Mon Sep 17 00:00:00 2001 From: Krzesimir Nowak Date: Tue, 1 Aug 2023 14:29:41 +0200 Subject: [PATCH] sys-apps/shadow: Sync with Gentoo It's from Gentoo commit a6ec9c2a8a13f2dbd82e8768666356beea63f445. --- .../sys-apps/shadow/files/securetty | 33 ----- .../shadow-4.1.3-dots-in-usernames.patch | 10 -- .../files/shadow-4.13-CVE-2023-29383.patch | 100 +++++++++++++ .../files/shadow-4.13-password-leak.patch | 135 ++++++++++++++++++ .../shadow-4.13-usermod-prefix-gid.patch | 33 +++++ .../shadow/files/tmpfiles.d/etc-shadow.conf | 5 - .../shadow/files/tmpfiles.d/var-shadow.conf | 1 - ...w-4.13-r1.ebuild => shadow-4.13-r4.ebuild} | 87 +++++------ 8 files changed, 305 insertions(+), 99 deletions(-) delete mode 100644 sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/securetty delete mode 100644 sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.1.3-dots-in-usernames.patch create mode 100644 sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.13-CVE-2023-29383.patch create mode 100644 sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.13-password-leak.patch create mode 100644 sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.13-usermod-prefix-gid.patch delete mode 100644 sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/tmpfiles.d/etc-shadow.conf delete mode 100644 sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/tmpfiles.d/var-shadow.conf rename sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/{shadow-4.13-r1.ebuild => shadow-4.13-r4.ebuild} (74%) diff --git a/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/securetty b/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/securetty deleted file mode 100644 index c7042fae2c..0000000000 --- a/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/securetty +++ /dev/null @@ -1,33 +0,0 @@ -# /etc/securetty: list of terminals on which root is allowed to login. -# See securetty(5) and login(1). -console - -vc/0 -vc/1 -vc/2 -vc/3 -vc/4 -vc/5 -vc/6 -vc/7 -vc/8 -vc/9 -vc/10 -vc/11 -vc/12 -tty0 -tty1 -tty2 -tty3 -tty4 -tty5 -tty6 -tty7 -tty8 -tty9 -tty10 -tty11 -tty12 - -tts/0 -ttyS0 diff --git a/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.1.3-dots-in-usernames.patch b/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.1.3-dots-in-usernames.patch deleted file mode 100644 index efcb33dbd9..0000000000 --- a/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.1.3-dots-in-usernames.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- shadow-4.1.3/libmisc/chkname.c -+++ shadow-4.1.3/libmisc/chkname.c -@@ -66,6 +66,7 @@ - ( ('0' <= *name) && ('9' >= *name) ) || - ('_' == *name) || - ('-' == *name) || -+ ('.' == *name) || - ( ('$' == *name) && ('\0' == *(name + 1)) ) - )) { - return false; diff --git a/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.13-CVE-2023-29383.patch b/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.13-CVE-2023-29383.patch new file mode 100644 index 0000000000..49868ba67c --- /dev/null +++ b/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.13-CVE-2023-29383.patch @@ -0,0 +1,100 @@ +From e5905c4b84d4fb90aefcd96ee618411ebfac663d Mon Sep 17 00:00:00 2001 +From: tomspiderlabs <128755403+tomspiderlabs@users.noreply.github.com> +Date: Thu, 23 Mar 2023 23:39:38 +0000 +Subject: [PATCH] Added control character check + +Added control character check, returning -1 (to "err") if control characters are present. +--- + lib/fields.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/lib/fields.c b/lib/fields.c +index 640be931f..fb51b5829 100644 +--- a/lib/fields.c ++++ b/lib/fields.c +@@ -21,9 +21,9 @@ + * + * The supplied field is scanned for non-printable and other illegal + * characters. +- * + -1 is returned if an illegal character is present. +- * + 1 is returned if no illegal characters are present, but the field +- * contains a non-printable character. ++ * + -1 is returned if an illegal or control character is present. ++ * + 1 is returned if no illegal or control characters are present, ++ * but the field contains a non-printable character. + * + 0 is returned otherwise. + */ + int valid_field (const char *field, const char *illegal) +@@ -45,10 +45,13 @@ int valid_field (const char *field, const char *illegal) + } + + if (0 == err) { +- /* Search if there are some non-printable characters */ ++ /* Search if there are non-printable or control characters */ + for (cp = field; '\0' != *cp; cp++) { + if (!isprint (*cp)) { + err = 1; ++ } ++ if (!iscntrl (*cp)) { ++ err = -1; + break; + } + } +From 2eaea70111f65b16d55998386e4ceb4273c19eb4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= +Date: Fri, 31 Mar 2023 14:46:50 +0200 +Subject: [PATCH] Overhaul valid_field() + +e5905c4b ("Added control character check") introduced checking for +control characters but had the logic inverted, so it rejects all +characters that are not control ones. + +Cast the character to `unsigned char` before passing to the character +checking functions to avoid UB. + +Use strpbrk(3) for the illegal character test and return early. +--- + lib/fields.c | 24 ++++++++++-------------- + 1 file changed, 10 insertions(+), 14 deletions(-) + +diff --git a/lib/fields.c b/lib/fields.c +index fb51b5829..539292485 100644 +--- a/lib/fields.c ++++ b/lib/fields.c +@@ -37,26 +37,22 @@ int valid_field (const char *field, const char *illegal) + + /* For each character of field, search if it appears in the list + * of illegal characters. */ ++ if (illegal && NULL != strpbrk (field, illegal)) { ++ return -1; ++ } ++ ++ /* Search if there are non-printable or control characters */ + for (cp = field; '\0' != *cp; cp++) { +- if (strchr (illegal, *cp) != NULL) { ++ unsigned char c = *cp; ++ if (!isprint (c)) { ++ err = 1; ++ } ++ if (iscntrl (c)) { + err = -1; + break; + } + } + +- if (0 == err) { +- /* Search if there are non-printable or control characters */ +- for (cp = field; '\0' != *cp; cp++) { +- if (!isprint (*cp)) { +- err = 1; +- } +- if (!iscntrl (*cp)) { +- err = -1; +- break; +- } +- } +- } +- + return err; + } + diff --git a/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.13-password-leak.patch b/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.13-password-leak.patch new file mode 100644 index 0000000000..25b5ec39c5 --- /dev/null +++ b/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.13-password-leak.patch @@ -0,0 +1,135 @@ +https://github.com/shadow-maint/shadow/commit/65c88a43a23c2391dcc90c0abda3e839e9c57904 + +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 +--- a/src/gpasswd.c ++++ b/src/gpasswd.c +@@ -898,6 +898,7 @@ static void change_passwd (struct group *gr) + erase_pass (cp); + cp = agetpass (_("Re-enter new password: ")); + if (NULL == cp) { ++ memzero (pass, sizeof pass); + exit (1); + } + diff --git a/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.13-usermod-prefix-gid.patch b/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.13-usermod-prefix-gid.patch new file mode 100644 index 0000000000..50cbe699d1 --- /dev/null +++ b/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/shadow-4.13-usermod-prefix-gid.patch @@ -0,0 +1,33 @@ +https://bugs.gentoo.org/903083 +https://github.com/shadow-maint/shadow/pull/691 +https://github.com/shadow-maint/shadow/commit/bd2d0079c90241f24671a7946a3ad175dc1a3aeb + +From fcb04de38a0ddc263288a1c450b35bfb1503d523 Mon Sep 17 00:00:00 2001 +From: Mike Gilbert +Date: Sat, 25 Mar 2023 21:16:55 -0400 +Subject: [PATCH] usermod: respect --prefix for --gid option + +The --gid option accepts a group name or id. When a name is provided, it +is resolved to an id by looking up the name in the group database +(/etc/group). + +The --prefix option overides the location of the passwd and group +databases. I suspect the --gid option was overlooked when wiring up the +--prefix option. + +useradd --gid already respects --prefix; this change makes usermod +behave the same way. + +Fixes: b6b2c756c91806b1c3e150ea0ee4721c6cdaf9d0 +Signed-off-by: Mike Gilbert +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -1072,7 +1072,7 @@ static void process_flags (int argc, char **argv) + fflg = true; + break; + case 'g': +- grp = getgr_nam_gid (optarg); ++ grp = prefix_getgr_nam_gid (optarg); + if (NULL == grp) { + fprintf (stderr, + _("%s: group '%s' does not exist\n"), diff --git a/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/tmpfiles.d/etc-shadow.conf b/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/tmpfiles.d/etc-shadow.conf deleted file mode 100644 index 0acaf6838a..0000000000 --- a/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/tmpfiles.d/etc-shadow.conf +++ /dev/null @@ -1,5 +0,0 @@ -L /etc/login.defs - - - - ../usr/share/shadow/login.defs -L /etc/securetty - - - - ../usr/share/shadow/securetty - -d /etc/default - - - - - -L /etc/default/useradd - - - - ../../usr/share/shadow/useradd diff --git a/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/tmpfiles.d/var-shadow.conf b/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/tmpfiles.d/var-shadow.conf deleted file mode 100644 index 612187d6ae..0000000000 --- a/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/files/tmpfiles.d/var-shadow.conf +++ /dev/null @@ -1 +0,0 @@ -f /var/log/faillog - - - - - diff --git a/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/shadow-4.13-r1.ebuild b/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/shadow-4.13-r4.ebuild similarity index 74% rename from sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/shadow-4.13-r1.ebuild rename to sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/shadow-4.13-r4.ebuild index 682625ab58..0316a96320 100644 --- a/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/shadow-4.13-r1.ebuild +++ b/sdk_container/src/third_party/coreos-overlay/sys-apps/shadow/shadow-4.13-r4.ebuild @@ -7,11 +7,8 @@ EAPI=8 # official. Don't keyword the pre-releases! # Check https://github.com/shadow-maint/shadow/releases. -# Flatcar: -TMPFILES_OPTIONAL=1 VERIFY_SIG_OPENPGP_KEY_PATH="${BROOT}"/usr/share/openpgp-keys/sergehallyn.asc -# Flatcar: install systemd units and tmpfiles -inherit libtool pam verify-sig systemd tmpfiles +inherit libtool pam verify-sig DESCRIPTION="Utilities to deal with user accounts" HOMEPAGE="https://github.com/shadow-maint/shadow" @@ -21,7 +18,7 @@ SRC_URI+=" verify-sig? ( https://github.com/shadow-maint/shadow/releases/downloa LICENSE="BSD GPL-2" # Subslot is for libsubid's SONAME. SLOT="0/4" -KEYWORDS="~alpha amd64 arm arm64 ~hppa ~ia64 ~loong ~m68k ~mips ppc ppc64 ~riscv ~s390 sparc x86" +KEYWORDS="~alpha amd64 ~arm arm64 hppa ~ia64 ~loong ~m68k ~mips ~ppc ppc64 ~riscv ~s390 ~sparc ~x86" IUSE="acl audit bcrypt cracklib nls pam selinux skey split-usr su xattr" # Taken from the man/Makefile.am file. LANGS=( cs da de es fi fr hu id it ja ko pl pt_BR ru sv tr zh_CN zh_TW ) @@ -30,22 +27,24 @@ REQUIRED_USE="?? ( cracklib pam )" COMMON_DEPEND=" virtual/libcrypt:= - acl? ( sys-apps/acl:0= ) - audit? ( >=sys-process/audit-2.6:0= ) - cracklib? ( >=sys-libs/cracklib-2.7-r3:0= ) + acl? ( sys-apps/acl:= ) + audit? ( >=sys-process/audit-2.6:= ) + cracklib? ( >=sys-libs/cracklib-2.7-r3:= ) nls? ( virtual/libintl ) - pam? ( sys-libs/pam:0= ) - skey? ( sys-auth/skey:0= ) + pam? ( sys-libs/pam:= ) + skey? ( sys-auth/skey:= ) selinux? ( - >=sys-libs/libselinux-1.28:0= - sys-libs/libsemanage:0= + >=sys-libs/libselinux-1.28:= + sys-libs/libsemanage:= ) - xattr? ( sys-apps/attr:0= ) + xattr? ( sys-apps/attr:= ) " -DEPEND="${COMMON_DEPEND} +DEPEND=" + ${COMMON_DEPEND} >=sys-kernel/linux-headers-4.14 " -RDEPEND="${COMMON_DEPEND} +RDEPEND=" + ${COMMON_DEPEND} !/s:^:#:" \ - "${ED}"/usr/share/shadow/login.defs || die + "${ED}"/etc/login.defs || die else sed -i -r \ -e "/^#?${opt}\>/s:.*:${opt} ${val}:" \ - "${ED}"/usr/share/shadow/login.defs + "${ED}"/etc/login.defs fi - local res=$(grep "^${comment}${opt}\>" "${ED}"/usr/share/shadow/login.defs) - einfo "${res:-Unable to find ${opt} in /usr/share/shadow/login.defs}" + local res=$(grep "^${comment}${opt}\>" "${ED}"/etc/login.defs) + einfo "${res:-Unable to find ${opt} in /etc/login.defs}" } src_install() { @@ -129,43 +130,29 @@ src_install() { find "${ED}" -name '*.la' -type f -delete || die - # Flatcar: - # Remove files from /etc, they will be symlinks to /usr instead. - rm -f "${ED}"/etc/{limits,login.access,login.defs,securetty,default/useradd} - - # CoreOS: break shadow.conf into two files so that we only have to apply - # etc-shadow.conf in the initrd. - dotmpfiles "${FILESDIR}"/tmpfiles.d/etc-shadow.conf - dotmpfiles "${FILESDIR}"/tmpfiles.d/var-shadow.conf - # Package the symlinks for the SDK and containers. - systemd-tmpfiles --create --root="${ED}" "${FILESDIR}"/tmpfiles.d/* - - insinto /usr/share/shadow + insinto /etc if ! use pam ; then insopts -m0600 doins etc/login.access etc/limits fi - # Flatcar: - # Using a securetty with devfs device names added - # (compat names kept for non-devfs compatibility) - insopts -m0600 ; doins "${FILESDIR}"/securetty - # Output arch-specific cruft - local devs - case $(tc-arch) in - ppc*) devs="hvc0 hvsi0 ttyPSC0";; - hppa) devs="ttyB0";; - arm) devs="ttyFB0 ttySAC0 ttySAC1 ttySAC2 ttySAC3 ttymxc0 ttymxc1 ttymxc2 ttymxc3 ttyO0 ttyO1 ttyO2";; - sh) devs="ttySC0 ttySC1";; - amd64|x86) devs="hvc0";; - esac - if [[ -n ${devs} ]]; then - printf '%s\n' ${devs} >> "${ED}"/usr/share/shadow/securetty - fi # needed for 'useradd -D' + insinto /etc/default insopts -m0600 doins "${FILESDIR}"/default/useradd + if use split-usr ; then + # move passwd to / to help recover broke systems #64441 + # We cannot simply remove this or else net-misc/scponly + # and other tools will break because of hardcoded passwd + # location + dodir /bin + mv "${ED}"/usr/bin/passwd "${ED}"/bin/ || die + dosym ../../bin/passwd /usr/bin/passwd + fi + + cd "${S}" || die + insinto /etc insopts -m0644 newins etc/login.defs login.defs @@ -180,7 +167,7 @@ src_install() { else dopamd "${FILESDIR}"/pam.d-include/shadow - for x in chsh shfn ; do + for x in chsh chfn ; do newpamd "${FILESDIR}"/pam.d-include/passwd ${x} done @@ -219,7 +206,7 @@ src_install() { -e 'b exit' \ -e ': pamnote; i# NOTE: This setting should be configured via /etc/pam.d/ and not in this file.' \ -e ': exit' \ - "${ED}"/usr/share/shadow/login.defs || die + "${ED}"/etc/login.defs || die # Remove manpages that pam will install for us # and/or don't apply when using pam