Message ID | 20180711035905.17809-1-ebiggers3@gmail.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Herbert Xu |
Headers | show |
On Tue, Jul 10, 2018 at 08:59:05PM -0700, Eric Biggers wrote: > From: Eric Biggers <ebiggers@google.com> > > It was forgotten to increase DH_KPP_SECRET_MIN_SIZE to include 'q_size', > causing an out-of-bounds write of 4 bytes in crypto_dh_encode_key(), and > an out-of-bounds read of 4 bytes in crypto_dh_decode_key(). Fix it. > Also add a BUG_ON() if crypto_dh_encode_key() doesn't exactly fill the > buffer, as that would have found this bug without resorting to KASAN. > > Reported-by: syzbot+6d38d558c25b53b8f4ed@syzkaller.appspotmail.com > Fixes: e3fe0ae12962 ("crypto: dh - add public key verification test") > Signed-off-by: Eric Biggers <ebiggers@google.com> Is it possible to return an error and use WARN_ON instead of BUG_ON? Or do the callers not bother to check for errors? Thanks,
Am Mittwoch, 11. Juli 2018, 05:59:05 CEST schrieb Eric Biggers: Hi Eric, > From: Eric Biggers <ebiggers@google.com> > > It was forgotten to increase DH_KPP_SECRET_MIN_SIZE to include 'q_size', > causing an out-of-bounds write of 4 bytes in crypto_dh_encode_key(), and > an out-of-bounds read of 4 bytes in crypto_dh_decode_key(). Fix it. > Also add a BUG_ON() if crypto_dh_encode_key() doesn't exactly fill the > buffer, as that would have found this bug without resorting to KASAN. > > Reported-by: syzbot+6d38d558c25b53b8f4ed@syzkaller.appspotmail.com > Fixes: e3fe0ae12962 ("crypto: dh - add public key verification test") > Signed-off-by: Eric Biggers <ebiggers@google.com> Thanks. Reviewed-by: Stephan Müller <smueller@chronox.de> Ciao Stephan
On Wed, Jul 11, 2018 at 03:26:56PM +0800, Herbert Xu wrote: > On Tue, Jul 10, 2018 at 08:59:05PM -0700, Eric Biggers wrote: > > From: Eric Biggers <ebiggers@google.com> > > > > It was forgotten to increase DH_KPP_SECRET_MIN_SIZE to include 'q_size', > > causing an out-of-bounds write of 4 bytes in crypto_dh_encode_key(), and > > an out-of-bounds read of 4 bytes in crypto_dh_decode_key(). Fix it. > > Also add a BUG_ON() if crypto_dh_encode_key() doesn't exactly fill the > > buffer, as that would have found this bug without resorting to KASAN. > > > > Reported-by: syzbot+6d38d558c25b53b8f4ed@syzkaller.appspotmail.com > > Fixes: e3fe0ae12962 ("crypto: dh - add public key verification test") > > Signed-off-by: Eric Biggers <ebiggers@google.com> > > Is it possible to return an error and use WARN_ON instead of BUG_ON? > Or do the callers not bother to check for errors? > The callers do check for errors, but at the point of the proposed BUG_ON() a buffer overflow may have already occurred, so I think a BUG_ON() would be more appropriate than a WARN_ON(). Of course, it would be better to prevent any buffer overflow from occurring in the first place, but that's already the purpose of the 'len != crypto_dh_key_len(params)' check; the issue was that 'crypto_dh_key_len()' calculated the wrong length. - Eric
On Wed, Jul 11, 2018 at 09:27:56AM -0700, Eric Biggers wrote: > > The callers do check for errors, but at the point of the proposed BUG_ON() a > buffer overflow may have already occurred, so I think a BUG_ON() would be more > appropriate than a WARN_ON(). Of course, it would be better to prevent any > buffer overflow from occurring in the first place, but that's already the > purpose of the 'len != crypto_dh_key_len(params)' check; the issue was that > 'crypto_dh_key_len()' calculated the wrong length. How about adding an end argument to dh_pack_data so that it can check that the buffer isn't overflown each time it's called? Then if you cared you could also have one final check at the end of the function to ensure the buffer is fully used. As we can easily avoid having a BUG_ON here I think we should since a BUG_ON would leave the machine unresponsive which should be a last resort. Thanks,
diff --git a/crypto/dh_helper.c b/crypto/dh_helper.c index a7de3d9ce5ace..87ad6e2e87644 100644 --- a/crypto/dh_helper.c +++ b/crypto/dh_helper.c @@ -14,7 +14,7 @@ #include <crypto/dh.h> #include <crypto/kpp.h> -#define DH_KPP_SECRET_MIN_SIZE (sizeof(struct kpp_secret) + 3 * sizeof(int)) +#define DH_KPP_SECRET_MIN_SIZE (sizeof(struct kpp_secret) + 4 * sizeof(int)) static inline u8 *dh_pack_data(void *dst, const void *src, size_t size) { @@ -61,7 +61,8 @@ int crypto_dh_encode_key(char *buf, unsigned int len, const struct dh *params) ptr = dh_pack_data(ptr, params->key, params->key_size); ptr = dh_pack_data(ptr, params->p, params->p_size); ptr = dh_pack_data(ptr, params->q, params->q_size); - dh_pack_data(ptr, params->g, params->g_size); + ptr = dh_pack_data(ptr, params->g, params->g_size); + BUG_ON(ptr != (u8 *)buf + len); return 0; }