diff mbox series

net/vmw_vsock: fix NULL pointer deref and improve locking

Message ID trinity-64b93de7-52ac-4127-a29a-1a6dbbb7aeb6-1612474127915@3c-app-gmx-bap39 (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series net/vmw_vsock: fix NULL pointer deref and improve locking | expand

Checks

Context Check Description
netdev/cover_letter success Link
netdev/fixes_present success Link
netdev/patch_count success Link
netdev/tree_selection success Guessed tree name to be net-next
netdev/subject_prefix warning Target tree name not specified in the subject
netdev/cc_maintainers warning 4 maintainers not CCed: davem@davemloft.net jhansen@vmware.com colin.king@canonical.com andraprs@amazon.com
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Link
netdev/module_param success Was 0 now: 0
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/verify_fixes success Link
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 27 lines checked
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/header_inline success Link
netdev/stable success Stable not CCed

Commit Message

Norbert Slusarek Feb. 4, 2021, 9:28 p.m. UTC
From: Norbert Slusarek <nslusarek@gmx.net>
Date: Thu, 4 Feb 2021 18:49:24 +0100
Subject: [PATCH] net/vmw_vsock: fix NULL pointer deref and improve locking

In vsock_stream_connect(), a thread will enter schedule_timeout().
While being scheduled out, another thread can enter vsock_stream_connect() as
well and set vsk->transport to NULL. In case a signal was sent, the first
thread can leave schedule_timeout() and vsock_transport_cancel_pkt() will be
called right after. Inside vsock_transport_cancel_pkt(), a null dereference
will happen on transport->cancel_pkt.

The patch also features improved locking inside vsock_connect_timeout().

Signed-off-by: Norbert Slusarek <nslusarek@gmx.net>
---
 net/vmw_vsock/af_vsock.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

--
2.30.0

Comments

Eric Dumazet Feb. 4, 2021, 9:37 p.m. UTC | #1
On 2/4/21 10:28 PM, Norbert Slusarek wrote:
> From: Norbert Slusarek <nslusarek@gmx.net>
> Date: Thu, 4 Feb 2021 18:49:24 +0100
> Subject: [PATCH] net/vmw_vsock: fix NULL pointer deref and improve locking
> 
> In vsock_stream_connect(), a thread will enter schedule_timeout().
> While being scheduled out, another thread can enter vsock_stream_connect() as
> well and set vsk->transport to NULL. In case a signal was sent, the first
> thread can leave schedule_timeout() and vsock_transport_cancel_pkt() will be
> called right after. Inside vsock_transport_cancel_pkt(), a null dereference
> will happen on transport->cancel_pkt.
> 
> The patch also features improved locking inside vsock_connect_timeout().


We request Fixes: tag for patches targeting net tree.

You could also mention the vsock_connect_timeout()
issue was found by a reviewer and give some credits ;)

> 
> Signed-off-by: Norbert Slusarek <nslusarek@gmx.net>
> ---
>  net/vmw_vsock/af_vsock.c | 7 ++-----
>  1 file changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
> index 3b480ed0953a..ea7b9d208724 100644
> --- a/net/vmw_vsock/af_vsock.c
> +++ b/net/vmw_vsock/af_vsock.c
> @@ -1233,7 +1233,7 @@ static int vsock_transport_cancel_pkt(struct vsock_sock *vsk)
>  {
>  	const struct vsock_transport *transport = vsk->transport;
> 
> -	if (!transport->cancel_pkt)
> +	if (!transport || !transport->cancel_pkt)
>  		return -EOPNOTSUPP;
> 
>  	return transport->cancel_pkt(vsk);
> @@ -1243,7 +1243,6 @@ static void vsock_connect_timeout(struct work_struct *work)
>  {
>  	struct sock *sk;
>  	struct vsock_sock *vsk;
> -	int cancel = 0;
> 
>  	vsk = container_of(work, struct vsock_sock, connect_work.work);
>  	sk = sk_vsock(vsk);
> @@ -1254,11 +1253,9 @@ static void vsock_connect_timeout(struct work_struct *work)
>  		sk->sk_state = TCP_CLOSE;
>  		sk->sk_err = ETIMEDOUT;
>  		sk->sk_error_report(sk);
> -		cancel = 1;
> +		vsock_transport_cancel_pkt(vsk);
>  	}
>  	release_sock(sk);
> -	if (cancel)
> -		vsock_transport_cancel_pkt(vsk);
> 
>  	sock_put(sk);
>  }
> --
> 2.30.0
>
Norbert Slusarek Feb. 4, 2021, 10:22 p.m. UTC | #2
> We request Fixes: tag for patches targeting net tree.
>
> You could also mention the vsock_connect_timeout()
> issue was found by a reviewer and give some credits ;)

You're right, Eric Dumazet spotted the locking problem in vsock_cancel_timeout().
I am not too familiar how I should format my response to include it to the final
patch message, in case I should specifically format it, just let me know.
For now:

Fixes: 380feae0def7e6a115124a3219c3ec9b654dca32 (vsock: cancel packets when failing to connect)
Reported-by: Norbert Slusarek <nslusarek@gmx.net>
Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
Stefano Garzarella Feb. 5, 2021, 8:20 a.m. UTC | #3
On Thu, Feb 04, 2021 at 11:22:42PM +0100, Norbert Slusarek wrote:
>> We request Fixes: tag for patches targeting net tree.
>>
>> You could also mention the vsock_connect_timeout()
>> issue was found by a reviewer and give some credits ;)
>
>You're right, Eric Dumazet spotted the locking problem in vsock_cancel_timeout().
>I am not too familiar how I should format my response to include it to the final
>patch message, in case I should specifically format it, just let me know.
>For now:
>

 From Documentation/process/submitting-patches.rst:
"please use the 'Fixes:' tag with the first 12 characters of the SHA-1 
ID, and the one line summary."

>Fixes: 380feae0def7e6a115124a3219c3ec9b654dca32 (vsock: cancel packets when failing to connect)

So this should be :
Fixes: 380feae0def7 ("vsock: cancel packets when failing to connect")

This maybe could apply for the locking issue, but for the NULL pointer 
issue is better to refer to the commit that handled vsk->transport 
pointer dynamically, that is this one:

Fixes: c0cfa2d8a788 ("vsock: add multi-transports support")

As I suggested, I think is better to split this patch in two patches 
since we are fixing two issues. This should also simplify to attach the 
proper 'Fixes' tag.

But if you want to send a single patch, I thing the right 'Fixes:' tag 
should be the c0cfa2d8a788, since before this commit, both issues are 
not really exploitable.

>Reported-by: Norbert Slusarek <nslusarek@gmx.net>
>Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
>

Splitting also allows to put the reporter in the right issue he 
reported.

Thanks,
Stefano
Norbert Slusarek Feb. 5, 2021, 9:05 a.m. UTC | #4
> As I suggested, I think is better to split this patch in two patches
> since we are fixing two issues. This should also simplify to attach the
> proper 'Fixes' tag.

> Splitting also allows to put the reporter in the right issue he
> reported.

I agree it makes sense to split it. I will send separate patches in a few hours.

Norbert
diff mbox series

Patch

diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 3b480ed0953a..ea7b9d208724 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1233,7 +1233,7 @@  static int vsock_transport_cancel_pkt(struct vsock_sock *vsk)
 {
 	const struct vsock_transport *transport = vsk->transport;

-	if (!transport->cancel_pkt)
+	if (!transport || !transport->cancel_pkt)
 		return -EOPNOTSUPP;

 	return transport->cancel_pkt(vsk);
@@ -1243,7 +1243,6 @@  static void vsock_connect_timeout(struct work_struct *work)
 {
 	struct sock *sk;
 	struct vsock_sock *vsk;
-	int cancel = 0;

 	vsk = container_of(work, struct vsock_sock, connect_work.work);
 	sk = sk_vsock(vsk);
@@ -1254,11 +1253,9 @@  static void vsock_connect_timeout(struct work_struct *work)
 		sk->sk_state = TCP_CLOSE;
 		sk->sk_err = ETIMEDOUT;
 		sk->sk_error_report(sk);
-		cancel = 1;
+		vsock_transport_cancel_pkt(vsk);
 	}
 	release_sock(sk);
-	if (cancel)
-		vsock_transport_cancel_pkt(vsk);

 	sock_put(sk);
 }