From 8e9ad6eda2ac454dfc3a208eac8e83e102b48ff4 Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Wed, 26 Oct 2022 01:54:13 -0500 Subject: [PATCH] krb5: Fix UB --- lib/krb5/aes-test.c | 6 ++++-- lib/krb5/crypto-evp.c | 7 +++++-- lib/krb5/salt-aes-sha2.c | 5 +++-- lib/krb5/salt-des.c | 3 ++- lib/krb5/salt-des3.c | 3 ++- lib/krb5/store_emem.c | 18 +++++++++++++----- 6 files changed, 29 insertions(+), 13 deletions(-) diff --git a/lib/krb5/aes-test.c b/lib/krb5/aes-test.c index 01522dd59..2d048e426 100644 --- a/lib/krb5/aes-test.c +++ b/lib/krb5/aes-test.c @@ -328,7 +328,8 @@ krb_enc(krb5_context context, } if (decrypt.length != clear->length || - memcmp(decrypt.data, clear->data, decrypt.length) != 0) { + (decrypt.length && + memcmp(decrypt.data, clear->data, decrypt.length) != 0)) { krb5_warnx(context, "clear text not same"); return EINVAL; } @@ -568,7 +569,8 @@ krb_enc_mit(krb5_context context, return ret; if (decrypt.length != clear->length || - memcmp(decrypt.data, clear->data, decrypt.length) != 0) { + (decrypt.length && + memcmp(decrypt.data, clear->data, decrypt.length) != 0)) { krb5_warnx(context, "clear text not same"); return EINVAL; } diff --git a/lib/krb5/crypto-evp.c b/lib/krb5/crypto-evp.c index a03cdca2e..0ed749a24 100644 --- a/lib/krb5/crypto-evp.c +++ b/lib/krb5/crypto-evp.c @@ -82,9 +82,11 @@ _krb5_evp_digest_iov(krb5_crypto crypto, if (ret != 1) goto out; + /* Minimize EVP calls by coalescing contiguous iovec elements */ for (i = 0; i < niov; i++) { if (_krb5_crypto_iov_should_sign(&iov[i])) { - if ((char *)current.data + current.length == iov[i].data.data) { + if (current.data && + (char *)current.data + current.length == iov[i].data.data) { current.length += iov[i].data.length; } else { if (current.data) { @@ -145,7 +147,8 @@ _krb5_evp_hmac_iov(krb5_context context, for (i = 0; i < niov; i++) { if (_krb5_crypto_iov_should_sign(&iov[i])) { - if ((char *)current.data + current.length == iov[i].data.data) { + if (current.data && + (char *)current.data + current.length == iov[i].data.data) { current.length += iov[i].data.length; } else { if (current.data) diff --git a/lib/krb5/salt-aes-sha2.c b/lib/krb5/salt-aes-sha2.c index bfd726c34..bc674bd2d 100644 --- a/lib/krb5/salt-aes-sha2.c +++ b/lib/krb5/salt-aes-sha2.c @@ -92,8 +92,9 @@ AES_SHA2_string_to_key(krb5_context context, goto cleanup; } memcpy(saltp.data, et->name, enctypesz); - memcpy((unsigned char *)saltp.data + enctypesz, - salt.saltvalue.data, salt.saltvalue.length); + if (salt.saltvalue.length) + memcpy((unsigned char *)saltp.data + enctypesz, + salt.saltvalue.data, salt.saltvalue.length); ret = _krb5_aes_sha2_md_for_enctype(context, enctype, &md); if (ret) diff --git a/lib/krb5/salt-des.c b/lib/krb5/salt-des.c index d898d6c20..474ba5d59 100644 --- a/lib/krb5/salt-des.c +++ b/lib/krb5/salt-des.c @@ -194,7 +194,8 @@ krb5_DES_string_to_key(krb5_context context, if (len > 0 && s == NULL) return krb5_enomem(context); memcpy(s, password.data, password.length); - memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length); + if (salt.saltvalue.length) + memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length); DES_string_to_key_int(s, len, &tmp); key->keytype = enctype; krb5_data_copy(&key->keyvalue, tmp, sizeof(tmp)); diff --git a/lib/krb5/salt-des3.c b/lib/krb5/salt-des3.c index 8cb73cf46..a9293ccec 100644 --- a/lib/krb5/salt-des3.c +++ b/lib/krb5/salt-des3.c @@ -113,7 +113,8 @@ DES3_string_to_key_derived(krb5_context context, if (len != 0 && s == NULL) return krb5_enomem(context); memcpy(s, password.data, password.length); - memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length); + if (salt.saltvalue.length) + memcpy(s + password.length, salt.saltvalue.data, salt.saltvalue.length); ret = krb5_string_to_key_derived(context, s, len, diff --git a/lib/krb5/store_emem.c b/lib/krb5/store_emem.c index 6a3908f74..c52b4ec76 100644 --- a/lib/krb5/store_emem.c +++ b/lib/krb5/store_emem.c @@ -84,7 +84,8 @@ emem_store(krb5_storage *sp, const void *data, size_t size) s->base = base; s->ptr = (unsigned char*)base + off; } - memmove(s->ptr, data, size); + if (size) + memmove(s->ptr, data, size); sp->seek(sp, size, SEEK_CUR); return size; } @@ -125,10 +126,17 @@ emem_trunc(krb5_storage *sp, off_t offset) * shrunk more then half of the current size, adjust buffer. */ if (offset == 0) { - free(s->base); - s->size = 0; - s->base = NULL; - s->ptr = NULL; + if (s->size > 1024) { + void *base; + + base = realloc(s->base, 1024); + if (base) { + s->base = base; + s->size = 1024; + } + } + s->len = 0; + s->ptr = s->base; } else if ((size_t)offset > s->size || (s->size / 2) > (size_t)offset) { void *base; size_t off;