diff mbox

crypto: use-after-free in alg_bind

Message ID 20151230122417.GA10774@gondor.apana.org.au (mailing list archive)
State Accepted
Delegated to: Herbert Xu
Headers show

Commit Message

Herbert Xu Dec. 30, 2015, 12:24 p.m. UTC
On Wed, Dec 30, 2015 at 11:58:58AM +0100, Dmitry Vyukov wrote:
>
> I forgot to diff include/crypto/if_alg.h, but the changes are there
> (otherwise all references to refcnt would not compile). Also I moved
> ask->refcnt checks to alg_setsockopt to fix the deadlock, I believe
> that's the missing chunks you refer to. I can retest if you wish, but
> I don't think that my changes can affect the reported use-after-free.
> Do you?

OK I see the problem now.  When accept fails we free the socket
twice.

---8<---
Subject: crypto: af_alg - Fix socket double-free when accept fails

When we fail an accept(2) call we will end up freeing the socket
twice, once due to the direct sk_free call and once again through
newsock.

This patch fixes this by removing the sk_free call.

Cc: stable@vger.kernel.org
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Comments

Dmitry Vyukov Dec. 30, 2015, 12:45 p.m. UTC | #1
On Wed, Dec 30, 2015 at 1:24 PM, Herbert Xu <herbert@gondor.apana.org.au> wrote:
> On Wed, Dec 30, 2015 at 11:58:58AM +0100, Dmitry Vyukov wrote:
>>
>> I forgot to diff include/crypto/if_alg.h, but the changes are there
>> (otherwise all references to refcnt would not compile). Also I moved
>> ask->refcnt checks to alg_setsockopt to fix the deadlock, I believe
>> that's the missing chunks you refer to. I can retest if you wish, but
>> I don't think that my changes can affect the reported use-after-free.
>> Do you?
>
> OK I see the problem now.  When accept fails we free the socket
> twice.

Great!

This seems to be a zero-day. Should we CC stable@vger.kernel.org ?

Code in 03c8efc1ffeb6b82a22c1af8dd908af349563314 (Oct 19, 2010) contained:

+       sock_init_data(newsock, sk2);
+
+       err = type->accept(ask->private, sk2);
+       if (err) {
+               sk_free(sk2);
+               goto unlock;
+       }

There were no sock_graft call, but sock_init_data also sets
newsock->sk = sk2, which seems to be enough for the double-free.




> ---8<---
> Subject: crypto: af_alg - Fix socket double-free when accept fails
>
> When we fail an accept(2) call we will end up freeing the socket
> twice, once due to the direct sk_free call and once again through
> newsock.
>
> This patch fixes this by removing the sk_free call.
>
> Cc: stable@vger.kernel.org
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
>
> diff --git a/crypto/af_alg.c b/crypto/af_alg.c
> index 7b5b592..eaf98e2 100644
> --- a/crypto/af_alg.c
> +++ b/crypto/af_alg.c
> @@ -285,10 +285,8 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
>         security_sk_clone(sk, sk2);
>
>         err = type->accept(ask->private, sk2);
> -       if (err) {
> -               sk_free(sk2);
> +       if (err)
>                 goto unlock;
> -       }
>
>         sk2->sk_family = PF_ALG;
>
> --
> Email: Herbert Xu <herbert@gondor.apana.org.au>
> Home Page: http://gondor.apana.org.au/~herbert/
> PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Herbert Xu Dec. 30, 2015, 12:52 p.m. UTC | #2
On Wed, Dec 30, 2015 at 01:45:15PM +0100, Dmitry Vyukov wrote:
>
> This seems to be a zero-day. Should we CC stable@vger.kernel.org ?
> 
> Code in 03c8efc1ffeb6b82a22c1af8dd908af349563314 (Oct 19, 2010) contained:
> 
> +       sock_init_data(newsock, sk2);
> +
> +       err = type->accept(ask->private, sk2);
> +       if (err) {
> +               sk_free(sk2);
> +               goto unlock;
> +       }
> 
> There were no sock_graft call, but sock_init_data also sets
> newsock->sk = sk2, which seems to be enough for the double-free.

But accept only started failing because the newly added has_key
check.  Otherwise the only way for it to fail is if we run out
of memory.

IOW the bug can only be easily triggered in the current crypto tree.

Cheers,
diff mbox

Patch

diff --git a/crypto/af_alg.c b/crypto/af_alg.c
index 7b5b592..eaf98e2 100644
--- a/crypto/af_alg.c
+++ b/crypto/af_alg.c
@@ -285,10 +285,8 @@  int af_alg_accept(struct sock *sk, struct socket *newsock)
 	security_sk_clone(sk, sk2);
 
 	err = type->accept(ask->private, sk2);
-	if (err) {
-		sk_free(sk2);
+	if (err)
 		goto unlock;
-	}
 
 	sk2->sk_family = PF_ALG;