diff mbox series

[bpf-next,4/4] bpf, sockmap: Fix double uncharge the mem of sk_msg

Message ID 20220225014929.942444-5-wangyufen@huawei.com (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series bpf, sockmap: Fix memleaks and issues of mem charge/uncharge | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR success PR summary
netdev/tree_selection success Clearly marked for bpf-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 2 this patch: 2
netdev/cc_maintainers success CCed 17 of 17 maintainers
netdev/build_clang success Errors and warnings before: 18 this patch: 18
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 7 this patch: 7
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 8 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next success VM_Test

Commit Message

wangyufen Feb. 25, 2022, 1:49 a.m. UTC
If tcp_bpf_sendmsg is running during a tear down operation, psock may be
freed.

tcp_bpf_sendmsg()
 tcp_bpf_send_verdict()
  sk_msg_return()
  tcp_bpf_sendmsg_redir()
   unlikely(!psock))
   sk_msg_free()

The mem of msg has been uncharged in tcp_bpf_send_verdict() by
sk_msg_return(), so we need to use sk_msg_free_nocharge while psock
is null.

This issue can cause the following info:
WARNING: CPU: 0 PID: 2136 at net/ipv4/af_inet.c:155 inet_sock_destruct+0x13c/0x260
Call Trace:
 <TASK>
 __sk_destruct+0x24/0x1f0
 sk_psock_destroy+0x19b/0x1c0
 process_one_work+0x1b3/0x3c0
 worker_thread+0x30/0x350
 ? process_one_work+0x3c0/0x3c0
 kthread+0xe6/0x110
 ? kthread_complete_and_exit+0x20/0x20
 ret_from_fork+0x22/0x30
 </TASK>

Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
Signed-off-by: Wang Yufen <wangyufen@huawei.com>
---
 net/ipv4/tcp_bpf.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

John Fastabend March 1, 2022, 4:11 a.m. UTC | #1
Wang Yufen wrote:
> If tcp_bpf_sendmsg is running during a tear down operation, psock may be
> freed.
> 
> tcp_bpf_sendmsg()
>  tcp_bpf_send_verdict()
>   sk_msg_return()
>   tcp_bpf_sendmsg_redir()
>    unlikely(!psock))
>    sk_msg_free()
> 
> The mem of msg has been uncharged in tcp_bpf_send_verdict() by
> sk_msg_return(), so we need to use sk_msg_free_nocharge while psock
> is null.
> 
> This issue can cause the following info:
> WARNING: CPU: 0 PID: 2136 at net/ipv4/af_inet.c:155 inet_sock_destruct+0x13c/0x260
> Call Trace:
>  <TASK>
>  __sk_destruct+0x24/0x1f0
>  sk_psock_destroy+0x19b/0x1c0
>  process_one_work+0x1b3/0x3c0
>  worker_thread+0x30/0x350
>  ? process_one_work+0x3c0/0x3c0
>  kthread+0xe6/0x110
>  ? kthread_complete_and_exit+0x20/0x20
>  ret_from_fork+0x22/0x30
>  </TASK>
> 
> Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
> Signed-off-by: Wang Yufen <wangyufen@huawei.com>
> ---
>  net/ipv4/tcp_bpf.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
> index 1f0364e06619..03c037d2a055 100644
> --- a/net/ipv4/tcp_bpf.c
> +++ b/net/ipv4/tcp_bpf.c
> @@ -139,7 +139,7 @@ int tcp_bpf_sendmsg_redir(struct sock *sk, struct sk_msg *msg,
>  	int ret;
>  
>  	if (unlikely(!psock)) {
> -		sk_msg_free(sk, msg);
> +		sk_msg_free_nocharge(sk, msg);
>  		return 0;
>  	}
>  	ret = ingress ? bpf_tcp_ingress(sk, psock, msg, bytes, flags) :

Did you consider simply returning an error code here? This would then
trigger the sk_msg_free_nocharge in the error path of __SK_REDIRECT
and would have the side effect of throwing an error up to user space.
This would be a slight change in behavior from user side but would
look the same as an error if the redirect on the socket threw an
error so I think it would be OK.

Thanks,
John
wangyufen March 1, 2022, 7:24 a.m. UTC | #2
在 2022/3/1 12:11, John Fastabend 写道:
> Wang Yufen wrote:
>> If tcp_bpf_sendmsg is running during a tear down operation, psock may be
>> freed.
>>
>> tcp_bpf_sendmsg()
>>   tcp_bpf_send_verdict()
>>    sk_msg_return()
>>    tcp_bpf_sendmsg_redir()
>>     unlikely(!psock))
>>     sk_msg_free()
>>
>> The mem of msg has been uncharged in tcp_bpf_send_verdict() by
>> sk_msg_return(), so we need to use sk_msg_free_nocharge while psock
>> is null.
>>
>> This issue can cause the following info:
>> WARNING: CPU: 0 PID: 2136 at net/ipv4/af_inet.c:155 inet_sock_destruct+0x13c/0x260
>> Call Trace:
>>   <TASK>
>>   __sk_destruct+0x24/0x1f0
>>   sk_psock_destroy+0x19b/0x1c0
>>   process_one_work+0x1b3/0x3c0
>>   worker_thread+0x30/0x350
>>   ? process_one_work+0x3c0/0x3c0
>>   kthread+0xe6/0x110
>>   ? kthread_complete_and_exit+0x20/0x20
>>   ret_from_fork+0x22/0x30
>>   </TASK>
>>
>> Fixes: 604326b41a6f ("bpf, sockmap: convert to generic sk_msg interface")
>> Signed-off-by: Wang Yufen <wangyufen@huawei.com>
>> ---
>>   net/ipv4/tcp_bpf.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
>> index 1f0364e06619..03c037d2a055 100644
>> --- a/net/ipv4/tcp_bpf.c
>> +++ b/net/ipv4/tcp_bpf.c
>> @@ -139,7 +139,7 @@ int tcp_bpf_sendmsg_redir(struct sock *sk, struct sk_msg *msg,
>>   	int ret;
>>   
>>   	if (unlikely(!psock)) {
>> -		sk_msg_free(sk, msg);
>> +		sk_msg_free_nocharge(sk, msg);
>>   		return 0;
>>   	}
>>   	ret = ingress ? bpf_tcp_ingress(sk, psock, msg, bytes, flags) :
> Did you consider simply returning an error code here? This would then
> trigger the sk_msg_free_nocharge in the error path of __SK_REDIRECT
> and would have the side effect of throwing an error up to user space.
> This would be a slight change in behavior from user side but would
> look the same as an error if the redirect on the socket threw an
> error so I think it would be OK.

Yes, I think it would be better to return -EPIPE,  will do in v2.

Thanks.

>
> Thanks,
> John
> .
diff mbox series

Patch

diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c
index 1f0364e06619..03c037d2a055 100644
--- a/net/ipv4/tcp_bpf.c
+++ b/net/ipv4/tcp_bpf.c
@@ -139,7 +139,7 @@  int tcp_bpf_sendmsg_redir(struct sock *sk, struct sk_msg *msg,
 	int ret;
 
 	if (unlikely(!psock)) {
-		sk_msg_free(sk, msg);
+		sk_msg_free_nocharge(sk, msg);
 		return 0;
 	}
 	ret = ingress ? bpf_tcp_ingress(sk, psock, msg, bytes, flags) :