Karel Zak [Mon, 30 Mar 2026 12:16:25 +0000 (14:16 +0200)]
nsenter: keep PID:inode validated pidfd open
The original code validated the PID:inode by opening a pidfd via
ul_get_valid_pidfd_or_err(), but immediately closed it. Later,
pidfd_open() was called again for the same PID. This created a
window between close() and the second pidfd_open() where the PID
could be recycled by the kernel, defeating the purpose of the
PID:inode identity verification.
Keep the validated pidfd from PID:inode open and reuse it, so the
process identity is pinned for the entire lifetime of nsenter. As
long as the pidfd is held open, the kernel will not recycle the PID,
making subsequent operations (setns, ioctls) race-free.
Introduce ns_pid_fd to separate the pidfd used for enter_namespaces()
(setns, requires kernel >= 5.7) from the general-purpose pid_fd used
for ioctls like PIDFD_GET_USER_NAMESPACE and pidfd_getfd(). The kernel
version check gates only the setns-related usage.
Also use ul_parse_pid_str_or_err() for consistent error handling
across utilities that support the PID:inode format.
Karel Zak [Tue, 31 Mar 2026 08:27:57 +0000 (10:27 +0200)]
Merge branch 'prlimit_pidino_support' of https://github.com/cgoesche/util-linux-fork
* 'prlimit_pidino_support' of https://github.com/cgoesche/util-linux-fork:
tests: (prlimit) add pid:ino address format test
prlimit: support 'PID:inode' process address format
Leonid Znamenok [Mon, 30 Mar 2026 20:33:46 +0000 (00:33 +0400)]
fincore: (tests) fix tmpfs detection for out-of-tree builds
The tmpfs check used $PWD which points to the source directory, not
to the output directory where test files are actually created. When
tests are run with --builddir on tmpfs (e.g. /tmp), the check fails
to detect it and the test produces wrong results because O_DIRECT
has no effect on tmpfs.
Use $TS_OUTDIR instead, which is the actual directory where dd
creates test files and fincore inspects them.
When setting the effective user fails the code prints a
misleading error message stating that 'group' privileges
could not be dropped, but it should state 'user' instead.
Signed-off-by: Christian Goeschel Ndjomouo <cgoesc2@wgu.edu>
The variable name 'match' naturally implies a binary
state e.g. true or false and is not appropriate for
the indexing of a string literal, it is better to
avoid this ambiguity and use a name that properly
conveys its purpose, in this case 'idx' is a better
choice.
Signed-off-by: Christian Goeschel Ndjomouo <cgoesc2@wgu.edu>
This patch improves the coding style in various places for
better readability, semantic clarity and alignment with
common best practices.
Changes include the transposition of a variable assignment
in a conditional statement to its own line for better
readability, the removal of defensive programming techniques
like 'yoda conditions' where constants are specified on the
left of variables, which reduce natural readability and are
not necessary as erroneous variable assignments will be
indicated by the compiler anyways. Lastly, the 'u' suffix is
extraneous for variable assignments to 'match' as it is a size_t.
Signed-off-by: Christian Goeschel Ndjomouo <cgoesc2@wgu.edu>
unshare: new option to prevent environment variable inheritance
In some cases it is desirable to have a clean environment for
an unshared process and conveniently prevent any information
leakage into the new namespace.
This is what the --clear-env option can be used for; it makes
it so that unshare(1) clears the environment variable array,
obtained from the calling process, right before executing the
target program.
Signed-off-by: Christian Goeschel Ndjomouo <cgoesc2@wgu.edu>
Karel Zak [Thu, 26 Mar 2026 12:44:08 +0000 (13:44 +0100)]
tests: add btrfs RAID is-mounted test for libmount
Add a test that verifies mnt_table_is_fs_mounted() correctly detects
already-mounted btrfs subvolumes when the fstab source device differs
from the one in mountinfo (simulating btrfs RAID).
The test uses synthetic mountinfo and fstab files with /dev/sdc1 in
mountinfo and /dev/sdc2 in fstab, covering both subvol= and
subvolid= variants.
Addresses: https://github.com/util-linux/util-linux/issues/3778 Signed-off-by: Karel Zak <kzak@redhat.com>
Karel Zak [Thu, 26 Mar 2026 12:28:45 +0000 (13:28 +0100)]
libmount: return btrfs rootfs from get_btrfs_fs_root()
Extend get_btrfs_fs_root() to return the matching mountinfo entry via
a new rootfs parameter. This allows mnt_table_get_fs_root() to
propagate the actual mounted device as src_fs, so
__mnt_table_is_fs_mounted() uses the device path from mountinfo rather
than the fstab-resolved one.
This fixes btrfs RAID detection where the fstab source (e.g.,
/dev/sdc2) may differ from the device the kernel used in mountinfo
(e.g., /dev/sdc1), causing mount -a to not recognize already-mounted
subvolumes.
Also add a new branch for fstab entries with subvol= (without
subvolid=) to search mountinfo for the matching entry.
The test_is_mounted now accepts an optional mountinfo file argument
to allow testing without a live mount setup.
Addresses: https://github.com/util-linux/util-linux/issues/3778 Signed-off-by: Karel Zak <kzak@redhat.com>
Karel Zak [Wed, 25 Mar 2026 13:27:05 +0000 (14:27 +0100)]
libmount: use match_source for mountinfo comparison
Use mnt_fs_match_source() instead of mnt_fs_streq_srcpath() in
__mnt_table_is_fs_mounted() to compare source paths against mountinfo
entries.
The streq_srcpath() does a simple string comparison that fails when
the device name in mountinfo differs from the resolved fstab source
(e.g., /dev/dm-N vs /dev/mapper/name, or different btrfs RAID member
devices). The match_source() handles device name canonicalization and
tag-based matching through the cache.
Addresses: https://github.com/util-linux/util-linux/issues/3778 Signed-off-by: Karel Zak <kzak@redhat.com>
Clarify when mount IDs are available depending on how the mount table
was populated (mountinfo parsing vs listmount/statmount). Document
that mnt_fs_get_uniq_id() returns 0 for mountinfo-parsed tables and
point users to mnt_id_from_path() as the statx-based alternative.
Karel Zak [Tue, 24 Mar 2026 10:28:40 +0000 (11:28 +0100)]
tools: git-version-next fix -devel tag and rename variables
Fix UL_LAST_FINAL_RELEASE to not match -devel tags by using a
positive match for final release formats (vX.Y or vX.Y.Z) instead
of only excluding -rc suffixes.
Karel Zak [Thu, 19 Mar 2026 19:53:41 +0000 (20:53 +0100)]
liblastlog2: generate lastlog2.h from template
Convert lastlog2.h to lastlog2.h.in and add LIBLASTLOG2_VERSION,
LIBLASTLOG2_MAJOR_VERSION, LIBLASTLOG2_MINOR_VERSION, and
LIBLASTLOG2_PATCH_VERSION defines to follow the same pattern as
libmount, libfdisk, libsmartcols, and libblkid.
Update both autotools (configure.ac, Makemodule.am) and meson
(liblastlog2/meson.build) to generate the header.
Karel Zak [Thu, 19 Mar 2026 13:20:40 +0000 (14:20 +0100)]
libblkid: add LIBBLKID_VERSION to blkid.h, remove redundant config.h versions
Add LIBBLKID_VERSION, LIBBLKID_MAJOR_VERSION, LIBBLKID_MINOR_VERSION,
and LIBBLKID_PATCH_VERSION to blkid.h.in to follow the same pattern as
libmount, libfdisk, and libsmartcols. Keep BLKID_VERSION and BLKID_DATE
as backward-compatible aliases.
Remove redundant AC_DEFINE for library version strings from configure.ac
(LIBMOUNT_VERSION, LIBSMARTCOLS_VERSION, LIBFDISK_VERSION,
LIBLASTLOG2_VERSION). These were duplicated in config.h when the library
public headers already define them via .h.in templates.
Remove LIBBLKID_VERSION and LIBBLKID_DATE from meson config.h for the
same reason.
Karel Zak [Thu, 19 Mar 2026 12:44:16 +0000 (13:44 +0100)]
meson: add hwclock-gplv3 option
Add the missing hwclock-gplv3 option (default: true) to match
autotools --disable-hwclock-gplv3. Without the USE_HWCLOCK_GPLv3_DATETIME
define, meson builds used the minimalistic GPLv2 date parser even though
the GPLv3 parse-date.y was always compiled and linked.
Karel Zak [Thu, 19 Mar 2026 12:41:56 +0000 (13:41 +0100)]
meson: add login-stat-mail option
Add the missing login-stat-mail option (default: false) to match
autotools --enable-login-stat-mail. When enabled, login will stat()
the mailbox to check for new mail.
Karel Zak [Thu, 19 Mar 2026 12:39:52 +0000 (13:39 +0100)]
meson: add check for security_get_initial_context()
The mount command uses HAVE_SECURITY_GET_INITIAL_CONTEXT to enable
SELinux context warnings. This check was missing in meson, leaving
that code path dead in meson builds.
Autotools checks for this function in configure.ac since it may be
missing in old libselinux 1.xx versions.
Karel Zak [Thu, 19 Mar 2026 12:30:22 +0000 (13:30 +0100)]
meson: remove unused HAVE_NCURSES config define
No source code uses HAVE_NCURSES (without _W or _H suffix).
In autotools it only exists as an AM_CONDITIONAL for Makefile logic,
not as a config.h define.
Karel Zak [Thu, 19 Mar 2026 12:21:31 +0000 (13:21 +0100)]
meson: fix plymouth support macro name
The source code (agetty.c, sulogin.c) checks for USE_PLYMOUTH_SUPPORT,
but meson defined ENABLE_PLYMOUTH_SUPPORT, silently disabling plymouth
support in meson builds.
Rename to USE_PLYMOUTH_SUPPORT to match autotools and source code.
The caught_signal variable could be modified while the original signal
handler is restored. If this happens, su does not kill itself with the
signal but just triggers another installed signal handler, ultimately
exiting with return value 1 instead.
Prevent this race by storing the value on stack and then proceed with
this definitely fixed value.
Karel Zak [Mon, 23 Mar 2026 11:13:11 +0000 (12:13 +0100)]
pwdutils: extend ul_getuserpw_str() and ul_getgrp_str() to return ID
Add an optional result parameter to ul_getuserpw_str() and
ul_getgrp_str() to return the parsed UID/GID even when getpwuid() or
getgrgid() returns NULL (i.e., the numeric ID has no entry in the
passwd/group database).
This avoids the need for callers to re-parse the string when they only
need the numeric ID.
Also zero errno before calling getpwnam()/getgrnam() to prevent stale
errno from the preceding ul_strtou64() call from leaking to callers.
This fixes unshare --map-user/--map-group regression introduced in
commit 0a7fb8061 where a valid numeric UID/GID without a passwd/group
entry would cause a failure instead of being used directly.
Addresses: https://github.com/util-linux/util-linux/pull/4134 Signed-off-by: Karel Zak <kzak@redhat.com>
This is caused by lseek() of /dev/null and /dev/zero always returning 0
regardless of whence. If fallocate is run on /dev/zero or /dev/null
with the option -d or -z, the length to skip in the main loop logic in
dig_holes() is always calculated as zero.
A conforming VFS never behaves like this so it's safe to assume that the
SEEK_DATA and SEEK_HOLE behaviour is broken.
Karel Zak [Thu, 19 Mar 2026 10:52:24 +0000 (11:52 +0100)]
tools: add git-compare-backport script
Compare commit subject lines between master and a stable/* branch
to identify commits missing from the stable branch (backport
candidates). Merge commits are ignored, cherry-picked commits are
detected by matching subject lines.
Karel Zak [Thu, 19 Mar 2026 10:06:20 +0000 (11:06 +0100)]
bash-completion: (unshare) remove embedded tabs from option strings
Line continuations in the option string assignments preserved the
leading tab (code indentation) from continuation lines, embedding
literal tab characters into the variable values. This broke regex
matching in the offset-detection loop for --mount-proc (OPTARGOPTS),
--map-groups (REQARGOPTS), and --map-subids (NOARGOPTS).
Addresses: https://github.com/util-linux/util-linux/pull/4084 Signed-off-by: Karel Zak <kzak@redhat.com>
Karel Zak [Thu, 19 Mar 2026 09:40:45 +0000 (10:40 +0100)]
Merge branch 'PR/benno-copyfilerange-files' of https://github.com/karelzak/util-linux-work
* 'PR/benno-copyfilerange-files' of https://github.com/karelzak/util-linux-work:
tests: (copyfilerange) update expected output for changed wording
copyfilerange: simply report "too few arguments", not misleading messages
copyfilerange: wrap some overlong lines (in a tabsize-independent way)
bash-completion: add improvements to unshare(1) completions
This change adds the ability to complete the command of the
executable that the unshare command is going to execute.
Additionally, it includes support for completions of long
options that have optional arguments and are thus specified
with a suffixed '=' sign, which delimits the option name
from the actual option argument.
Lastly, it also adds file/directory completions for options that
require file or directory paths as arguments.
Addresses: #4073 Signed-off-by: Christian Goeschel Ndjomouo <cgoesc2@wgu.edu>
Having the debug functions as static inline functions throughout the
code base leads to code bloat, since they always serve the same purpose
without custom modifications.
Keep defines and everything specific to an including file in a header, but
move function bodies into their own c file.
Reduces size of util-linux installation by up to 80 KB on x86_64.
Karel Zak [Wed, 18 Mar 2026 12:04:08 +0000 (13:04 +0100)]
tests: add SCS escape sequence test for column
Convert the ansiescape test to use subtests and add a test
for SCS (Select Character Set) escape sequences to verify
they are properly skipped in width calculation.
Addresses: https://github.com/util-linux/util-linux/issues/4121 Signed-off-by: Karel Zak <kzak@redhat.com>
Karel Zak [Wed, 18 Mar 2026 11:48:54 +0000 (12:48 +0100)]
mbsalign: cleanup escape sequences handling
Use '\033' (portable) instead of '\e' (GNU extension), simplify
the control character handling by checking for ESC directly, and
fix the SCS boundary check to only match complete sequences.
Karel Zak [Wed, 18 Mar 2026 11:36:37 +0000 (12:36 +0100)]
Merge branch 'fix/4121' of https://github.com/echoechoin/util-linux
* 'fix/4121' of https://github.com/echoechoin/util-linux:
mbsalign: validate ESC character before processing escape sequences
mbsalign: add support for SCS escape sequences
Karel Zak [Wed, 18 Mar 2026 11:01:11 +0000 (12:01 +0100)]
findmnt: fix SIGSEGV when parsing empty file
Set mnt_table_set_userdata() right after mnt_new_table() in all
functions that create a libmount table, so that parser_errcb() can
always safely access the findmnt userdata.
Previously, userdata was set only in main() after parse_tabfiles()
returned, meaning the error callback would dereference a NULL pointer
when encountering parse errors (e.g., an empty file passed via -F).
Also add a NULL guard in parser_errcb() as a safety net, and a test
for the empty file case.
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=2448233 Signed-off-by: Karel Zak <kzak@redhat.com>
copyfilerange: simply report "too few arguments", not misleading messages
Running ./copyfilerange without any arguments would report:
copyfilerange: source file is required
giving the impression that only a source file is required.
But running ./copyfilerange with one argument would report:
copyfilerange: destination file is required
giving the impression that specifying two files would be enough.
But running ./copyfilerange with two arguments would report:
copyfilerange: nothing to do, no ranges supplied
Instead of these custom messages, let's report what other tools
report when given too few arguments: "too few arguments".
This change also prevents `copyfilerange` from creating an empty
destination file when given just two arguments, when it reported
that there was nothing to do.
Furthermore, correct a parameter of a call of err(),
from `argv[2]` to `range.out_filename`.
CC: Dick Marinus <dick@mrns.nl> Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
copyfilerange: wrap some overlong lines (in a tabsize-independent way)
Most tools in util-linux seem to assume a tabsize of 8, judging from
the alignments of several continuation lines. But `copyfilerange.c`
appears to have assumed a tabsize of 2, because with a tabsize of 8
the text on line 147 started in column 209!
But even with a tabsize of 2, three lines were much wider than the
reasonable 100 columns. So, wrap those, and in the bargain improve
the wording of the affected messages, and add a space before %m.
CC: Dick Marinus <dick@mrns.nl> Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
WanBingjiang [Tue, 17 Mar 2026 02:17:15 +0000 (10:17 +0800)]
mbsalign: add support for SCS escape sequences
Add handling for SCS (Select Character Set) escape sequences:
\e(X, \e)X, \e*X, \e+X. These sequences are now properly skipped
when calculating string width.
Karel Zak [Mon, 16 Mar 2026 13:02:55 +0000 (14:02 +0100)]
chmem: fix segfault when parameter is just a dash
When running "chmem --disable -", ul_strv_split("-", "-") returns an
empty array (length 0) because the input string contains only the
separator. The code only checked for length > 2, so length 0 fell
through to parse_range_param() with NULL pointers, causing a segfault
in strlen().
Fix by rejecting parameters that produce fewer than 1 token, and add
NULL checks in parse_range_param() for additional robustness.
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=2447899 Signed-off-by: Karel Zak <kzak@redhat.com>
copyfilerange: (usage) correct the markup and improve the wording
The <source>, <destination>, and <range> arguments are required,
so do not mark them as optional (with the square brackets).
Also, trim the redundant lines about the source and destination
files, improve the explanation for the <range> argument and put
it after the options, and keep the text within 80 columns.
Furthermore, list the short options first (as is custom), and
match the indentaion of the -h and -V options to the others.
CC: Dick Marinus <dick@mrns.nl> Signed-off-by: Benno Schulenberg <bensberg@telfort.nl>
lsmem: (man) correct the markup of column names, and improve some grammar
The column names should be marked in bold and not in italics, as they
are literal values, not placeholders.
Also, indent the list of column names, to make it clearer where the
list ends. And add the missing markup for "RANGE" and the missing
name "REMOVABLE".
Furthermore, drop the small table, as it held nearly no information
and was confusing: the explicit numbers in the BLOCK column gave the
impression that block 0 can only be online, block 1 only offline but
configured, and block 2 only offline and deconfigured. The content
of the MEMMAP-ON-MEMORY column being always "yes/no" was useless.
Leaving out those columns left only STATE and CONFIGURED, where the
values implied that memory can only be online when it is configured.
This information can be conveyed in a single sentence.
(The table was added in commit 6f1e4ff054 from five months ago.)
Karel Zak [Mon, 16 Mar 2026 10:43:19 +0000 (11:43 +0100)]
libblkid: add debug message for private DM device skip
Add a DBG() trace and set errno = EINVAL when
blkid_new_probe_from_filename() skips a private device-mapper
device, to aid troubleshooting and distinguish from I/O errors.
Addresses: https://github.com/util-linux/util-linux/pull/4120 Signed-off-by: Karel Zak <kzak@redhat.com>
Karel Zak [Mon, 16 Mar 2026 10:18:45 +0000 (11:18 +0100)]
Merge branch 'PR/libsmartcols-width-calc' of https://github.com/karelzak/util-linux-work
* 'PR/libsmartcols-width-calc' of https://github.com/karelzak/util-linux-work:
tests: update to reflect libsmartcols changes
libsmartcols: enlarge columns with absolute width hint
column: Add notes about the role of the column header
libsmartcols: improve truncation of column width
tests: add column strictwidth test
libsmartcols: fix column width calculation
libsmartcols: fix width= property parsing
Karel Zak [Mon, 16 Mar 2026 10:18:30 +0000 (11:18 +0100)]
Merge branch 'PR/dmesg-delta-notime' of https://github.com/karelzak/util-linux-work
* 'PR/dmesg-delta-notime' of https://github.com/karelzak/util-linux-work:
dmesg: rename is_time_fmt_set() to is_time_fmt()
dmesg: warn on boot time failure instead of suppressing timestamps
dmesg: add replace_time_fmt() and replace_delta_fmt() helpers
tests: add dmesg -d -t and -t -d timestamp format tests
dmesg: fix -d -t (--show-delta --notime) output regression
dmesg: remove delta variable, use time format list consistently
WanBingjiang [Mon, 16 Mar 2026 03:59:56 +0000 (11:59 +0800)]
getopt: document whitespace as separator in --longoptions
The --longoptions option accepts not only commas but also whitespace
(spaces, tabs, or newlines) as separators between option names.
Update the man page to reflect this behavior.
Zdenek Kabelac [Sat, 14 Mar 2026 13:39:41 +0000 (14:39 +0100)]
libblkid: check for private DM device before open
blkid_new_probe_from_filename() opens the device before calling
blkid_probe_set_device(), which checks sysfs_devno_is_dm_private()
and sets BLKID_FL_NOSCAN_DEV. But the open() itself bumps the
kernel open count, so a concurrent DM_DEVICE_REMOVE ioctl sees
EBUSY even though blkid never actually probes the device.
Move the private-device check before open() in
blkid_new_probe_from_filename(). The sysfs UUID is readable
without opening the block device, so this closes the race window
between udev-worker's blkid builtin and device-mapper remove.
Note: blkid_verify() in verify.c already does the check before
open() -- this patch makes the probe path consistent.
YuriyRyabikov [Fri, 13 Mar 2026 16:34:19 +0000 (16:34 +0000)]
pager: address review feedback for less --header support
- Remove static globals; store header_lines/header_width in
struct child_process instead
- Invert pager_open/pager_open_header: pager_open() now calls
pager_open_header(0, 0) as a thin wrapper
- Append --header to existing LESS value when set, instead of
silently skipping header setup
- Flatten nested if-blocks into single setenv() call
- Use int consistently instead of mixing int and size_t
- Document that header_lines=0 means no header regardless of width
kurok [Fri, 13 Mar 2026 11:31:33 +0000 (11:31 +0000)]
libsmartcols: add scols_table_calculate(), pager: add less --header support
Add scols_table_calculate() public API to allow column width calculation
without printing. This enables callers to query column widths (via
scols_column_get_width()) before starting output, which is needed to
set up "less --header" for freezing table headers and the first column.
The new function runs __scols_initialize_printing() (which includes
__scols_calculate()) and sets an is_calculated flag so that subsequent
scols_print_table() calls skip redundant recalculation.
Add pager_open_header() to lib/pager.c that sets the LESS environment
variable with "--header N,M" options before spawning the pager process.
This freezes the first N lines (header row) and first M character columns
(first table column) when scrolling in less.
Karel Zak [Thu, 12 Mar 2026 13:13:59 +0000 (14:13 +0100)]
autotools: Remove the need for --disable-liblastlog2
We typically build all in-tree libraries, but liblastlog2 requires an
external dependency on sqlite3. It doesn't make sense to force all
users to use --disable-liblastlog2 to explicitly disable it.
Let's check for sqlite3, and if it's not installed, disable the library.
Addresses: https://github.com/util-linux/util-linux/issues/4112#issuecomment-4042305081 Signed-off-by: Karel Zak <kzak@redhat.com>
Karel Zak [Thu, 12 Mar 2026 12:26:47 +0000 (13:26 +0100)]
dmesg: rename is_time_fmt_set() to is_time_fmt()
Shorten the function name for consistency with the other time format
helpers (include_time_fmt, exclude_time_fmt, replace_time_fmt).
No functional change.
Karel Zak [Thu, 12 Mar 2026 12:22:55 +0000 (13:22 +0100)]
dmesg: warn on boot time failure instead of suppressing timestamps
When dmesg_get_boot_time() fails, warn the user instead of silently
adding DMESG_TIMEFTM_NONE to suppress all timestamp output. The user
asked for a specific format and should get it, with a warning that
wall-clock timestamps may be inaccurate.
Also move the boot time check after the time format post-processing
so it operates on the final resolved format list, and add
DMESG_TIMEFTM_CTIME_DELTA to the condition since it also requires
boot time.