All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Biggers <ebiggers@google.com>
To: Alexander Potapenko <glider@google.com>
Cc: linux-crypto@vger.kernel.org, Kostya Serebryany <kcc@google.com>,
	keyrings@vger.kernel.org, Dmitriy Vyukov <dvyukov@google.com>,
	Andrey Konovalov <andreyknvl@google.com>
Subject: Re: x509 parsing bug + fuzzing crypto in the userspace
Date: Mon, 20 Nov 2017 13:42:57 -0800	[thread overview]
Message-ID: <20171120214257.GB61394@google.com> (raw)
In-Reply-To: <CAG_fn=XJZG_MJXXgos5jZmOThKho=uSvwgfhkMSYONZ04PKKaw@mail.gmail.com>

+Cc keyrings@vger.kernel.org (for asymmetric_keys)

First of all, thanks for working on this!  A lot of this code really needs to be
better tested.

On Mon, Nov 20, 2017 at 03:10:55PM +0100, Alexander Potapenko wrote:
> Hi all,
> 
> TL;DR userspace fuzzing may be very effective for finding bugs in
> crypto code, but might require some kernel-side changes.
> 
> When the attached binary file,
> crash-bbeda07d4ce60cf3b7fc20c3af92297e19f6dbae, is passed as payload
> to add_key("asymmetric", "desc", payload, len), it triggers a
> slab-out-of-bounds KASAN report (see below). This can be reproduced
> with the attached program, add_key.c.

The bug is in asn1_ber_decoder(): the special length value of 0x80, which
indicates an "indefinite length", is being passed to one of the "action"
functions as the real length, causing the input buffer to be overread.  Off-hand
I don't know the best fix, but probably it would involve calling
asn1_find_indefinite_length() before the "action" rather than after...

> 
> We found this bug by fuzzing asn1_ber_decoder() in the userspace using
> libFuzzer (http://llvm.org/docs/LibFuzzer.html).
> The trick is to compile and link together several translation units
> that provide a transitive closure of asn1_ber_decoder() (some of the
> kernel functions need to be re-implemented to run in the userspace).
> I've attached the resulting fuzzer as well (asn1_fuzzer.tar.gz). It
> can operate on its own, although better results are achieved when
> using the fuzzing corpus from
> https://github.com/google/boringssl/tree/master/fuzz and
> https://github.com/openssl/openssl/tree/master/fuzz.

I had actually tried almost the same thing recently, but with afl-fuzz instead
of libFuzzer.  But I don't think it was any better than what you did, and I
didn't find the above bug, perhaps because the AFL_HARDEN compiler options don't
include AddressSanitizer.

I did use the original unpreprocessed .c files instead of preprocessed ones, but
it required stubbing out quite a few headers.  Probably using preprocessed files
is a bit easier.

For the fuzzing function I had it call x509_cert_parse() rather than
asn1_ber_decode() directly, but with x509_get_sig_params() and
x509_check_for_self_signed() stubbed out.  It would be nice to get coverage of
x509_check_for_self_signed() because it will call into crypto/rsa.c and, among
other things, run yet another ASN.1 decoder...  But that would have required
porting a lot of the crypto API to userspace.

> 
> Could it be possible to decouple the parsing algorithms from the rest
> of kernel-specific crypto code? Maybe someone has other ideas about
> how this code can be ran in the userspace?
> 

One idea is that the ASN.1 parsers could be run with no "actions", which would
minimize dependencies on other kernel code.  But unfortunately that would omit a
lot of the interesting code.  Many (or most?) bugs will be in how the parsed
data is used, rather than in the parsing itself.  I don't think there is an easy
solution.

Note that separate from asymmetric_keys (which you can think of as being
in-between the keyrings subsystem and the crypto subsystem) there is also the
userspace interface to cryptographic algorithms, AF_ALG.  It might be possible
to port a lot of the crypto API to userspace, but it would require a lot of work
to stub things out.  Maybe a simpler improvement would be to teach syzkaller to
more thoroughly test AF_ALG.  For example it could be made aware of algorithm
templates so that it could try combining them in unusual ways.  (Example:
https://marc.info/?l=linux-crypto-vger&m=148063683310477&w=2 was a NULL pointer
dereference bug that occurred if you asked to use the algorithm "mcryptd(md5)",
i.e. the mcryptd template wrapping md5.)  Also,
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS should be unset, so that the crypto
self-tests are enabled.

Eric

WARNING: multiple messages have this Message-ID (diff)
From: Eric Biggers <ebiggers@google.com>
To: Alexander Potapenko <glider@google.com>
Cc: linux-crypto@vger.kernel.org, Kostya Serebryany <kcc@google.com>,
	keyrings@vger.kernel.org, Dmitriy Vyukov <dvyukov@google.com>,
	Andrey Konovalov <andreyknvl@google.com>
Subject: Re: x509 parsing bug + fuzzing crypto in the userspace
Date: Mon, 20 Nov 2017 21:42:57 +0000	[thread overview]
Message-ID: <20171120214257.GB61394@google.com> (raw)
In-Reply-To: <CAG_fn=XJZG_MJXXgos5jZmOThKho=uSvwgfhkMSYONZ04PKKaw@mail.gmail.com>

+Cc keyrings@vger.kernel.org (for asymmetric_keys)

First of all, thanks for working on this!  A lot of this code really needs to be
better tested.

On Mon, Nov 20, 2017 at 03:10:55PM +0100, Alexander Potapenko wrote:
> Hi all,
> 
> TL;DR userspace fuzzing may be very effective for finding bugs in
> crypto code, but might require some kernel-side changes.
> 
> When the attached binary file,
> crash-bbeda07d4ce60cf3b7fc20c3af92297e19f6dbae, is passed as payload
> to add_key("asymmetric", "desc", payload, len), it triggers a
> slab-out-of-bounds KASAN report (see below). This can be reproduced
> with the attached program, add_key.c.

The bug is in asn1_ber_decoder(): the special length value of 0x80, which
indicates an "indefinite length", is being passed to one of the "action"
functions as the real length, causing the input buffer to be overread.  Off-hand
I don't know the best fix, but probably it would involve calling
asn1_find_indefinite_length() before the "action" rather than after...

> 
> We found this bug by fuzzing asn1_ber_decoder() in the userspace using
> libFuzzer (http://llvm.org/docs/LibFuzzer.html).
> The trick is to compile and link together several translation units
> that provide a transitive closure of asn1_ber_decoder() (some of the
> kernel functions need to be re-implemented to run in the userspace).
> I've attached the resulting fuzzer as well (asn1_fuzzer.tar.gz). It
> can operate on its own, although better results are achieved when
> using the fuzzing corpus from
> https://github.com/google/boringssl/tree/master/fuzz and
> https://github.com/openssl/openssl/tree/master/fuzz.

I had actually tried almost the same thing recently, but with afl-fuzz instead
of libFuzzer.  But I don't think it was any better than what you did, and I
didn't find the above bug, perhaps because the AFL_HARDEN compiler options don't
include AddressSanitizer.

I did use the original unpreprocessed .c files instead of preprocessed ones, but
it required stubbing out quite a few headers.  Probably using preprocessed files
is a bit easier.

For the fuzzing function I had it call x509_cert_parse() rather than
asn1_ber_decode() directly, but with x509_get_sig_params() and
x509_check_for_self_signed() stubbed out.  It would be nice to get coverage of
x509_check_for_self_signed() because it will call into crypto/rsa.c and, among
other things, run yet another ASN.1 decoder...  But that would have required
porting a lot of the crypto API to userspace.

> 
> Could it be possible to decouple the parsing algorithms from the rest
> of kernel-specific crypto code? Maybe someone has other ideas about
> how this code can be ran in the userspace?
> 

One idea is that the ASN.1 parsers could be run with no "actions", which would
minimize dependencies on other kernel code.  But unfortunately that would omit a
lot of the interesting code.  Many (or most?) bugs will be in how the parsed
data is used, rather than in the parsing itself.  I don't think there is an easy
solution.

Note that separate from asymmetric_keys (which you can think of as being
in-between the keyrings subsystem and the crypto subsystem) there is also the
userspace interface to cryptographic algorithms, AF_ALG.  It might be possible
to port a lot of the crypto API to userspace, but it would require a lot of work
to stub things out.  Maybe a simpler improvement would be to teach syzkaller to
more thoroughly test AF_ALG.  For example it could be made aware of algorithm
templates so that it could try combining them in unusual ways.  (Example:
https://marc.info/?l=linux-crypto-vger&m\x148063683310477&w=2 was a NULL pointer
dereference bug that occurred if you asked to use the algorithm "mcryptd(md5)",
i.e. the mcryptd template wrapping md5.)  Also,
CONFIG_CRYPTO_MANAGER_DISABLE_TESTS should be unset, so that the crypto
self-tests are enabled.

Eric

  reply	other threads:[~2017-11-20 21:43 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-20 14:10 x509 parsing bug + fuzzing crypto in the userspace Alexander Potapenko
2017-11-20 21:42 ` Eric Biggers [this message]
2017-11-20 21:42   ` Eric Biggers
2017-11-21  8:00   ` Dmitry Vyukov
2017-11-21  8:00     ` Dmitry Vyukov
2017-11-21 20:46     ` Eric Biggers
2017-11-21 20:46       ` Eric Biggers
2017-11-22 10:44       ` Dmitry Vyukov
2017-11-22 10:44         ` Dmitry Vyukov
2017-11-22 17:08         ` Stephan Mueller
2017-11-22 17:08           ` Stephan Mueller
2017-11-23  9:32           ` Dmitry Vyukov
2017-11-23  9:32             ` Dmitry Vyukov
2017-11-23  9:35             ` Dmitry Vyukov
2017-11-23  9:35               ` Dmitry Vyukov
2017-11-23  9:37               ` Dmitry Vyukov
2017-11-23  9:37                 ` Dmitry Vyukov
2017-11-23 11:10                 ` Stephan Mueller
2017-11-23 11:10                   ` Stephan Mueller
2017-11-23 11:27                   ` Dmitry Vyukov
2017-11-23 11:27                     ` Dmitry Vyukov
2017-11-23 11:34                     ` Dmitry Vyukov
2017-11-23 11:34                       ` Dmitry Vyukov
2017-11-23 12:35                       ` Stephan Mueller
2017-11-23 12:35                         ` Stephan Mueller
2017-11-24 13:49                         ` Dmitry Vyukov
2017-11-24 13:49                           ` Dmitry Vyukov
2017-11-24 14:36                           ` Stephan Mueller
2017-11-24 14:36                             ` Stephan Mueller
2017-11-24 14:55                             ` Dmitry Vyukov
2017-11-24 14:55                               ` Dmitry Vyukov
2017-11-24 15:13                               ` Stephan Mueller
2017-11-24 15:13                                 ` Stephan Mueller
2017-11-24 15:53                                 ` Dmitry Vyukov
2017-11-24 15:53                                   ` Dmitry Vyukov
2017-11-24 16:07                                   ` Stephan Mueller
2017-11-24 16:07                                     ` Stephan Mueller
2017-11-24 15:03                           ` Stephan Mueller
2017-11-24 15:03                             ` Stephan Mueller
2017-11-24 16:10                             ` Dmitry Vyukov
2017-11-24 16:10                               ` Dmitry Vyukov
2017-11-24 16:19                               ` Stephan Mueller
2017-11-24 16:19                                 ` Stephan Mueller
2017-11-24 16:25                                 ` Dmitry Vyukov
2017-11-24 16:25                                   ` Dmitry Vyukov
2017-11-24 16:31                                   ` Stephan Mueller
2017-11-24 16:31                                     ` Stephan Mueller
2017-11-28  9:59                                     ` Dmitry Vyukov
2017-11-28  9:59                                       ` Dmitry Vyukov
2017-11-24 16:18                             ` Dmitry Vyukov
2017-11-24 16:18                               ` Dmitry Vyukov
2017-11-24 16:23                               ` Stephan Mueller
2017-11-24 16:23                                 ` Stephan Mueller
2017-11-23 12:32                     ` Stephan Mueller
2017-11-23 12:32                       ` Stephan Mueller
2017-11-22 16:54       ` Stephan Mueller
2017-11-22 16:54         ` Stephan Mueller
2017-11-22 17:03         ` Dmitry Vyukov
2017-11-22 17:03           ` Dmitry Vyukov
2017-11-22 17:15           ` Stephan Mueller
2017-11-22 17:15             ` Stephan Mueller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171120214257.GB61394@google.com \
    --to=ebiggers@google.com \
    --cc=andreyknvl@google.com \
    --cc=dvyukov@google.com \
    --cc=glider@google.com \
    --cc=kcc@google.com \
    --cc=keyrings@vger.kernel.org \
    --cc=linux-crypto@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.