Skip to content

arch-syscall-check: verify #ifdef __NR_ guards match __SNR_ define names#491

Open
rawrmonster17 wants to merge 1 commit into
seccomp:mainfrom
rawrmonster17:arch-syscall-check-snr-validation
Open

arch-syscall-check: verify #ifdef __NR_ guards match __SNR_ define names#491
rawrmonster17 wants to merge 1 commit into
seccomp:mainfrom
rawrmonster17:arch-syscall-check-snr-validation

Conversation

@rawrmonster17

Copy link
Copy Markdown

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

  • Clean pass on the current seccomp-syscalls.h (all guards match).
  • Injecting #ifdef __NR_accept_TYPO in place of #ifdef __NR_accept
    produces: MISMATCH at …seccomp-syscalls.h:313: #ifdef __NR_accept_TYPO but #define __SNR_accept
    and exits 1.
  • make check passes (PASS: arch-syscall-check, PASS: regression).

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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant