From: Omar Almahri <[email protected]>
rsa_gen_key_prop() copies the DER public exponent into a fixed 8 byte buffer with memcpy(pub_exp + sizeof(uint64_t) - e_sz, e, e_sz). e_sz comes from the key and is only bounded by e_sz <= n_sz in rsa_get_e(), nothing limits it to 8 bytes. Since e_sz is a size_t, an exponent larger than 8 bytes underflows the destination to pub_exp - (e_sz - 8) and writes attacker-controlled bytes below the allocation. A 256 byte exponent gives a 248 byte heap underflow of controlled content. It's reachable while verifying a certificate embedded in an attacker-supplied PKCS#7 (efi_signature.c -> pkcs7_verify_one -> public_key_verify_signature -> rsa_verify_with_pkey -> rsa_gen_key_prop), before the cert is checked against the trust anchors, so on a Secure Boot board it's pre-trust. The fix rejects an exponent that doesn't fit the 8 byte buffer before the copy. Reported-by: Omar A. <[email protected]> Fixes: e0d310b098b1 ("lib: rsa: generate additional parameters for public key") Signed-off-by: Omar Almahri <[email protected]> Reviewed-by: Heinrich Schuchardt <[email protected]> --- lib/rsa/rsa-keyprop.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/rsa/rsa-keyprop.c b/lib/rsa/rsa-keyprop.c index 80d0594a430..2ac039ac3f4 100644 --- a/lib/rsa/rsa-keyprop.c +++ b/lib/rsa/rsa-keyprop.c @@ -665,6 +665,16 @@ int rsa_gen_key_prop(const void *key, uint32_t keylen, struct key_prop **prop) if (ret) goto out; + /* + * The public exponent is copied right-justified into an 8-byte + * buffer below; an exponent longer than that buffer underflows the + * destination pointer and writes out of bounds. Reject it here. + */ + if (rsa_key.e_sz > sizeof(uint64_t)) { + ret = -EINVAL; + goto out; + } + /* modulus */ /* removing leading 0's */ for (i = 0; i < rsa_key.n_sz && !rsa_key.n[i]; i++) -- 2.53.0
