diff mbox series

[bpf-next] bpf: Add rcu ptr in btf_id_sock_common_types

Message ID 20241008080916.44724-1-lulie@linux.alibaba.com (mailing list archive)
State Changes Requested
Delegated to: BPF
Headers show
Series [bpf-next] bpf: Add rcu ptr in btf_id_sock_common_types | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-0 success Logs for Lint
bpf/vmtest-bpf-next-VM_Test-3 success Logs for Validate matrix.py
bpf/vmtest-bpf-next-VM_Test-2 success Logs for Unittests
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-5 success Logs for aarch64-gcc / build-release
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for bpf-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 6 this patch: 6
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 13 of 13 maintainers
netdev/build_clang success Errors and warnings before: 6 this patch: 6
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 15 this patch: 15
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 7 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-4 success Logs for aarch64-gcc / build / build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-17 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-10 success Logs for aarch64-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-15 success Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-11 success Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-12 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-18 success Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-19 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-next-VM_Test-16 success Logs for s390x-gcc / veristat
bpf/vmtest-bpf-next-VM_Test-20 success Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-24 success Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-25 success Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-29 success Logs for x86_64-llvm-17 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-26 success Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-32 success Logs for x86_64-llvm-17 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-33 success Logs for x86_64-llvm-17 / veristat
bpf/vmtest-bpf-next-VM_Test-28 success Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17-O2
bpf/vmtest-bpf-next-VM_Test-35 success Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18-O2
bpf/vmtest-bpf-next-VM_Test-36 success Logs for x86_64-llvm-18 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-41 success Logs for x86_64-llvm-18 / veristat
bpf/vmtest-bpf-next-VM_Test-34 success Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-40 success Logs for x86_64-llvm-18 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-7 success Logs for aarch64-gcc / test (test_progs, false, 360) / test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-6 success Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-8 success Logs for aarch64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-14 success Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-30 success Logs for x86_64-llvm-17 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-22 success Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-31 success Logs for x86_64-llvm-17 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-17
bpf/vmtest-bpf-next-VM_Test-21 success Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-39 success Logs for x86_64-llvm-18 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-37 success Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-38 success Logs for x86_64-llvm-18 / test (test_progs_cpuv4, false, 360) / test_progs_cpuv4 on x86_64 with llvm-18
bpf/vmtest-bpf-next-VM_Test-13 success Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc

Commit Message

Philo Lu Oct. 8, 2024, 8:09 a.m. UTC
Sometimes sk is dereferenced as an rcu ptr, such as skb->sk in tp_btf,
which is a valid type of sock common. Then helpers like bpf_skc_to_*()
can be used with skb->sk.

For example, the following prog will be rejected without this patch:
```
SEC("tp_btf/tcp_bad_csum")
int BPF_PROG(tcp_bad_csum, struct sk_buff* skb)
{
	struct sock *sk = skb->sk;
	struct tcp_sock *tp;

	if (!sk)
		return 0;
	tp = bpf_skc_to_tcp_sock(sk);

	return 0;
}
```

Signed-off-by: Philo Lu <lulie@linux.alibaba.com>
---
 kernel/bpf/verifier.c | 1 +
 1 file changed, 1 insertion(+)

Comments

Martin KaFai Lau Oct. 8, 2024, 7:05 p.m. UTC | #1
On 10/8/24 1:09 AM, Philo Lu wrote:
> Sometimes sk is dereferenced as an rcu ptr, such as skb->sk in tp_btf,
> which is a valid type of sock common. Then helpers like bpf_skc_to_*()
> can be used with skb->sk.
> 
> For example, the following prog will be rejected without this patch:
> ```
> SEC("tp_btf/tcp_bad_csum")
> int BPF_PROG(tcp_bad_csum, struct sk_buff* skb)
> {
> 	struct sock *sk = skb->sk;
> 	struct tcp_sock *tp;
> 
> 	if (!sk)
> 		return 0;
> 	tp = bpf_skc_to_tcp_sock(sk);

If the use case is for reading the fields in tp, please use the bpf_core_cast 
from the libbpf's bpf_core_read.h. bpf_core_cast is using the bpf_rdonly_cast 
kfunc underneath.

pw-bot: cr
Philo Lu Oct. 9, 2024, 2:23 a.m. UTC | #2
On 2024/10/9 03:05, Martin KaFai Lau wrote:
> On 10/8/24 1:09 AM, Philo Lu wrote:
>> Sometimes sk is dereferenced as an rcu ptr, such as skb->sk in tp_btf,
>> which is a valid type of sock common. Then helpers like bpf_skc_to_*()
>> can be used with skb->sk.
>>
>> For example, the following prog will be rejected without this patch:
>> ```
>> SEC("tp_btf/tcp_bad_csum")
>> int BPF_PROG(tcp_bad_csum, struct sk_buff* skb)
>> {
>>     struct sock *sk = skb->sk;
>>     struct tcp_sock *tp;
>>
>>     if (!sk)
>>         return 0;
>>     tp = bpf_skc_to_tcp_sock(sk);
> 
> If the use case is for reading the fields in tp, please use the 
> bpf_core_cast from the libbpf's bpf_core_read.h. bpf_core_cast is using 
> the bpf_rdonly_cast kfunc underneath.
> 

Thank you! This works for me so this patch is unnecessary then.

Just curious is there any technical issue to include rcu_ptr into 
btf_id_sock_common_types? AFAICT rcu_ptr should also be a valid ptr 
type, and then btf_id_sock_common_types will behave like (PTR_TO_BTF_ID 
+ &btf_sock_ids[BTF_SOCK_TYPE_SOCK_COMMON]) in bpf_func_proto.

Thanks.
Martin KaFai Lau Oct. 10, 2024, 10:07 p.m. UTC | #3
On 10/8/24 7:23 PM, Philo Lu wrote:
> 
> 
> On 2024/10/9 03:05, Martin KaFai Lau wrote:
>> On 10/8/24 1:09 AM, Philo Lu wrote:
>>> Sometimes sk is dereferenced as an rcu ptr, such as skb->sk in tp_btf,
>>> which is a valid type of sock common. Then helpers like bpf_skc_to_*()
>>> can be used with skb->sk.
>>>
>>> For example, the following prog will be rejected without this patch:
>>> ```
>>> SEC("tp_btf/tcp_bad_csum")
>>> int BPF_PROG(tcp_bad_csum, struct sk_buff* skb)
>>> {
>>>     struct sock *sk = skb->sk;
>>>     struct tcp_sock *tp;
>>>
>>>     if (!sk)
>>>         return 0;
>>>     tp = bpf_skc_to_tcp_sock(sk);
>>
>> If the use case is for reading the fields in tp, please use the bpf_core_cast 
>> from the libbpf's bpf_core_read.h. bpf_core_cast is using the bpf_rdonly_cast 
>> kfunc underneath.
>>
> 
> Thank you! This works for me so this patch is unnecessary then.
> 
> Just curious is there any technical issue to include rcu_ptr into 
> btf_id_sock_common_types? AFAICT rcu_ptr should also be a valid ptr type, and 
> then btf_id_sock_common_types will behave like (PTR_TO_BTF_ID + 
> &btf_sock_ids[BTF_SOCK_TYPE_SOCK_COMMON]) in bpf_func_proto.

bpf_skc_to_*() returns a PTR_TO_BTF_ID which can be passed into other helpers 
that takes ARG_PTR_TO_BTF_ID_SOCK_COMMON. There are helpers that change the sk. 
e.g. bpf_setsockopt() changes the sk and needs sk to be locked. Other non 
tracing hooks do have a hold on the skb also. I did take a quick look at the 
bpf_setsockopt situation and looks ok. I am positive there are other helpers 
that need to audit first.

Tracing use case should only read the sk. bpf_core_cast() is the correct one to 
use. The bpf_sk_storage_{get,delete}() should be the only allowed helper that 
can change the sk.
Philo Lu Oct. 11, 2024, 1:46 a.m. UTC | #4
On 2024/10/11 06:07, Martin KaFai Lau wrote:
> On 10/8/24 7:23 PM, Philo Lu wrote:
>>
>>
>> On 2024/10/9 03:05, Martin KaFai Lau wrote:
>>> On 10/8/24 1:09 AM, Philo Lu wrote:
>>>> Sometimes sk is dereferenced as an rcu ptr, such as skb->sk in tp_btf,
>>>> which is a valid type of sock common. Then helpers like bpf_skc_to_*()
>>>> can be used with skb->sk.
>>>>
>>>> For example, the following prog will be rejected without this patch:
>>>> ```
>>>> SEC("tp_btf/tcp_bad_csum")
>>>> int BPF_PROG(tcp_bad_csum, struct sk_buff* skb)
>>>> {
>>>>     struct sock *sk = skb->sk;
>>>>     struct tcp_sock *tp;
>>>>
>>>>     if (!sk)
>>>>         return 0;
>>>>     tp = bpf_skc_to_tcp_sock(sk);
>>>
>>> If the use case is for reading the fields in tp, please use the 
>>> bpf_core_cast from the libbpf's bpf_core_read.h. bpf_core_cast is 
>>> using the bpf_rdonly_cast kfunc underneath.
>>>
>>
>> Thank you! This works for me so this patch is unnecessary then.
>>
>> Just curious is there any technical issue to include rcu_ptr into 
>> btf_id_sock_common_types? AFAICT rcu_ptr should also be a valid ptr 
>> type, and then btf_id_sock_common_types will behave like 
>> (PTR_TO_BTF_ID + &btf_sock_ids[BTF_SOCK_TYPE_SOCK_COMMON]) in 
>> bpf_func_proto.
> 
> bpf_skc_to_*() returns a PTR_TO_BTF_ID which can be passed into other 
> helpers that takes ARG_PTR_TO_BTF_ID_SOCK_COMMON. There are helpers that 
> change the sk. e.g. bpf_setsockopt() changes the sk and needs sk to be 
> locked. Other non tracing hooks do have a hold on the skb also. I did 
> take a quick look at the bpf_setsockopt situation and looks ok. I am 
> positive there are other helpers that need to audit first.
> 
> Tracing use case should only read the sk. bpf_core_cast() is the correct 
> one to use. The bpf_sk_storage_{get,delete}() should be the only allowed 
> helper that can change the sk.

Thank you for explanation, Martin. This helps me a lot.
diff mbox series

Patch

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 9a7ed527e47e..3e7ce448ae03 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -8362,6 +8362,7 @@  static const struct bpf_reg_types btf_id_sock_common_types = {
 		PTR_TO_XDP_SOCK,
 		PTR_TO_BTF_ID,
 		PTR_TO_BTF_ID | PTR_TRUSTED,
+		PTR_TO_BTF_ID | MEM_RCU,
 	},
 	.btf_id = &btf_sock_ids[BTF_SOCK_TYPE_SOCK_COMMON],
 };