mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-29 19:48:36 -04:00
The test installs a kprobe on __sys_connect and checks that bpf_probe_write_user() can modify the syscall argument. However, any concurrent thread in any other test that calls connect() will also trigger the kprobe and have its sockaddr silently overwritten, causing flaky failures in unrelated tests. Constrain the hook to the current test process by filtering on a PID stored as a global variable in .bss. Initialize the .bss value from user space before bpf_object__load() using bpf_map__set_initial_value(), and validate the bss map value size to catch layout mismatches. No new map is introduced and the test keeps the existing non-skeleton flow. Signed-off-by: Sun Jian <sun.jian.kdev@gmail.com> Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Link: https://lore.kernel.org/r/20260306083330.518627-1-sun.jian.kdev@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
57 lines
1.2 KiB
C
57 lines
1.2 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
#include "vmlinux.h"
|
|
#include <bpf/bpf_helpers.h>
|
|
#include <bpf/bpf_tracing.h>
|
|
#include <bpf/bpf_core_read.h>
|
|
#include "bpf_misc.h"
|
|
|
|
struct test_pro_bss {
|
|
struct sockaddr_in old;
|
|
__u32 test_pid;
|
|
};
|
|
|
|
struct test_pro_bss bss;
|
|
|
|
static int handle_sys_connect_common(struct sockaddr_in *uservaddr)
|
|
{
|
|
struct sockaddr_in new;
|
|
__u32 cur = bpf_get_current_pid_tgid() >> 32;
|
|
|
|
if (bss.test_pid && cur != bss.test_pid)
|
|
return 0;
|
|
|
|
bpf_probe_read_user(&bss.old, sizeof(bss.old), uservaddr);
|
|
__builtin_memset(&new, 0xab, sizeof(new));
|
|
bpf_probe_write_user(uservaddr, &new, sizeof(new));
|
|
|
|
return 0;
|
|
}
|
|
|
|
SEC("ksyscall/connect")
|
|
int BPF_KSYSCALL(handle_sys_connect, int fd, struct sockaddr_in *uservaddr,
|
|
int addrlen)
|
|
{
|
|
return handle_sys_connect_common(uservaddr);
|
|
}
|
|
|
|
#if defined(bpf_target_s390)
|
|
#ifndef SYS_CONNECT
|
|
#define SYS_CONNECT 3
|
|
#endif
|
|
|
|
SEC("ksyscall/socketcall")
|
|
int BPF_KSYSCALL(handle_sys_socketcall, int call, unsigned long *args)
|
|
{
|
|
if (call == SYS_CONNECT) {
|
|
struct sockaddr_in *uservaddr;
|
|
|
|
bpf_probe_read_user(&uservaddr, sizeof(uservaddr), &args[1]);
|
|
return handle_sys_connect_common(uservaddr);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
char _license[] SEC("license") = "GPL";
|