Compare commits

...
Sign in to create a new pull request.

3 commits

Author SHA1 Message Date
Karel Zak
ac7d4ef0e2 agetty: fix stdin conversion to tty name [BZ#2326710] 2026-01-28 11:54:02 +01:00
Karel Zak
a957d6ce9e wall: Always use utmp as a fallback [BZ#2283049]
- clean up the patches section in the spec file
- re-sync patches with Git

(see https://github.com/karelzak/util-linux-work/tree/fedora/f42)
2026-01-27 10:27:25 +01:00
Karel Zak
33bdaab085 fix setpwnam() buffer use [CVE-2025-14104]
- libblkid: use snprintf() instead of sprintf()
2025-12-15 18:05:02 +01:00
11 changed files with 357 additions and 171 deletions

View file

@ -0,0 +1,28 @@
From 1a2ec6f6dbb1c74694403ff5bcfcbd36830ff2a4 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Tue, 2 Dec 2025 16:15:44 +0100
Subject: login: use O_CREAT on lastlog
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=151635
Signed-off-by: Karel Zak <kzak@redhat.com>
(cherry picked from commit 85902de01452198bc15199f5e5c147df31b38212)
---
login-utils/login.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/login-utils/login.c b/login-utils/login.c
index c8544f6a1..3de0398e9 100644
--- a/login-utils/login.c
+++ b/login-utils/login.c
@@ -681,7 +681,7 @@ static void log_lastlog(struct login_context *cxt)
sa.sa_handler = SIG_IGN;
sigaction(SIGXFSZ, &sa, &oldsa_xfsz);
- fd = open(_PATH_LASTLOG, O_RDWR, 0);
+ fd = open(_PATH_LASTLOG, O_RDWR | O_CREAT, 0);
if (fd < 0)
goto done;
offset = cxt->pwd->pw_uid * sizeof(ll);
--
2.52.0

View file

@ -0,0 +1,28 @@
From 84ee1e47e64fcabb83c39611d92a0496d086e0bb Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Tue, 2 Dec 2025 16:17:55 +0100
Subject: login: add /run/motd.d` to the hardcoded MOTD_FILE
Addresses: https://github.com/coreos/console-login-helper-messages/issues/60
Signed-off-by: Karel Zak <kzak@redhat.com>
(cherry picked from commit c8e1485a02c031926eb4ae0fc1e2ce380584be98)
---
include/pathnames.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/pathnames.h b/include/pathnames.h
index de456c53e..ac28a9a50 100644
--- a/include/pathnames.h
+++ b/include/pathnames.h
@@ -41,7 +41,7 @@
#ifndef _PATH_MAILDIR
# define _PATH_MAILDIR "/var/spool/mail"
#endif
-#define _PATH_MOTDFILE "/usr/share/misc/motd:/run/motd:/etc/motd"
+#define _PATH_MOTDFILE "/usr/share/misc/motd:/run/motd:/run/motd.d:/etc/motd:/etc/motd.d"
#ifndef _PATH_NOLOGIN
# define _PATH_NOLOGIN "/etc/nologin"
#endif
--
2.52.0

View file

@ -1,7 +1,7 @@
From ff0ac0f27dc3de7d250b2a69f6452bfeec104f8c Mon Sep 17 00:00:00 2001
From fa9260ab4d778c4c9958fd5a10644abf41ae6583 Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@redhat.com>
Date: Fri, 24 Jan 2025 08:37:12 -0600
Subject: [PATCH] blkid: allow up to 64k erofs block sizes
Subject: blkid: allow up to 64k erofs block sizes
Today, mkfs.erofs defaults to page size for block size, but blkid
does not recognize this. Increase the limit to 64k.
@ -29,5 +29,5 @@ index 05822460b..57fd80220 100644
if (!erofs_verify_checksum(pr, mag, sb))
--
2.48.1
2.52.0

View file

@ -0,0 +1,58 @@
From 83a413885e608296db220c009b2b1d015bb61e9c Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Mon, 6 Oct 2025 15:04:24 +0200
Subject: libblkid: use snprintf() instead of sprintf()
Replace sprintf() calls with snprintf() to ensure proper bounds
checking when formatting strings.
In encode.c, the check now validates snprintf() return value instead
of pre-checking buffer size, providing more robust error handling.
In probe.c, snprintf() is used with proper size calculation based on
remaining buffer space.
Signed-off-by: Karel Zak <kzak@redhat.com>
(cherry picked from commit 041380f4ca7244df624bf7efdb5e27fdd3144175)
(cherry picked from commit 917917253e60b0ba485cf6a27a2f993aa43e1eea)
---
libblkid/src/encode.c | 6 ++++--
libblkid/src/probe.c | 4 ++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/libblkid/src/encode.c b/libblkid/src/encode.c
index 8213873ee..4b83f6690 100644
--- a/libblkid/src/encode.c
+++ b/libblkid/src/encode.c
@@ -191,9 +191,11 @@ int blkid_encode_string(const char *str, char *str_enc, size_t len)
j += seqlen;
i += (seqlen-1);
} else if (str[i] == '\\' || !is_whitelisted(str[i], NULL)) {
- if (len-j < 4)
+ int rc;
+
+ rc = snprintf(&str_enc[j], len-j, "\\x%02x", (unsigned char) str[i]);
+ if (rc != 4)
goto err;
- sprintf(&str_enc[j], "\\x%02x", (unsigned char) str[i]);
j += 4;
} else {
if (len-j < 1)
diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c
index 7c561cf44..1f1031fda 100644
--- a/libblkid/src/probe.c
+++ b/libblkid/src/probe.c
@@ -1978,8 +1978,8 @@ static void blkid_probe_log_csum_mismatch(blkid_probe pr, size_t n, const void *
int hex_size = min(sizeof(csum_hex), n * 2);
for (int i = 0; i < hex_size; i+=2) {
- sprintf(&csum_hex[i], "%02X", ((const unsigned char *) csum)[i / 2]);
- sprintf(&expected_hex[i], "%02X", ((const unsigned char *) expected)[i / 2]);
+ snprintf(&csum_hex[i], sizeof(csum_hex) - i, "%02X", ((const unsigned char *) csum)[i / 2]);
+ snprintf(&expected_hex[i], sizeof(expected_hex) - i, "%02X", ((const unsigned char *) expected)[i / 2]);
}
ul_debug(
--
2.52.0

View file

@ -0,0 +1,50 @@
From 4d3bc36c528e8833e47cbd5b12063056ef9c0122 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Mon, 8 Dec 2025 13:36:41 +0100
Subject: login-utils: fix setpwnam() buffer use [CVE-2025-14104]
This issue has been originally fixed in the master branch, but
unfortunately was not backported to stable/v2.41 yet.
References: aaa9e718c88d6916b003da7ebcfe38a3c88df8e6
References: 9a36d77012c4c771f8d51eba46b6e62c29bf572a
Signed-off-by: Karel Zak <kzak@redhat.com>
(cherry picked from commit 9753e6ad9705104c3b05713f79ad6732cc4c7b30)
---
login-utils/setpwnam.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/login-utils/setpwnam.c b/login-utils/setpwnam.c
index 3e3c1abde..7778e98f7 100644
--- a/login-utils/setpwnam.c
+++ b/login-utils/setpwnam.c
@@ -99,7 +99,8 @@ int setpwnam(struct passwd *pwd, const char *prefix)
goto fail;
namelen = strlen(pwd->pw_name);
-
+ if (namelen > buflen)
+ buflen += namelen;
linebuf = malloc(buflen);
if (!linebuf)
goto fail;
@@ -126,10 +127,12 @@ int setpwnam(struct passwd *pwd, const char *prefix)
}
/* Is this the username we were sent to change? */
- if (!found && linebuf[namelen] == ':' &&
- !strncmp(linebuf, pwd->pw_name, namelen)) {
- /* Yes! So go forth in the name of the Lord and
- * change it! */
+ if (!found &&
+ strncmp(linebuf, pwd->pw_name, namelen) == 0 &&
+ strlen(linebuf) > namelen &&
+ linebuf[namelen] == ':') {
+ /* Yes! But this time lets not walk past the end of the buffer
+ * in the name of the Lord, SUID, or anything else. */
if (putpwent(pwd, fp) < 0)
goto fail;
found = 1;
--
2.52.0

View file

@ -0,0 +1,137 @@
From 0a856e72df9b6c37497e4e394841d893754b0fa8 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Mon, 3 Jun 2024 14:32:18 +0200
Subject: wall: always use utmp as fallback
Wall(1) can be compiled with systemd support to read the names of ttys
from the systemd session list. However, this may not work on all systems.
In case of failure, the best option is to use the traditional
utmp method as a fallback.
This commit uses strv (string vector) to collect tty names from both
sources (systemd and utmp) and then sends a message to all ttys.
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=2283049
Signed-off-by: Karel Zak <kzak@redhat.com>
(cherry picked from commit 0af497c6688b53a3a176176bfbcdca821bd856ec)
---
term-utils/wall.c | 57 ++++++++++++++++++++++++++++++++---------------
1 file changed, 39 insertions(+), 18 deletions(-)
diff --git a/term-utils/wall.c b/term-utils/wall.c
index 125fde438..22c3918bb 100644
--- a/term-utils/wall.c
+++ b/term-utils/wall.c
@@ -78,6 +78,7 @@
#include "closestream.h"
#include "timeutils.h"
#include "pwdutils.h"
+#include "strv.h"
#define TERM_WIDTH 79
#define WRITE_TIME_OUT 300 /* in seconds */
@@ -190,19 +191,30 @@ static int is_gr_member(const char *login, const struct group_workspace *buf)
return 0;
}
+static int has_tty(char **ttys, char *name)
+{
+ char **str;
+
+ STRV_FOREACH(str, ttys) {
+ if (strcmp(*str, name) == 0)
+ return 1;
+ }
+
+ return 0;
+}
+
int main(int argc, char **argv)
{
int ch;
struct iovec iov;
struct utmpx *utmpptr;
- char *p;
char line[sizeof(utmpptr->ut_line) + 1];
int print_banner = TRUE;
struct group_workspace *group_buf = NULL;
char *mbuf, *fname = NULL;
size_t mbufsize;
unsigned timeout = WRITE_TIME_OUT;
- char **mvec = NULL;
+ char **mvec = NULL, **ttys = NULL, **str;
int mvecsz = 0;
static const struct option longopts[] = {
@@ -265,30 +277,30 @@ int main(int argc, char **argv)
int sessions;
sessions = sd_get_sessions(&sessions_list);
- if (sessions < 0)
- errx(EXIT_FAILURE, _("error getting sessions: %s"),
- strerror(-sessions));
+ if (sessions < 0) {
+ warnx(_("error getting sessions: %s"), strerror(-sessions));
+ goto utmp;
+ }
for (int i = 0; i < sessions; i++) {
char *name, *tty;
int r;
- if ((r = sd_session_get_username(sessions_list[i], &name)) < 0)
- errx(EXIT_FAILURE, _("get user name failed: %s"), strerror (-r));
-
- if (!(group_buf && !is_gr_member(name, group_buf))) {
- if (sd_session_get_tty(sessions_list[i], &tty) >= 0) {
- if ((p = ttymsg(&iov, 1, tty, timeout)) != NULL)
- warnx("%s", p);
-
- free(tty);
- }
+ if ((r = sd_session_get_username(sessions_list[i], &name)) < 0) {
+ warnx(_("get user name failed: %s"), strerror (-r));
+ goto utmp;
}
+ if (!(group_buf && !is_gr_member(name, group_buf))
+ && sd_session_get_tty(sessions_list[i], &tty) >= 0
+ && strv_consume(&ttys, tty) < 0)
+ err(EXIT_FAILURE, _("failed to allocate lines list"));
+
free(name);
free(sessions_list[i]);
}
free(sessions_list);
- } else
+ }
+utmp:
#endif
{
while ((utmpptr = getutxent())) {
@@ -310,12 +322,21 @@ int main(int argc, char **argv)
continue;
mem2strcpy(line, utmpptr->ut_line, sizeof(utmpptr->ut_line), sizeof(line));
- if ((p = ttymsg(&iov, 1, line, timeout)) != NULL)
- warnx("%s", p);
+ if (has_tty(ttys, line))
+ continue;
+ if (strv_extend(&ttys, line) < 0)
+ err(EXIT_FAILURE, _("failed to allocate lines list"));
}
endutxent();
}
+ STRV_FOREACH(str, ttys) {
+ char *er = ttymsg(&iov, 1, *str, timeout);
+ if (er)
+ warnx("%s", er);
+ }
+
+ strv_free(ttys);
free(mbuf);
free_group_workspace(group_buf);
exit(EXIT_SUCCESS);
--
2.52.0

View file

@ -0,0 +1,39 @@
From 5bb099a5d86a26dcac5d32b1c75e6d9f84b298bf Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Mon, 24 Feb 2025 13:37:04 +0100
Subject: agetty: fix stdin conversion to tty name
Addresses: https://github.com/util-linux/util-linux/issues/3304
Signed-off-by: Karel Zak <kzak@redhat.com>
(cherry picked from commit bd6c104f931329ce6fbc5a1250c8c80a1d8223ee)
(cherry picked from commit c69353a5e03779b4840f260ba52a7d2bb7b8943c)
---
term-utils/agetty.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/term-utils/agetty.c b/term-utils/agetty.c
index a3823137d..34a39a51b 100644
--- a/term-utils/agetty.c
+++ b/term-utils/agetty.c
@@ -928,11 +928,15 @@ static void parse_args(int argc, char **argv, struct options *op)
/* resolve the tty path in case it was provided as stdin */
if (strcmp(op->tty, "-") == 0) {
+ int fd;
+ const char *name = op->tty;
+
op->tty_is_stdin = 1;
- int fd = get_terminal_name(NULL, &op->tty, NULL);
- if (fd < 0) {
+ fd = get_terminal_name(NULL, &name, NULL);
+ if (fd >= 0)
+ op->tty = name; /* set real device name */
+ else
log_warn(_("could not get terminal name: %d"), fd);
- }
}
/* On virtual console remember the line which is used for */
--
2.52.0

View file

@ -1,133 +0,0 @@
From 2b99ee2526ae61be761b0e31c50e106dbec5e9e4 Mon Sep 17 00:00:00 2001
From: Filipe Manana <fdmanana@kernel.org>
Date: Thu, 17 Aug 2023 10:20:13 +0100
Subject: [PATCH] libmount: Fix regression when mounting with atime
A regression was introduced in v2.39 that causes mounting with the atime
option to fail:
$ mkfs.ext4 -F /dev/sdi
$ mount -o atime /dev/sdi /mnt/sdi
mount: /mnt/sdi: not mount point or bad option.
dmesg(1) may have more information after failed mount system call.
The failure comes from the mount_setattr(2) call returning -EINVAL. This
is because we pass an invalid value for the attr_clr argument. From a
strace capture we have:
mount_setattr(4, "", AT_EMPTY_PATH, {attr_set=0, attr_clr=MOUNT_ATTR_NOATIME, propagation=0 /* MS_??? */, userns_fd=0}, 32) = -1 EINVAL (Invalid argument)
We can't pass MOUNT_ATTR_NOATIME to mount_setattr(2) through the attr_clr
argument because all atime options are exclusive, so in order to set atime
one has to pass MOUNT_ATTR__ATIME to attr_clr and leave attr_set as
MOUNT_ATTR_RELATIME (which is defined as a value of 0).
This can be read from the man page for mount_setattr(2) and also from the
kernel source:
$ cat fs/namespace.c
static int build_mount_kattr(const struct mount_attr *attr, size_t usize,
struct mount_kattr *kattr, unsigned int flags)
{
(...)
/*
* Since the MOUNT_ATTR_<atime> values are an enum, not a bitmap,
* users wanting to transition to a different atime setting cannot
* simply specify the atime setting in @attr_set, but must also
* specify MOUNT_ATTR__ATIME in the @attr_clr field.
* So ensure that MOUNT_ATTR__ATIME can't be partially set in
* @attr_clr and that @attr_set can't have any atime bits set if
* MOUNT_ATTR__ATIME isn't set in @attr_clr.
*/
if (attr->attr_clr & MOUNT_ATTR__ATIME) {
if ((attr->attr_clr & MOUNT_ATTR__ATIME) != MOUNT_ATTR__ATIME)
return -EINVAL;
/*
* Clear all previous time settings as they are mutually
* exclusive.
*/
kattr->attr_clr |= MNT_RELATIME | MNT_NOATIME;
switch (attr->attr_set & MOUNT_ATTR__ATIME) {
case MOUNT_ATTR_RELATIME:
kattr->attr_set |= MNT_RELATIME;
break;
case MOUNT_ATTR_NOATIME:
kattr->attr_set |= MNT_NOATIME;
break;
case MOUNT_ATTR_STRICTATIME:
break;
default:
return -EINVAL;
}
(...)
So fix this by setting attr_clr MOUNT_ATTR__ATIME if we want to clear any
atime related option.
Signed-off-by: Filipe Manana <fdmanana@kernel.org>
---
libmount/src/optlist.c | 13 ++++++++++++-
tests/expected/libmount/context-mount-flags | 3 +++
tests/ts/libmount/context | 9 ++++++++-
3 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/libmount/src/optlist.c b/libmount/src/optlist.c
index e93810b47..d0afc94f7 100644
--- a/libmount/src/optlist.c
+++ b/libmount/src/optlist.c
@@ -875,7 +875,18 @@ int mnt_optlist_get_attrs(struct libmnt_optlist *ls, uint64_t *set, uint64_t *cl
if (opt->ent->mask & MNT_INVERT) {
DBG(OPTLIST, ul_debugobj(ls, " clr: %s", opt->ent->name));
- *clr |= x;
+ /*
+ * All atime settings are mutually exclusive so *clr must
+ * have MOUNT_ATTR__ATIME set.
+ *
+ * See the function fs/namespace.c:build_mount_kattr()
+ * in the linux kernel source.
+ */
+ if (x == MOUNT_ATTR_RELATIME || x == MOUNT_ATTR_NOATIME ||
+ x == MOUNT_ATTR_STRICTATIME)
+ *clr |= MOUNT_ATTR__ATIME;
+ else
+ *clr |= x;
} else {
DBG(OPTLIST, ul_debugobj(ls, " set: %s", opt->ent->name));
*set |= x;
diff --git a/tests/expected/libmount/context-mount-flags b/tests/expected/libmount/context-mount-flags
index 960641863..eb71323dd 100644
--- a/tests/expected/libmount/context-mount-flags
+++ b/tests/expected/libmount/context-mount-flags
@@ -3,3 +3,6 @@ ro,nosuid,noexec
successfully mounted
rw,nosuid,noexec
successfully umounted
+successfully mounted
+rw,relatime
+successfully umounted
diff --git a/tests/ts/libmount/context b/tests/ts/libmount/context
index f5b47185e..a5d2e81a3 100755
--- a/tests/ts/libmount/context
+++ b/tests/ts/libmount/context
@@ -116,8 +116,15 @@ $TS_CMD_FINDMNT --kernel --mountpoint $MOUNTPOINT -o VFS-OPTIONS -n >> $TS_OUTPU
ts_run $TESTPROG --umount $MOUNTPOINT >> $TS_OUTPUT 2>> $TS_ERRLOG
is_mounted $DEVICE && echo "$DEVICE still mounted" >> $TS_OUTPUT 2>> $TS_ERRLOG
-ts_finalize_subtest
+# Test that the atime option works after the migration to use the new kernel mount APIs.
+ts_run $TESTPROG --mount -o atime $DEVICE $MOUNTPOINT >> $TS_OUTPUT 2>> $TS_ERRLOG
+$TS_CMD_FINDMNT --kernel --mountpoint $MOUNTPOINT -o VFS-OPTIONS -n >> $TS_OUTPUT 2>> $TS_ERRLOG
+is_mounted $DEVICE || echo "$DEVICE not mounted" >> $TS_OUTPUT 2>> $TS_ERRLOG
+ts_run $TESTPROG --umount $MOUNTPOINT >> $TS_OUTPUT 2>> $TS_ERRLOG
+is_mounted $DEVICE && echo "$DEVICE still mounted" >> $TS_OUTPUT 2>> $TS_ERRLOG
+
+ts_finalize_subtest
ts_init_subtest "mount-loopdev"
mkdir -p $MOUNTPOINT &> /dev/null
--
2.40.1

View file

@ -1,13 +0,0 @@
diff --git a/include/pathnames.h b/include/pathnames.h
index 3845d4c33..fac3a0783 100644
--- a/include/pathnames.h
+++ b/include/pathnames.h
@@ -41,7 +41,7 @@
#ifndef _PATH_MAILDIR
# define _PATH_MAILDIR "/var/spool/mail"
#endif
-#define _PATH_MOTDFILE "/usr/share/misc/motd:/run/motd:/etc/motd"
+#define _PATH_MOTDFILE "/usr/share/misc/motd:/run/motd:/run/motd.d:/etc/motd:/etc/motd.d"
#ifndef _PATH_NOLOGIN
# define _PATH_NOLOGIN "/etc/nologin"
#endif

View file

@ -1,12 +0,0 @@
diff -up util-linux-2.36/login-utils/login.c.kzak util-linux-2.36/login-utils/login.c
--- util-linux-2.36/login-utils/login.c.kzak 2020-07-23 14:13:26.777030764 +0200
+++ util-linux-2.36/login-utils/login.c 2020-07-23 14:11:22.793686983 +0200
@@ -585,7 +585,7 @@ static void log_lastlog(struct login_con
sa.sa_handler = SIG_IGN;
sigaction(SIGXFSZ, &sa, &oldsa_xfsz);
- fd = open(_PATH_LASTLOG, O_RDWR, 0);
+ fd = open(_PATH_LASTLOG, O_RDWR | O_CREAT, 0);
if (fd < 0)
goto done;
offset = cxt->pwd->pw_uid * sizeof(ll);

View file

@ -103,16 +103,20 @@ Provides: /usr/sbin/runuser
Provides: /usr/sbin/sfdisk
%endif
### Ready for upstream?
###
# 151635 - makeing /var/log/lastlog
Patch0: login-lastlog-create.patch
# Add `/run/motd.d` to the hardcoded MOTD_FILE
# https://github.com/coreos/console-login-helper-messages/issues/60
Patch1: login-default-motd-file.patch
# Backport better support for erofs on ppc64le
Patch2: 0001-blkid-allow-up-to-64k-erofs-block-sizes.patch
# 151635 - login: use O_CREAT on lastlog
Patch0: 0000-login-use-O_CREAT-on-lastlog.patch
# login: add /run/motd.d` to the hardcoded MOTD_FILE
Patch1: 0001-login-add-run-motd.d-to-the-hardcoded-MOTD_FILE.patch
# blkid: allow up to 64k erofs block sizes
Patch2: 0002-blkid-allow-up-to-64k-erofs-block-sizes.patch
# libblkid: use snprintf() instead of sprintf()
Patch3: 0003-libblkid-use-snprintf-instead-of-sprintf.patch
# login-utils: fix setpwnam() buffer use [CVE-2025-14104]
Patch4: 0004-login-utils-fix-setpwnam-buffer-use-CVE-2025-14104.patch
# wall: always use utmp as fallback
Patch5: 0005-wall-always-use-utmp-as-fallback.patch
%description
The util-linux package contains a large variety of low-level system