The arch-syscall-check script already verifies that the set of syscall
names in syscalls.csv matches the set of __SNR_ defines in
seccomp-syscalls.h. However it does not verify that each '#ifdef
__NR_<name>' guard immediately preceding a '#define __SNR_<name>' uses
the same syscall name as the define it guards.
A mismatch -- e.g. '#ifdef __NR_foo' guarding '#define __SNR_bar' --
means the define will silently resolve to __PNR_bar (not present)
even when __NR_foo is defined by the kernel headers, rendering the
syscall unreachable through libseccomp on any arch that has it.
Add check_snr_ifdef() which reads seccomp-syscalls.h line by line and
reports any '#ifdef __NR_<X>' / '#define __SNR_<Y>' pairing where X
and Y differ. Any other preprocessor directive between the #ifdef and
the matching #define resets the pending guard name (handles the
unconditional '#define __SNR_x __NR_x' form, which carries no #ifdef
and needs no cross-check).
The exit code from check_snr_ifdef() is accumulated into the script's
overall return code alongside the existing check_snr() and check_pnr()
checks, so a guard mismatch will fail the 'arch-syscall-check' test
that runs as part of 'make check'.
Fixes: Github Issue seccomp#315
Signed-off-by: rawrmonster17 <rawrmonster17@users.noreply.github.com>
Problem
src/arch-syscall-check already verifies that the set of syscall names in
syscalls.csv matches the set of __SNR_ defines in seccomp-syscalls.h.
However it does not verify that each #ifdef __NR_<name> guard immediately
preceding a #define __SNR_<name> uses the same syscall name as the
define it guards.
A mismatch — e.g. #ifdef __NR_foo guarding #define __SNR_bar — means the
define will silently resolve to __PNR_bar (not present) even when __NR_foo
is defined by the kernel headers. The existing name-set diff (using sort -u)
would not catch this because both names appear in the header; only the pairing
is wrong.
Fixes: Github Issue #315
Fix
Add check_snr_ifdef() to src/arch-syscall-check. The function reads
seccomp-syscalls.h line by line and reports any #ifdef __NR_<X> /
#define __SNR_<Y> pairing where X ≠ Y, along with the file and line number.
Any other preprocessor directive between an #ifdef and the expected
#define (including unconditional defines that carry no #ifdef guard)
resets the pending guard name so only genuine guarded pairs are checked.
The exit code from check_snr_ifdef() is accumulated into the script's
overall return value alongside the existing check_snr() and check_pnr()
checks, so a guard mismatch fails the arch-syscall-check test that runs
as part of make check.
Testing
produces: MISMATCH at …seccomp-syscalls.h:313: #ifdef __NR_accept_TYPO but #define __SNR_accept
and exits 1.