Hi Matej,

On Fri, 2026-07-03 at 12:30 +0200, Matej Smycka wrote:
> 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.

Well spotted.

> 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;

Yes, this is the correct sanity check.

>    memcpy(&hdr, sig, sizeof(struct signature_v2_hdr)); /* avoid just aliasing 
> */
>  
>    if (c->verbose_fd >= 0)

Pushed as https://sourceware.org/cgit/elfutils/commit/?id=f246b5b92728

Thanks,

Mark

Reply via email to