diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-30 11:05:59 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-30 11:05:59 +0300 |
| commit | 4e6d9e1a6c74e0bdb4d89df10ef22a664f84737f (patch) | |
| tree | d19f1d3755a61f880910033a39ba040d145b186d | |
| parent | 2be8db995514529921d1d57a8df3d275fbc64758 (diff) | |
test(generate): lock in sched_setparam pid-not-fd classification
Add TestClassifySchedSetparamPidNotFd as a dedicated regression test for
the sched_setparam(2) audit. The syscall takes a pid_t (args[0], NOT an
fd; 0 = calling thread) and a userspace const struct sched_param *, so
the enter must classify as KindNull and the exit as KindRet/UNCLASSIFIED
(returns 0/-1, no byte transfer), matching family Sched.
Implementation, docs, and generated C/Go artifacts already matched the
man page; sched_setparam was previously only asserted as a sibling check
inside the sched_getparam test. This pins its full behavior directly,
consistent with prior sched_getparam/sched_getattr audits.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| -rw-r--r-- | internal/generate/classify_test.go | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/internal/generate/classify_test.go b/internal/generate/classify_test.go index d354178..25d01b4 100644 --- a/internal/generate/classify_test.go +++ b/internal/generate/classify_test.go @@ -2378,6 +2378,73 @@ func TestClassifySchedGetparamPidNotFd(t *testing.T) { } } +// TestClassifySchedSetparamPidNotFd is a lock-in regression test for the +// sched_setparam(2) audit. The syscall signature is: +// +// int sched_setparam(pid_t pid, const struct sched_param *param) +// +// args[0] is a PID (the thread/process whose scheduling parameters are set; 0 +// means the calling thread), NOT a file descriptor, and param is a userspace +// input pointer to a struct sched_param. No fd or filesystem path is involved, +// so the enter tracepoint must classify as KindNull (plain null_event; the pid +// must never be picked up as an fd). On success sched_setparam returns 0 (-1 on +// error) and transfers no byte count, so its exit stays KindRet / UNCLASSIFIED +// — exactly like its getter sibling sched_getparam and sched_setscheduler. +func TestClassifySchedSetparamPidNotFd(t *testing.T) { + // Field layout mirrors the actual kernel tracepoint format for + // sys_enter_sched_setparam: pid_t pid, const struct sched_param *param. + r := ClassifyFormat(&Format{ + Name: "sys_enter_sched_setparam", + ExternalFields: []Field{ + {Type: "long", Name: "__syscall_nr"}, + {Type: "pid_t", Name: "pid"}, + {Type: "const struct sched_param *", Name: "param"}, + }, + }) + if r.Kind != KindNull { + t.Fatalf("sched_setparam: got kind %d, want KindNull (pid arg must not be treated as fd)", r.Kind) + } + if r.Kind == KindFd { + t.Fatalf("sched_setparam: pid arg misclassified as fd") + } + + // Family must match the Sched siblings (sched_getparam, sched_setscheduler, ...). + if fam := ClassifySyscallFamily("sys_enter_sched_setparam"); fam != FamilySched { + t.Fatalf("sched_setparam: got family %s, want FamilySched", fam) + } + + // Exit returns int 0/-1 (a status code, not a transferred byte count), so + // the return must classify as KindRet / UNCLASSIFIED. + exit := ClassifyFormat(&Format{ + Name: "sys_exit_sched_setparam", + ExternalFields: []Field{ + {Type: "long", Name: "__syscall_nr"}, + {Type: "long", Name: "ret"}, + }, + }) + if exit.Kind != KindRet { + t.Fatalf("exit_sched_setparam: got kind %d, want KindRet", exit.Kind) + } + if got := ClassifyRet("sys_exit_sched_setparam"); got != Unclassified { + t.Errorf("ClassifyRet(sys_exit_sched_setparam) = %q, want UNCLASSIFIED", got) + } + + // Sibling consistency: the matching getter shares family Sched and KindNull. + if g := ClassifyFormat(&Format{ + Name: "sys_enter_sched_getparam", + ExternalFields: []Field{ + {Type: "long", Name: "__syscall_nr"}, + {Type: "pid_t", Name: "pid"}, + {Type: "struct sched_param *", Name: "param"}, + }, + }); g.Kind != KindNull { + t.Errorf("sched_getparam: got kind %d, want KindNull", g.Kind) + } + if fam := ClassifySyscallFamily("sys_enter_sched_getparam"); fam != FamilySched { + t.Errorf("sched_getparam: got family %s, want FamilySched", fam) + } +} + // TestClassifyGetRobustListPidNotFd is a lock-in regression test for the // get_robust_list(2) / set_robust_list(2) audit. The signatures are: // |
