Re: [PATCH v2] seccomp: passthrough uretprobe systemcall without filtering

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Kees,

On Tue, Jan 28, 2025 at 5:41 PM Kees Cook <kees@xxxxxxxxxx> wrote:
> [...]
> Also please add a KUnit tests to cover this in
> tools/testing/selftests/seccomp/seccomp_bpf.c
> With at least these cases combinations below. Check each of:
>
>         - not using uretprobe passes
>         - using uretprobe passes (and validates that uretprobe did work)
>
> in each of the following conditions:
>
>         - default-allow filter
>         - default-block filter
>         - filter explicitly blocking __NR_uretprobe and nothing else
>         - filter explicitly allowing __NR_uretprobe (and only other
>           required syscalls)

In order to validate my understanding of the required test cases,
I've attached a small bash script which validates them.
As expected, the script fails without the suggested change.

If there are gaps in my understanding of the required scope, please
let me know.
I plan to port these test cases to use the kselftests infrastructure as
requested.

To my understanding, the other issues with regards to the proposed patch
are resolved, i.e. there aren't plans to support a 32 bit or mips flavor
of this syscall, and the suggested patch fails closed if they are added.

As such, is it possible to merge the suggested patch so it could be back
merged? I'm suggesting this in the interest of time, as for example Ubuntu
LTS is going to be using kernel 6.11 soon [1] and other distributions
are probably going to as well, and I believe the coding/review process
for the testing code will take a while and probably won't be backmerged
anyway.

Thanks!
Eyal.

[1] https://www.omgubuntu.co.uk/2025/01/ubuntu-24-04-2-release-date
#!/bin/bash -e

bt=/usr/bin/bpftrace

default_allow_filter=$(cat << EOF
{
    	scmp_filter_ctx ctx;
    
    	ctx = seccomp_init(SCMP_ACT_ALLOW);
    	seccomp_load(ctx);
    	seccomp_release(ctx);
}
EOF
)

default_block_filter=$(cat << EOF
{
    	scmp_filter_ctx ctx;
    
    	ctx = seccomp_init(SCMP_ACT_KILL);
    	for (int i = 0; i < num_syscalls; i++) {
    		seccomp_rule_add(ctx, SCMP_ACT_ALLOW,
    				 seccomp_syscall_resolve_name(syscalls[i]), 0);
    	}
    	seccomp_load(ctx);
    	seccomp_release(ctx);
}
EOF
)

allow_uretprobe_filter=$(cat << EOF
{
    	scmp_filter_ctx ctx;
    
    	ctx = seccomp_init(SCMP_ACT_KILL);
    	for (int i = 0; i < num_syscalls; i++) {
    		seccomp_rule_add(ctx, SCMP_ACT_ALLOW,
    				 seccomp_syscall_resolve_name(syscalls[i]), 0);
    	}
    	seccomp_rule_add(ctx, SCMP_ACT_ALLOW, 335, 0);
    	seccomp_load(ctx);
    	seccomp_release(ctx);
}
EOF
)

block_uretprobe_filter=$(cat << EOF
{
    	scmp_filter_ctx ctx;
    
    	ctx = seccomp_init(SCMP_ACT_ALLOW);
    	seccomp_rule_add(ctx, SCMP_ACT_KILL, 335, 0);
    	seccomp_load(ctx);
    	seccomp_release(ctx);
}
EOF
)

t()
{
    with_uretprobe=$1;
    filter_name=$2;
    filter=${!filter_name};

    echo "Test: uretprobe $with_uretprobe, filter $filter_name"

    cat > /tmp/x.c << EOF
    #include <stdio.h>
    #include <seccomp.h>
    
    char *syscalls[] = {
    	"exit_group",
    };
    
    __attribute__((noinline)) int probed(void)
    {
    	return 1;
    }
    
    void apply_seccomp_filter(char **syscalls, int num_syscalls)
	$filter
    
    int main(int argc, char *argv[])
    {
    	int num_syscalls = sizeof(syscalls) / sizeof(syscalls[0]);
    
    	apply_seccomp_filter(syscalls, num_syscalls);
    
    	probed();
    
    	return 0;
    }
EOF
    
    cat > /tmp/trace.bt << EOF
    uretprobe:/tmp/x:probed
    {
        printf("ret=%d\n", retval);
    }
EOF
    
    gcc -o /tmp/x /tmp/x.c -lseccomp
    
    $with_uretprobe && {
	$bt /tmp/trace.bt &
	btpid=$!
        sleep 5 # wait for uretprobe attach
    }
    
    /tmp/x
    
    $with_uretprobe && kill $btpid
    
    rm /tmp/x /tmp/x.c /tmp/trace.bt
}

t false "default_allow_filter"
t true "default_allow_filter"
t false "default_block_filter"
t true "default_block_filter"
t false "allow_uretprobe_filter"
t true "allow_uretprobe_filter"
t false "block_uretprobe_filter"
t true "block_uretprobe_filter"

[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux