Message ID | 20151230122417.GA10774@gondor.apana.org.au (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Herbert Xu |
Headers | show |
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
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 --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;