This adds a few typed assertion helpers to src/shared/tests.h that print
where things differ on failure, instead of just aborting:
- ASSERT_MEMEQ() / ASSERT_MEMEQ_NN() for memory regions
- ASSERT_MEMEQ_BYTE() / ASSERT_MEMEQ_ZERO()
- ASSERT_IOVEC_EQ() / ASSERT_IOVW_EQ()
On mismatch they show a hexdump-style, side-by-side diff of the
operands. To back this, hexdump() is moved from basic/hexdecoct to a new
shared/hexdump (the EFI hexdump() in src/boot is renamed to hexdump16()
to avoid the name clash), and the dump helpers live next to it.
The rest is mechanical: existing ASSERT_TRUE(memcmp(...) == 0) and
similar patterns are switched to the new macros, and assert_se() in the
fuzzers (plus a couple of test files) is converted to the typed ASSERT_*
family.
No functional change to non-test code.
I'm tired of reviews that constantly point out to add `/*
parameter_name= */` comments to functions calls where `NULL`, `0`, or
`true`, or `false` are passed. Let's add automated checking for this so
people have a reliable way to test this and the CI warns about it.
This is #43725 again. GitHub closed it when its base branch was deleted
after the tree-wide comments in #44532 were merged.
Since #44532 went in 23 pull requests added 232 new bare literals. The
checker also got stricter in the meantime. It now checks calls through
the shims in `src/include/override`, literals that have a comment after
them and `/* name */` comments that lost their `=`. That's 342 arguments
on current main and they're all fixed up here, one commit per top-level
source directory like in #44532, before the CI step is switched on. The
fixups are comments only. The `fsmount()` shim now uses the parameter
names from fsmount(2), so its last argument is commented as `attr_flags`
instead of glibc's misleading `ms_flags`.
The checker needs libclang 19 or newer. On four CPUs the whole suite
takes about a minute and a half.
The tree is clean now, keep it that way. Run the whole argument-comments
suite like the clang-tidy one. Checking only the lines a pull request
changed misses comments that go stale when a parameter is renamed,
since no caller's line changes then. On four CPUs the suite takes about
a minute and a half.
meson test reports a test that exits with 77 as skipped, so make sure
the libclang bindings are there first. Otherwise a tools tree without
them would pass the step without checking anything.
While at it, add the script to the mypy and tab checks.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
tools/check-argument-comments.py only takes the /* name= */ form that
docs/CODING_STYLE.md shows as naming a parameter, as clang-tidy's
bugprone-argument-comment does. Add the '=' these comments are missing.
Mechanical, generated by tools/check-argument-comments.py --fix.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
While at it, add the '=' that some of the existing comments are missing.
By hand, drop the /* uncompressed */ in dns_packet_read_rr() which only
repeats the new comment, and wrap the get_mempolicy() call in
numa-util.c that grew to 141 columns.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
tools/check-argument-comments.py only takes the /* name= */ form that
docs/CODING_STYLE.md shows as naming a parameter, as clang-tidy's
bugprone-argument-comment does. Add the '=' these comments are missing.
Mechanical, generated by tools/check-argument-comments.py --fix.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
While at it, add the '=' that some of the existing comments are missing.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
docs/CODING_STYLE.md asks for a /* name= */ comment whenever NULL or
another value meaning "unset" is passed to a function. Add it wherever
a bare NULL, 0, false or true is passed for a parameter with a telling
name. Mechanical, generated by tools/check-argument-comments.py --fix.
The fsmount() shim took its parameter names from glibc which calls the
last one ms_flags. That's misleading as it takes MOUNT_ATTR_* flags and
not MS_* flags. The kernel and fsmount(2) call it attr_flags. Use the
names from fsmount(2) and fix up the two comments in namespace.c that
called it mount_attrs and flags.
Run tools/check-argument-comments.py over the sources that are compiled,
one test per top-level source directory, in a suite that a plain "meson
test" leaves out like the other linters. The NSS, PAM and cryptsetup
token modules don't end up in sources, so collect theirs as well. The
source directory is passed explicitly, so the suite works without git,
from a tarball say. The script exits with meson's skip code where the
libclang python bindings are missing.
CODING_STYLE asks for a /* name= */ comment whenever NULL or another
value meaning "unset" is passed to a function. Nothing enforces it.
clang-tidy's bugprone-argument-comment only validates comments that
exist, and its option to demand them for literals never sees NULL
behind its cast in C and flags every size and mode along the way.
Add tools/check-argument-comments.py. It parses each file with
libclang and the flags from compile_commands.json, with every set of
them for a file that is built more than once, takes the parameter
names from the first declaration the caller sees, the one clang-tidy
compares comments against, and reports arguments spelled as a bare
NULL, 0, false or true, in the file and in the in-tree headers it
includes.
The arguments are read from the text of the call. So a literal with a
comment after it is still bare, and a comment at the end of the
previous line belongs to the previous argument. Like clang-tidy, only
a /* name= */ comment names a parameter, and case and leading or
trailing underscores don't matter. A /* name */ that lost its '=' is
reported too.
Calls into libc are skipped, and so are calls produced by macro bodies
since the caller never spelled their arguments. A call written inside
a macro argument is checked, as is a call through a macro that only
renames the function, the shims in src/include/override for example,
and a call through the sym_* pointers of the dlopen() wrappers.
--diff REV limits the report to lines that differ from a revision, and
--fix inserts the comments.
tools/check-argument-comments.py --diff "$(git merge-base main HEAD)" src
The builtin headers, stddef.h and friends, are located by asking the
clang binary of the same major version. libclang derives their
location from its own, and in the Fedora rawhide tools tree that
comes out as the relative ../lib/clang/22, so every file fails to
parse with 'stddef.h' file not found.
Needs python3-clang and libclang 19 or newer. Older versions return
the file location from clang_getSpellingLocation(), so calls produced
by macro bodies would be checked as if the caller had spelled them.
Let's use idmap-aware inode LSM hooks on Linux 7.4 and newer to check
the
ownership recorded on the actual backing filesystem. This permits safe
OverlayFS uppers while rejecting persistent transient IDs, including
when a
mount idmap translates stable caller IDs into transient IDs. Older
kernels
continue to use the path policy.
Let's preserve the policy maps and replace pinned program links
atomically
on restart, so failed replacement keeps existing namespaces protected.
Tests
cover OverlayFS, mount idmaps, links, ownership changes, POSIX queue
creation
and namespace lifetimes, and failed pin replacement.
The two xopenat_full() reopen checks were already expressed with
ASSERT_OK() right below; remove the leftover assert_se() duplicates.
Follow-up for 3295505085