On Fri, Jun 12, 2026 at 11:37 PM Andy Lutomirski <[email protected]> wrote:
> > The filter
> > itself is also rather complex (mostly due to needing to account for
> > BPF jump sizes, which differ
> > as different configs (uprobe, uretprobe, SECCOMP_ARCH_COMPAT) have
> > different logic., and I'd worry about
> > keeping logic synced.
>
> Perhaps you and your AI could elaborate?  What are these jump sizes?
>
> In any case, I think the actual issue is that the STRICT filter's
> failure case doesn't quite correspond to any of the FILTER actions.
> So maybe it's too complex to be worthwhile.
>
> --Andy

The filter as implemented looks approximately like

load arch
#ifdef SECCOMP_ARCH_COMPAT
    if arch == compat: goto check_compat
#endif
if arch != native arch: goto kill
load syscall nr
if syscall == {read/write/exit/sigreturn}: goto allow
#ifdef URETPROBE
    if syscall == uretprobe: goto allow
#endif
#ifdef UPROBE
    if syscall == uprobe: goto allow
#endif
ret kill
#ifdef SECCOMP_ARCH_COMPAT
    check_compat:
    if syscall == {read/write/exit/sigreturn}: goto allow
    ret kill
#endif
allow:
ret allow

The offsets from each instruction to 'allow' will differ based on the
presence of various options.
I came up with an approach using an enum for numbering each step like so:
> enum {
>   SF_LD_ARCH = 0,
> #ifdef SECCOMP_ARCH_COMPAT
>   SF_JEQ_COMPAT_ARCH,
> #endif
>   SF_JEQ_NATIVE_ARCH,
>  /* ... */
> }
> #define SF_REL(from, to) ((__u8)((to) - (from) - 1))
> static const struct sock_filter seccomp_strict_filter[] = {
>     [SF_LD_ARCH] = BPF_STMT(...),
> #ifdef SECCOMP_ARCH_COMPAT
>     [SF_JEQ_COMPAT_ARCH] = BPF_JUMP(..., SF_REL(SF_JEQ_COMPAT_ARCH, 
> SF_LD_NR_COMPAT))
> #endif
>     /* ... */
> };

But I'm not convinced it's entirely readable/maintainable.

And just to be clear, I'm not using an AI personally; I was referring
to the Sashiko review bot, which I've now realised does not reply-all
with its reviews.

Reply via email to