sys-apps/shadow: Sync with Gentoo

It's from Gentoo commit a6ec9c2a8a13f2dbd82e8768666356beea63f445.
This commit is contained in:
Krzesimir Nowak 2023-08-01 14:29:41 +02:00
parent 8801a16b72
commit 9ac9ad9e10
8 changed files with 305 additions and 99 deletions

View File

@ -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

View File

@ -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;

View File

@ -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?= <cgzones@googlemail.com>
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;
}

View File

@ -0,0 +1,135 @@
https://github.com/shadow-maint/shadow/commit/65c88a43a23c2391dcc90c0abda3e839e9c57904
From 65c88a43a23c2391dcc90c0abda3e839e9c57904 Mon Sep 17 00:00:00 2001
From: Alejandro Colomar <alx@kernel.org>
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 <alx@kernel.org>
Cc: Serge Hallyn <serge@hallyn.com>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Cc: Seth Arnold <seth.arnold@canonical.com>
Cc: Christian Brauner <christian@brauner.io>
Cc: Balint Reczey <rbalint@debian.org>
Cc: Sam James <sam@gentoo.org>
Cc: David Runge <dvzrv@archlinux.org>
Cc: Andreas Jaeger <aj@suse.de>
Cc: <~hallyn/shadow@lists.sr.ht>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
--- 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);
}

View File

@ -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 <floppym@gentoo.org>
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 <floppym@gentoo.org>
--- 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"),

View File

@ -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

View File

@ -1 +0,0 @@
f /var/log/faillog - - - - -

View File

@ -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}
!<sys-apps/man-pages-5.11-r1
!=sys-apps/man-pages-5.12-r0
!=sys-apps/man-pages-5.12-r1
@ -65,6 +64,9 @@ BDEPEND="
PATCHES=(
"${FILESDIR}"/${P}-configure-clang16.patch
"${FILESDIR}"/${P}-CVE-2023-29383.patch
"${FILESDIR}"/${P}-usermod-prefix-gid.patch
"${FILESDIR}"/${P}-password-leak.patch
)
src_prepare() {
@ -105,20 +107,19 @@ src_configure() {
}
set_login_opt() {
# Flatcar: /etc/login.defs becomes /usr/share/shadow/login.defs
local comment="" opt=${1} val=${2}
if [[ -z ${val} ]]; then
comment="#"
sed -i \
-e "/^${opt}\>/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