debuginfod_validate_imasig() extracts the IMA signature from the
untrusted x-debuginfod-imasignature response header, converts it to
binary (bin_sig_len = strlen(sig_buf) / 2) and passes it on as

    debuginfod_verify_hash(c, ..., &bin_sig[1], bin_sig_len - 1);

The signature length is only bounded from above (MAX_SIGNATURE_SIZE);
nothing checks a lower bound.  In debuginfod_verify_hash() the length is
then used as

    EVP_PKEY_verify(ctx, sig + sizeof(hdr), siglen - sizeof(hdr), ...);

where siglen is an int and sizeof(hdr) a size_t.  When a server sends a
signature shorter than the fixed signature_v2_hdr, siglen - sizeof(hdr)
is evaluated in size_t and underflows to a value near SIZE_MAX, which is
handed to EVP_PKEY_verify() as the signature length, causing a large
out-of-bounds read.  A malicious or man-in-the-middle debuginfod server
can trigger this against any client performing IMA signature
verification.

Reject signatures shorter than the header before it is used.

Signed-off-by: Matej Smycka <[email protected]>
---
 debuginfod/debuginfod-client.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/debuginfod/debuginfod-client.c b/debuginfod/debuginfod-client.c
index d9915719..5fa72ee5 100644
--- a/debuginfod/debuginfod-client.c
+++ b/debuginfod/debuginfod-client.c
@@ -1565,6 +1565,9 @@ debuginfod_verify_hash(debuginfod_client *c, const 
unsigned char *hash, int size
   EVP_PKEY_CTX *ctx;
   const EVP_MD *md;
 
+  if (siglen < (int) sizeof(struct signature_v2_hdr))
+    return -EBADMSG;
+
   memcpy(&hdr, sig, sizeof(struct signature_v2_hdr)); /* avoid just aliasing */
 
   if (c->verbose_fd >= 0)
-- 
2.47.3

Reply via email to