summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorKuniyuki Iwashima <kuniyu@google.com>2026-10-08 03:15:25 +0000
committerAlexei Starovoitov <ast@kernel.org>2026-10-10 16:38:12 +0000
commitc071408db308a8f91d7be71b45bbf2da8c5e15f4 (patch)
tree7fdedb51ef5a9cb4fd6db015f1ee6c72b548636c /include/linux
parent59c25bb6759ae445d2bd431e7166cebec1afa9a2 (diff)
downloadlinux-c071408db308a8f91d7be71b45bbf2da8c5e15f4.tar.gz
linux-c071408db308a8f91d7be71b45bbf2da8c5e15f4.zip
bpf: tcp: Check BPF_SOCK_OPS_TEST_FLAG() after cgroup_bpf_enabled(CGROUP_SOCK_OPS).
BPF_CGROUP_RUN_PROG_XXX() macros guard __cgroup_bpf_run_filter_XXX() with cgroup_bpf_enabled(). However, even when no SOCK_OPS prog is attached, callers still initialise struct bpf_sock_ops_kern (memset(), etc.) or evaluate BPF_SOCK_OPS_TEST_FLAG(), which loads tp->bpf_sock_ops_cb_flags from a cold cacheline near the end of struct tcp_sock. Similar to bpf_tcp_ops, let's check cgroup_bpf_enabled() before BPF_SOCK_OPS_TEST_FLAG() and struct bpf_sock_ops_kern setup, and rename BPF_CGROUP_RUN_PROG_SOCK_OPS{,_SK}() with __ prefix. Since all direct callers of tcp_call_bpf() pass 0 and NULL for nargs and args, they can be folded into the new tcp_call_bpf() macro. All callers of tcp_call_bpf_{2,3}arg() check BPF_SOCK_OPS_TEST_FLAG() and do not need the return value. These are replaced with the new tcp_call_bpf_flag() macro. Now, bpf_skops_hdr_opt_len() and bpf_tcp_ops_hdr_opt_len() are just NOPs without bpf prog attached. $ llvm-objdump -S -D --disassemble=tcp_established_options vmlinux ... ; asm goto(ARCH_STATIC_BRANCH_ASM("%c0 + %c1", "%l[l_yes]") ; size = MAX_TCP_OPTION_SPACE - remaining; ffffffff825127ea: b9 28 00 00 00 movl $0x28, %ecx ffffffff825127ef: 29 c1 subl %eax, %ecx ; return size; ffffffff825127f1: 89 c8 movl %ecx, %eax ... ffffffff825127fb: 2e e9 6f 02 43 00 jmp 0xffffffff82942a70 <__x86_return_thunk> Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Amery Hung <ameryhung@gmail.com> Acked-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20261008031604.256498-6-kuniyu@google.com
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/bpf-cgroup.h36
1 files changed, 14 insertions, 22 deletions
diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index 8a75a6cd7309..02ef7f899b3d 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -345,27 +345,19 @@ static inline bool cgroup_bpf_sock_enabled(struct sock *sk,
* calling bpf_setsockopt on listener-sk will not make sense anyway,
* so passing 'sock_ops->sk == req_sk' to the bpf prog is appropriate here.
*/
-#define BPF_CGROUP_RUN_PROG_SOCK_OPS_SK(sock_ops, sk) \
-({ \
- int __ret = 0; \
- if (cgroup_bpf_enabled(CGROUP_SOCK_OPS)) \
- __ret = __cgroup_bpf_run_filter_sock_ops(sk, \
- sock_ops, \
- CGROUP_SOCK_OPS); \
- __ret; \
-})
-
-#define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) \
-({ \
- int __ret = 0; \
- if (cgroup_bpf_enabled(CGROUP_SOCK_OPS) && (sock_ops)->sk) { \
- typeof(sk) __sk = sk_to_full_sk((sock_ops)->sk); \
- if (__sk && sk_fullsock(__sk)) \
- __ret = __cgroup_bpf_run_filter_sock_ops(__sk, \
- sock_ops, \
- CGROUP_SOCK_OPS); \
- } \
- __ret; \
+#define __BPF_CGROUP_RUN_PROG_SOCK_OPS_SK(sock_ops, sk) \
+ __cgroup_bpf_run_filter_sock_ops(sk, sock_ops, \
+ CGROUP_SOCK_OPS)
+
+#define __BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) \
+({ \
+ int __ret = 0; \
+ typeof(sk) __sk = sk_to_full_sk((sock_ops)->sk); \
+ if (__sk && sk_fullsock(__sk)) \
+ __ret = __cgroup_bpf_run_filter_sock_ops(__sk, \
+ sock_ops, \
+ CGROUP_SOCK_OPS); \
+ __ret; \
})
#define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(atype, major, minor, access) \
@@ -529,7 +521,7 @@ static inline int cgroup_bpf_struct_ops_attach(struct bpf_map *map,
#define BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, uaddr, uaddrlen) ({ 0; })
#define BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, uaddr, uaddrlen) ({ 0; })
#define BPF_CGROUP_RUN_PROG_UNIX_RECVMSG_LOCK(sk, uaddr, uaddrlen) ({ 0; })
-#define BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; })
+#define __BPF_CGROUP_RUN_PROG_SOCK_OPS(sock_ops) ({ 0; })
#define BPF_CGROUP_RUN_PROG_DEVICE_CGROUP(atype, major, minor, access) ({ 0; })
#define BPF_CGROUP_RUN_PROG_SYSCTL(head,table,write,buf,count,pos) ({ 0; })
#define BPF_CGROUP_RUN_PROG_GETSOCKOPT(sock, level, optname, optval, \