summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-29 10:55:42 +0300
committerPaul Buetow <paul@buetow.org>2026-05-29 10:55:42 +0300
commit6561d63e5a47092d8b8f2a8128ad05ca9ffd2203 (patch)
tree81257fe07bf1cf0a343799d6c71c7bdbab33566c
parenta89ad0f245f15f7250ba9fe9506b2734bb49e12a (diff)
test(generate): lock in map_shadow_stack BPF handler field wiring
Audit of the x86 CET map_shadow_stack syscall (Linux 6.6+, void *map_shadow_stack(unsigned long addr, unsigned long size, unsigned int flags)) confirmed the existing tracing is correct: KindMem / FamilyMemory classification, memFieldSpec wires addr=args[0], length=args[1] (size), flags=args[2], length2=0, and the return (mapped address or -errno) is captured generically as ev->ret like every other KindMem exit. Docs and classify tests already match. The only gap was the lack of a codegen lock-in test for the BPF handler field wiring, which mlock2/remap_file_pages/mprotect/brk all have. Add TestGenerateMemHandlerMapShadowStack to guard against future drift. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
-rw-r--r--internal/generate/codegen_test.go18
1 files changed, 18 insertions, 0 deletions
diff --git a/internal/generate/codegen_test.go b/internal/generate/codegen_test.go
index ae2d643..09a23a5 100644
--- a/internal/generate/codegen_test.go
+++ b/internal/generate/codegen_test.go
@@ -280,6 +280,24 @@ func TestGenerateMemHandlerPkeyMprotect(t *testing.T) {
requireContains(t, output, "ev->flags = (__u64)ctx->args[2];")
}
+// TestGenerateMemHandlerMapShadowStack locks in the BPF handler wiring for the
+// x86 CET map_shadow_stack syscall (Linux 6.6+):
+// void *map_shadow_stack(unsigned long addr, unsigned long size, unsigned int flags).
+// The hint addr and size are args[0]/args[1] and flags is args[2]; there is no
+// second length, so length2 must stay zero. The return is a mapped address (or
+// -errno), captured generically via ev->ret like every other KindMem exit.
+func TestGenerateMemHandlerMapShadowStack(t *testing.T) {
+ output := GenerateTracepointsC(mustParseAll(t, syntheticPair("map_shadow_stack")))
+
+ requireContains(t, output, `SEC("tracepoint/syscalls/sys_enter_map_shadow_stack")`)
+ requireContains(t, output, "struct mem_event *ev")
+ requireContains(t, output, "ev->event_type = ENTER_MEM_EVENT;")
+ requireContains(t, output, "ev->addr = (__u64)ctx->args[0];")
+ requireContains(t, output, "ev->length = (__u64)ctx->args[1];")
+ requireContains(t, output, "ev->length2 = 0;")
+ requireContains(t, output, "ev->flags = (__u64)ctx->args[2];")
+}
+
func TestGenerateMemHandlerBrk(t *testing.T) {
output := GenerateTracepointsC(mustParseAll(t, syntheticPair("brk")))