diff mbox series

[bpf] bpf: Add sk_is_inet check in tls_sw_has_ctx_tx/rx

Message ID 20241029202830.3121552-1-zijianzhang@bytedance.com (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series [bpf] bpf: Add sk_is_inet check in tls_sw_has_ctx_tx/rx | expand

Checks

Context Check Description
bpf/vmtest-bpf-PR success PR summary
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for bpf
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 5 this patch: 5
netdev/build_tools success Errors and warnings before: 157 (+0) this patch: 157 (+0)
netdev/cc_maintainers warning 1 maintainers not CCed: netdev@vger.kernel.org
netdev/build_clang success Errors and warnings before: 3 this patch: 3
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 Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 63 this patch: 63
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 26 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-VM_Test-5 success Logs for aarch64-gcc / build-release
bpf/vmtest-bpf-VM_Test-0 success Logs for Lint
bpf/vmtest-bpf-VM_Test-2 success Logs for Unittests
bpf/vmtest-bpf-VM_Test-3 success Logs for Validate matrix.py
bpf/vmtest-bpf-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-VM_Test-17 success Logs for set-matrix
bpf/vmtest-bpf-VM_Test-6 success Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-21 success Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
bpf/vmtest-bpf-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-VM_Test-35 success Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18-O2
bpf/vmtest-bpf-VM_Test-27 success Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
bpf/vmtest-bpf-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-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-VM_Test-4 success Logs for aarch64-gcc / build / build for aarch64 with gcc
bpf/vmtest-bpf-VM_Test-28 success Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17-O2
bpf/vmtest-bpf-VM_Test-10 success Logs for aarch64-gcc / veristat
bpf/vmtest-bpf-VM_Test-19 success Logs for x86_64-gcc / build-release
bpf/vmtest-bpf-VM_Test-15 success Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
bpf/vmtest-bpf-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-VM_Test-41 success Logs for x86_64-llvm-18 / veristat
bpf/vmtest-bpf-VM_Test-25 success Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
bpf/vmtest-bpf-VM_Test-33 success Logs for x86_64-llvm-17 / veristat
bpf/vmtest-bpf-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-VM_Test-16 success Logs for s390x-gcc / veristat
bpf/vmtest-bpf-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-VM_Test-18 success Logs for x86_64-gcc / build / build for x86_64 with gcc
bpf/vmtest-bpf-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-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-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-VM_Test-26 success Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
bpf/vmtest-bpf-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-VM_Test-9 success Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-12 success Logs for s390x-gcc / build-release
bpf/vmtest-bpf-VM_Test-34 success Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
bpf/vmtest-bpf-VM_Test-11 success Logs for s390x-gcc / build / build for s390x with gcc
bpf/vmtest-bpf-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-VM_Test-20 success Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
bpf/vmtest-bpf-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-VM_Test-7 success Logs for aarch64-gcc / test (test_progs, false, 360) / test_progs on aarch64 with gcc
bpf/vmtest-bpf-VM_Test-13 success Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc
bpf/vmtest-bpf-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-VM_Test-14 success Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc

Commit Message

Zijian Zhang Oct. 29, 2024, 8:28 p.m. UTC
From: Zijian Zhang <zijianzhang@bytedance.com>

As the introduction of the support for vsock and unix sockets in sockmap,
tls_sw_has_ctx_tx/rx cannot presume the socket passed in must be inet.
Otherwise, tls_get_ctx may return an invalid pointer and result in page
fault in function tls_sw_ctx_rx.

BUG: unable to handle page fault for address: 0000000000040030
Workqueue: vsock-loopback vsock_loopback_work
RIP: 0010:sk_psock_strp_data_ready+0x23/0x60
Call Trace:
 ? __die+0x81/0xc3
 ? no_context+0x194/0x350
 ? do_page_fault+0x30/0x110
 ? async_page_fault+0x3e/0x50
 ? sk_psock_strp_data_ready+0x23/0x60
 virtio_transport_recv_pkt+0x750/0x800
 ? update_load_avg+0x7e/0x620
 vsock_loopback_work+0xd0/0x100
 process_one_work+0x1a7/0x360
 worker_thread+0x30/0x390
 ? create_worker+0x1a0/0x1a0
 kthread+0x112/0x130
 ? __kthread_cancel_work+0x40/0x40
 ret_from_fork+0x1f/0x40

Fixes: 0608c69c9a80 ("bpf: sk_msg, sock{map|hash} redirect through ULP")
Fixes: e91de6afa81c ("bpf: Fix running sk_skb program types with ktls")

Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
---
 include/net/tls.h | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

Comments

Stanislav Fomichev Oct. 29, 2024, 11:07 p.m. UTC | #1
On 10/29, zijianzhang@bytedance.com wrote:
> From: Zijian Zhang <zijianzhang@bytedance.com>
> 
> As the introduction of the support for vsock and unix sockets in sockmap,
> tls_sw_has_ctx_tx/rx cannot presume the socket passed in must be inet.
> Otherwise, tls_get_ctx may return an invalid pointer and result in page
> fault in function tls_sw_ctx_rx.
> 
> BUG: unable to handle page fault for address: 0000000000040030
> Workqueue: vsock-loopback vsock_loopback_work
> RIP: 0010:sk_psock_strp_data_ready+0x23/0x60
> Call Trace:
>  ? __die+0x81/0xc3
>  ? no_context+0x194/0x350
>  ? do_page_fault+0x30/0x110
>  ? async_page_fault+0x3e/0x50
>  ? sk_psock_strp_data_ready+0x23/0x60
>  virtio_transport_recv_pkt+0x750/0x800
>  ? update_load_avg+0x7e/0x620
>  vsock_loopback_work+0xd0/0x100
>  process_one_work+0x1a7/0x360
>  worker_thread+0x30/0x390
>  ? create_worker+0x1a0/0x1a0
>  kthread+0x112/0x130
>  ? __kthread_cancel_work+0x40/0x40
>  ret_from_fork+0x1f/0x40
> 
> Fixes: 0608c69c9a80 ("bpf: sk_msg, sock{map|hash} redirect through ULP")
> Fixes: e91de6afa81c ("bpf: Fix running sk_skb program types with ktls")
> 
> Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
> ---
>  include/net/tls.h | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/include/net/tls.h b/include/net/tls.h
> index 3a33924db2bc..a65939c7ad61 100644
> --- a/include/net/tls.h
> +++ b/include/net/tls.h
> @@ -390,8 +390,12 @@ tls_offload_ctx_tx(const struct tls_context *tls_ctx)
>  
>  static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
>  {
> -	struct tls_context *ctx = tls_get_ctx(sk);
> +	struct tls_context *ctx;
> +
> +	if (!sk_is_inet(sk))
> +		return false;
>  
> +	ctx = tls_get_ctx(sk);
>  	if (!ctx)
>  		return false;
>  	return !!tls_sw_ctx_tx(ctx);
> @@ -399,8 +403,12 @@ static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
>  
>  static inline bool tls_sw_has_ctx_rx(const struct sock *sk)
>  {
> -	struct tls_context *ctx = tls_get_ctx(sk);
> +	struct tls_context *ctx;
> +
> +	if (!sk_is_inet(sk))
> +		return false;
>  
> +	ctx = tls_get_ctx(sk);
>  	if (!ctx)
>  		return false;
>  	return !!tls_sw_ctx_rx(ctx);

This seems like a strange place to fix it. Why does tls_get_ctx return
invalid pointer for non-tls/ulp sockets? Shouldn't it be NULL?
Is sockmap even supposed to work with vsock?
Zijian Zhang Oct. 29, 2024, 11:37 p.m. UTC | #2
On 10/29/24 4:07 PM, Stanislav Fomichev wrote:
> On 10/29, zijianzhang@bytedance.com wrote:
>> From: Zijian Zhang <zijianzhang@bytedance.com>
>>
>> As the introduction of the support for vsock and unix sockets in sockmap,
>> tls_sw_has_ctx_tx/rx cannot presume the socket passed in must be inet.
>> Otherwise, tls_get_ctx may return an invalid pointer and result in page
>> fault in function tls_sw_ctx_rx.
>>
>> BUG: unable to handle page fault for address: 0000000000040030
>> Workqueue: vsock-loopback vsock_loopback_work
>> RIP: 0010:sk_psock_strp_data_ready+0x23/0x60
>> Call Trace:
>>   ? __die+0x81/0xc3
>>   ? no_context+0x194/0x350
>>   ? do_page_fault+0x30/0x110
>>   ? async_page_fault+0x3e/0x50
>>   ? sk_psock_strp_data_ready+0x23/0x60
>>   virtio_transport_recv_pkt+0x750/0x800
>>   ? update_load_avg+0x7e/0x620
>>   vsock_loopback_work+0xd0/0x100
>>   process_one_work+0x1a7/0x360
>>   worker_thread+0x30/0x390
>>   ? create_worker+0x1a0/0x1a0
>>   kthread+0x112/0x130
>>   ? __kthread_cancel_work+0x40/0x40
>>   ret_from_fork+0x1f/0x40
>>
>> Fixes: 0608c69c9a80 ("bpf: sk_msg, sock{map|hash} redirect through ULP")
>> Fixes: e91de6afa81c ("bpf: Fix running sk_skb program types with ktls")
>>
>> Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
>> ---
>>   include/net/tls.h | 12 ++++++++++--
>>   1 file changed, 10 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/net/tls.h b/include/net/tls.h
>> index 3a33924db2bc..a65939c7ad61 100644
>> --- a/include/net/tls.h
>> +++ b/include/net/tls.h
>> @@ -390,8 +390,12 @@ tls_offload_ctx_tx(const struct tls_context *tls_ctx)
>>   
>>   static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
>>   {
>> -	struct tls_context *ctx = tls_get_ctx(sk);
>> +	struct tls_context *ctx;
>> +
>> +	if (!sk_is_inet(sk))
>> +		return false;
>>   
>> +	ctx = tls_get_ctx(sk);
>>   	if (!ctx)
>>   		return false;
>>   	return !!tls_sw_ctx_tx(ctx);
>> @@ -399,8 +403,12 @@ static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
>>   
>>   static inline bool tls_sw_has_ctx_rx(const struct sock *sk)
>>   {
>> -	struct tls_context *ctx = tls_get_ctx(sk);
>> +	struct tls_context *ctx;
>> +
>> +	if (!sk_is_inet(sk))
>> +		return false;
>>   
>> +	ctx = tls_get_ctx(sk);
>>   	if (!ctx)
>>   		return false;
>>   	return !!tls_sw_ctx_rx(ctx);
> 
> This seems like a strange place to fix it. Why does tls_get_ctx return
> invalid pointer for non-tls/ulp sockets? Shouldn't it be NULL?
> Is sockmap even supposed to work with vsock?

Here is my understanding, please correct me if I am wrong :)
```
static inline struct tls_context *tls_get_ctx(const struct sock *sk)
{
	const struct inet_connection_sock *icsk = inet_csk(sk);
	return (__force void *)icsk->icsk_ulp_data;
}
```
tls_get_ctx assumes the socket passed is icsk_socket. However, unix
and vsock do not have inet_connection_sock, they have unix_sock and
vsock_sock. The offset of icsk_ulp_data are meaningless for them, and
they might point to some other values which might not be NULL.

Afaik, sockmap started to support vsock in 634f1a7110b4 ("vsock: support
sockmap"), and support unix in 94531cfcbe79 ("af_unix: Add
unix_stream_proto for sockmap").

If the above is correct, I find that using inet_test_bit(IS_ICSK, sk)
instead of sk_is_inet will be more accurate.
Stanislav Fomichev Oct. 30, 2024, 12:22 a.m. UTC | #3
On 10/29, Zijian Zhang wrote:
> 
> 
> On 10/29/24 4:07 PM, Stanislav Fomichev wrote:
> > On 10/29, zijianzhang@bytedance.com wrote:
> > > From: Zijian Zhang <zijianzhang@bytedance.com>
> > > 
> > > As the introduction of the support for vsock and unix sockets in sockmap,
> > > tls_sw_has_ctx_tx/rx cannot presume the socket passed in must be inet.
> > > Otherwise, tls_get_ctx may return an invalid pointer and result in page
> > > fault in function tls_sw_ctx_rx.
> > > 
> > > BUG: unable to handle page fault for address: 0000000000040030
> > > Workqueue: vsock-loopback vsock_loopback_work
> > > RIP: 0010:sk_psock_strp_data_ready+0x23/0x60
> > > Call Trace:
> > >   ? __die+0x81/0xc3
> > >   ? no_context+0x194/0x350
> > >   ? do_page_fault+0x30/0x110
> > >   ? async_page_fault+0x3e/0x50
> > >   ? sk_psock_strp_data_ready+0x23/0x60
> > >   virtio_transport_recv_pkt+0x750/0x800
> > >   ? update_load_avg+0x7e/0x620
> > >   vsock_loopback_work+0xd0/0x100
> > >   process_one_work+0x1a7/0x360
> > >   worker_thread+0x30/0x390
> > >   ? create_worker+0x1a0/0x1a0
> > >   kthread+0x112/0x130
> > >   ? __kthread_cancel_work+0x40/0x40
> > >   ret_from_fork+0x1f/0x40
> > > 
> > > Fixes: 0608c69c9a80 ("bpf: sk_msg, sock{map|hash} redirect through ULP")
> > > Fixes: e91de6afa81c ("bpf: Fix running sk_skb program types with ktls")
> > > 
> > > Signed-off-by: Zijian Zhang <zijianzhang@bytedance.com>
> > > ---
> > >   include/net/tls.h | 12 ++++++++++--
> > >   1 file changed, 10 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/include/net/tls.h b/include/net/tls.h
> > > index 3a33924db2bc..a65939c7ad61 100644
> > > --- a/include/net/tls.h
> > > +++ b/include/net/tls.h
> > > @@ -390,8 +390,12 @@ tls_offload_ctx_tx(const struct tls_context *tls_ctx)
> > >   static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
> > >   {
> > > -	struct tls_context *ctx = tls_get_ctx(sk);
> > > +	struct tls_context *ctx;
> > > +
> > > +	if (!sk_is_inet(sk))
> > > +		return false;
> > > +	ctx = tls_get_ctx(sk);
> > >   	if (!ctx)
> > >   		return false;
> > >   	return !!tls_sw_ctx_tx(ctx);
> > > @@ -399,8 +403,12 @@ static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
> > >   static inline bool tls_sw_has_ctx_rx(const struct sock *sk)
> > >   {
> > > -	struct tls_context *ctx = tls_get_ctx(sk);
> > > +	struct tls_context *ctx;
> > > +
> > > +	if (!sk_is_inet(sk))
> > > +		return false;
> > > +	ctx = tls_get_ctx(sk);
> > >   	if (!ctx)
> > >   		return false;
> > >   	return !!tls_sw_ctx_rx(ctx);
> > 
> > This seems like a strange place to fix it. Why does tls_get_ctx return
> > invalid pointer for non-tls/ulp sockets? Shouldn't it be NULL?
> > Is sockmap even supposed to work with vsock?
> 
> Here is my understanding, please correct me if I am wrong :)
> ```
> static inline struct tls_context *tls_get_ctx(const struct sock *sk)
> {
> 	const struct inet_connection_sock *icsk = inet_csk(sk);
> 	return (__force void *)icsk->icsk_ulp_data;
> }
> ```
> tls_get_ctx assumes the socket passed is icsk_socket. However, unix
> and vsock do not have inet_connection_sock, they have unix_sock and
> vsock_sock. The offset of icsk_ulp_data are meaningless for them, and
> they might point to some other values which might not be NULL.
> 
> Afaik, sockmap started to support vsock in 634f1a7110b4 ("vsock: support
> sockmap"), and support unix in 94531cfcbe79 ("af_unix: Add
> unix_stream_proto for sockmap").
> 
> If the above is correct, I find that using inet_test_bit(IS_ICSK, sk)
> instead of sk_is_inet will be more accurate.

Thanks for the context, makes sense. And consolidating this sk_is_inet
check inside tls_get_ctx is worse because it gets called outside of
sockmap?
Zijian Zhang Oct. 30, 2024, 12:55 a.m. UTC | #4
On 10/29/24 5:22 PM, Stanislav Fomichev wrote:
> On 10/29, Zijian Zhang wrote:
>>
>>
>> On 10/29/24 4:07 PM, Stanislav Fomichev wrote:
>>> On 10/29, zijianzhang@bytedance.com wrote:
...
>>>> diff --git a/include/net/tls.h b/include/net/tls.h
>>>> index 3a33924db2bc..a65939c7ad61 100644
>>>> --- a/include/net/tls.h
>>>> +++ b/include/net/tls.h
>>>> @@ -390,8 +390,12 @@ tls_offload_ctx_tx(const struct tls_context *tls_ctx)
>>>>    static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
>>>>    {
>>>> -	struct tls_context *ctx = tls_get_ctx(sk);
>>>> +	struct tls_context *ctx;
>>>> +
>>>> +	if (!sk_is_inet(sk))
>>>> +		return false;
>>>> +	ctx = tls_get_ctx(sk);
>>>>    	if (!ctx)
>>>>    		return false;
>>>>    	return !!tls_sw_ctx_tx(ctx);
>>>> @@ -399,8 +403,12 @@ static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
>>>>    static inline bool tls_sw_has_ctx_rx(const struct sock *sk)
>>>>    {
>>>> -	struct tls_context *ctx = tls_get_ctx(sk);
>>>> +	struct tls_context *ctx;
>>>> +
>>>> +	if (!sk_is_inet(sk))
>>>> +		return false;
>>>> +	ctx = tls_get_ctx(sk);
>>>>    	if (!ctx)
>>>>    		return false;
>>>>    	return !!tls_sw_ctx_rx(ctx);
>>>
>>> This seems like a strange place to fix it. Why does tls_get_ctx return
>>> invalid pointer for non-tls/ulp sockets? Shouldn't it be NULL?
>>> Is sockmap even supposed to work with vsock?
>>
>> Here is my understanding, please correct me if I am wrong :)
>> ```
>> static inline struct tls_context *tls_get_ctx(const struct sock *sk)
>> {
>> 	const struct inet_connection_sock *icsk = inet_csk(sk);
>> 	return (__force void *)icsk->icsk_ulp_data;
>> }
>> ```
>> tls_get_ctx assumes the socket passed is icsk_socket. However, unix
>> and vsock do not have inet_connection_sock, they have unix_sock and
>> vsock_sock. The offset of icsk_ulp_data are meaningless for them, and
>> they might point to some other values which might not be NULL.
>>
>> Afaik, sockmap started to support vsock in 634f1a7110b4 ("vsock: support
>> sockmap"), and support unix in 94531cfcbe79 ("af_unix: Add
>> unix_stream_proto for sockmap").
>>
>> If the above is correct, I find that using inet_test_bit(IS_ICSK, sk)
>> instead of sk_is_inet will be more accurate.
> 
> Thanks for the context, makes sense. And consolidating this sk_is_inet
> check inside tls_get_ctx is worse because it gets called outside of
> sockmap?

Yes, tls_get_ctx is invoked in multiple locations, and I want to only
fix sockmap related calls.
Stanislav Fomichev Oct. 30, 2024, 3:38 p.m. UTC | #5
On 10/29, Zijian Zhang wrote:
> 
> On 10/29/24 5:22 PM, Stanislav Fomichev wrote:
> > On 10/29, Zijian Zhang wrote:
> > > 
> > > 
> > > On 10/29/24 4:07 PM, Stanislav Fomichev wrote:
> > > > On 10/29, zijianzhang@bytedance.com wrote:
> ...
> > > > > diff --git a/include/net/tls.h b/include/net/tls.h
> > > > > index 3a33924db2bc..a65939c7ad61 100644
> > > > > --- a/include/net/tls.h
> > > > > +++ b/include/net/tls.h
> > > > > @@ -390,8 +390,12 @@ tls_offload_ctx_tx(const struct tls_context *tls_ctx)
> > > > >    static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
> > > > >    {
> > > > > -	struct tls_context *ctx = tls_get_ctx(sk);
> > > > > +	struct tls_context *ctx;
> > > > > +
> > > > > +	if (!sk_is_inet(sk))
> > > > > +		return false;
> > > > > +	ctx = tls_get_ctx(sk);
> > > > >    	if (!ctx)
> > > > >    		return false;
> > > > >    	return !!tls_sw_ctx_tx(ctx);
> > > > > @@ -399,8 +403,12 @@ static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
> > > > >    static inline bool tls_sw_has_ctx_rx(const struct sock *sk)
> > > > >    {
> > > > > -	struct tls_context *ctx = tls_get_ctx(sk);
> > > > > +	struct tls_context *ctx;
> > > > > +
> > > > > +	if (!sk_is_inet(sk))
> > > > > +		return false;
> > > > > +	ctx = tls_get_ctx(sk);
> > > > >    	if (!ctx)
> > > > >    		return false;
> > > > >    	return !!tls_sw_ctx_rx(ctx);
> > > > 
> > > > This seems like a strange place to fix it. Why does tls_get_ctx return
> > > > invalid pointer for non-tls/ulp sockets? Shouldn't it be NULL?
> > > > Is sockmap even supposed to work with vsock?
> > > 
> > > Here is my understanding, please correct me if I am wrong :)
> > > ```
> > > static inline struct tls_context *tls_get_ctx(const struct sock *sk)
> > > {
> > > 	const struct inet_connection_sock *icsk = inet_csk(sk);
> > > 	return (__force void *)icsk->icsk_ulp_data;
> > > }
> > > ```
> > > tls_get_ctx assumes the socket passed is icsk_socket. However, unix
> > > and vsock do not have inet_connection_sock, they have unix_sock and
> > > vsock_sock. The offset of icsk_ulp_data are meaningless for them, and
> > > they might point to some other values which might not be NULL.
> > > 
> > > Afaik, sockmap started to support vsock in 634f1a7110b4 ("vsock: support
> > > sockmap"), and support unix in 94531cfcbe79 ("af_unix: Add
> > > unix_stream_proto for sockmap").
> > > 
> > > If the above is correct, I find that using inet_test_bit(IS_ICSK, sk)
> > > instead of sk_is_inet will be more accurate.
> > 
> > Thanks for the context, makes sense. And consolidating this sk_is_inet
> > check inside tls_get_ctx is worse because it gets called outside of
> > sockmap?
> 
> Yes, tls_get_ctx is invoked in multiple locations, and I want to only
> fix sockmap related calls.

Sounds convincing. Unless John/Jakub have better suggestions:

Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Zijian Zhang Oct. 30, 2024, 4:37 p.m. UTC | #6
On 10/30/24 8:38 AM, Stanislav Fomichev wrote:
> On 10/29, Zijian Zhang wrote:
>>
>> On 10/29/24 5:22 PM, Stanislav Fomichev wrote:
>>> On 10/29, Zijian Zhang wrote:
>>>>
>>>>
>>>> On 10/29/24 4:07 PM, Stanislav Fomichev wrote:
>>>>> On 10/29, zijianzhang@bytedance.com wrote:
>> ...
>>>>>> diff --git a/include/net/tls.h b/include/net/tls.h
>>>>>> index 3a33924db2bc..a65939c7ad61 100644
>>>>>> --- a/include/net/tls.h
>>>>>> +++ b/include/net/tls.h
>>>>>> @@ -390,8 +390,12 @@ tls_offload_ctx_tx(const struct tls_context *tls_ctx)
>>>>>>     static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
>>>>>>     {
>>>>>> -	struct tls_context *ctx = tls_get_ctx(sk);
>>>>>> +	struct tls_context *ctx;
>>>>>> +
>>>>>> +	if (!sk_is_inet(sk))
>>>>>> +		return false;
>>>>>> +	ctx = tls_get_ctx(sk);
>>>>>>     	if (!ctx)
>>>>>>     		return false;
>>>>>>     	return !!tls_sw_ctx_tx(ctx);
>>>>>> @@ -399,8 +403,12 @@ static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
>>>>>>     static inline bool tls_sw_has_ctx_rx(const struct sock *sk)
>>>>>>     {
>>>>>> -	struct tls_context *ctx = tls_get_ctx(sk);
>>>>>> +	struct tls_context *ctx;
>>>>>> +
>>>>>> +	if (!sk_is_inet(sk))
>>>>>> +		return false;
>>>>>> +	ctx = tls_get_ctx(sk);
>>>>>>     	if (!ctx)
>>>>>>     		return false;
>>>>>>     	return !!tls_sw_ctx_rx(ctx);
>>>>>
>>>>> This seems like a strange place to fix it. Why does tls_get_ctx return
>>>>> invalid pointer for non-tls/ulp sockets? Shouldn't it be NULL?
>>>>> Is sockmap even supposed to work with vsock?
>>>>
>>>> Here is my understanding, please correct me if I am wrong :)
>>>> ```
>>>> static inline struct tls_context *tls_get_ctx(const struct sock *sk)
>>>> {
>>>> 	const struct inet_connection_sock *icsk = inet_csk(sk);
>>>> 	return (__force void *)icsk->icsk_ulp_data;
>>>> }
>>>> ```
>>>> tls_get_ctx assumes the socket passed is icsk_socket. However, unix
>>>> and vsock do not have inet_connection_sock, they have unix_sock and
>>>> vsock_sock. The offset of icsk_ulp_data are meaningless for them, and
>>>> they might point to some other values which might not be NULL.
>>>>
>>>> Afaik, sockmap started to support vsock in 634f1a7110b4 ("vsock: support
>>>> sockmap"), and support unix in 94531cfcbe79 ("af_unix: Add
>>>> unix_stream_proto for sockmap").
>>>>
>>>> If the above is correct, I find that using inet_test_bit(IS_ICSK, sk)
>>>> instead of sk_is_inet will be more accurate.
>>>
>>> Thanks for the context, makes sense. And consolidating this sk_is_inet
>>> check inside tls_get_ctx is worse because it gets called outside of
>>> sockmap?
>>
>> Yes, tls_get_ctx is invoked in multiple locations, and I want to only
>> fix sockmap related calls.
> 
> Sounds convincing. Unless John/Jakub have better suggestions:
> 
> Acked-by: Stanislav Fomichev <sdf@fomichev.me>

Thanks for the Ack and reviewing!

In order to make it more accurate, I added inet_test_bit(IS_ICSK, sk)
check in version2. I just found that sk_is_inet only cannot assure
inet_csk is valid. For example, udp_sock does not have inet_connection_sock.
Stanislav Fomichev Oct. 31, 2024, 4:39 p.m. UTC | #7
On 10/30, Zijian Zhang wrote:
> On 10/30/24 8:38 AM, Stanislav Fomichev wrote:
> > On 10/29, Zijian Zhang wrote:
> > > 
> > > On 10/29/24 5:22 PM, Stanislav Fomichev wrote:
> > > > On 10/29, Zijian Zhang wrote:
> > > > > 
> > > > > 
> > > > > On 10/29/24 4:07 PM, Stanislav Fomichev wrote:
> > > > > > On 10/29, zijianzhang@bytedance.com wrote:
> > > ...
> > > > > > > diff --git a/include/net/tls.h b/include/net/tls.h
> > > > > > > index 3a33924db2bc..a65939c7ad61 100644
> > > > > > > --- a/include/net/tls.h
> > > > > > > +++ b/include/net/tls.h
> > > > > > > @@ -390,8 +390,12 @@ tls_offload_ctx_tx(const struct tls_context *tls_ctx)
> > > > > > >     static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
> > > > > > >     {
> > > > > > > -	struct tls_context *ctx = tls_get_ctx(sk);
> > > > > > > +	struct tls_context *ctx;
> > > > > > > +
> > > > > > > +	if (!sk_is_inet(sk))
> > > > > > > +		return false;
> > > > > > > +	ctx = tls_get_ctx(sk);
> > > > > > >     	if (!ctx)
> > > > > > >     		return false;
> > > > > > >     	return !!tls_sw_ctx_tx(ctx);
> > > > > > > @@ -399,8 +403,12 @@ static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
> > > > > > >     static inline bool tls_sw_has_ctx_rx(const struct sock *sk)
> > > > > > >     {
> > > > > > > -	struct tls_context *ctx = tls_get_ctx(sk);
> > > > > > > +	struct tls_context *ctx;
> > > > > > > +
> > > > > > > +	if (!sk_is_inet(sk))
> > > > > > > +		return false;
> > > > > > > +	ctx = tls_get_ctx(sk);
> > > > > > >     	if (!ctx)
> > > > > > >     		return false;
> > > > > > >     	return !!tls_sw_ctx_rx(ctx);
> > > > > > 
> > > > > > This seems like a strange place to fix it. Why does tls_get_ctx return
> > > > > > invalid pointer for non-tls/ulp sockets? Shouldn't it be NULL?
> > > > > > Is sockmap even supposed to work with vsock?
> > > > > 
> > > > > Here is my understanding, please correct me if I am wrong :)
> > > > > ```
> > > > > static inline struct tls_context *tls_get_ctx(const struct sock *sk)
> > > > > {
> > > > > 	const struct inet_connection_sock *icsk = inet_csk(sk);
> > > > > 	return (__force void *)icsk->icsk_ulp_data;
> > > > > }
> > > > > ```
> > > > > tls_get_ctx assumes the socket passed is icsk_socket. However, unix
> > > > > and vsock do not have inet_connection_sock, they have unix_sock and
> > > > > vsock_sock. The offset of icsk_ulp_data are meaningless for them, and
> > > > > they might point to some other values which might not be NULL.
> > > > > 
> > > > > Afaik, sockmap started to support vsock in 634f1a7110b4 ("vsock: support
> > > > > sockmap"), and support unix in 94531cfcbe79 ("af_unix: Add
> > > > > unix_stream_proto for sockmap").
> > > > > 
> > > > > If the above is correct, I find that using inet_test_bit(IS_ICSK, sk)
> > > > > instead of sk_is_inet will be more accurate.
> > > > 
> > > > Thanks for the context, makes sense. And consolidating this sk_is_inet
> > > > check inside tls_get_ctx is worse because it gets called outside of
> > > > sockmap?
> > > 
> > > Yes, tls_get_ctx is invoked in multiple locations, and I want to only
> > > fix sockmap related calls.
> > 
> > Sounds convincing. Unless John/Jakub have better suggestions:
> > 
> > Acked-by: Stanislav Fomichev <sdf@fomichev.me>
> 
> Thanks for the Ack and reviewing!
> 
> In order to make it more accurate, I added inet_test_bit(IS_ICSK, sk)
> check in version2. I just found that sk_is_inet only cannot assure
> inet_csk is valid. For example, udp_sock does not have inet_connection_sock.

Instead of testing IS_ICSK bit, will inet_csk_has_ulp helper work?
Zijian Zhang Oct. 31, 2024, 5:54 p.m. UTC | #8
On 10/31/24 9:39 AM, Stanislav Fomichev wrote:
> On 10/30, Zijian Zhang wrote:
>> On 10/30/24 8:38 AM, Stanislav Fomichev wrote:
>>
>> Thanks for the Ack and reviewing!
>>
>> In order to make it more accurate, I added inet_test_bit(IS_ICSK, sk)
>> check in version2. I just found that sk_is_inet only cannot assure
>> inet_csk is valid. For example, udp_sock does not have inet_connection_sock.
> 
> Instead of testing IS_ICSK bit, will inet_csk_has_ulp helper work?

Nice catch, while testing IS_ICSK bit is sufficient, inet_csk_has_ulp is
a stricter check. I am good with either approach.
diff mbox series

Patch

diff --git a/include/net/tls.h b/include/net/tls.h
index 3a33924db2bc..a65939c7ad61 100644
--- a/include/net/tls.h
+++ b/include/net/tls.h
@@ -390,8 +390,12 @@  tls_offload_ctx_tx(const struct tls_context *tls_ctx)
 
 static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
 {
-	struct tls_context *ctx = tls_get_ctx(sk);
+	struct tls_context *ctx;
+
+	if (!sk_is_inet(sk))
+		return false;
 
+	ctx = tls_get_ctx(sk);
 	if (!ctx)
 		return false;
 	return !!tls_sw_ctx_tx(ctx);
@@ -399,8 +403,12 @@  static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
 
 static inline bool tls_sw_has_ctx_rx(const struct sock *sk)
 {
-	struct tls_context *ctx = tls_get_ctx(sk);
+	struct tls_context *ctx;
+
+	if (!sk_is_inet(sk))
+		return false;
 
+	ctx = tls_get_ctx(sk);
 	if (!ctx)
 		return false;
 	return !!tls_sw_ctx_rx(ctx);