Hello,

On Fri, May 15, 2026 at 02:59:11PM +0400, Omar A. wrote:
> Hello,
> While auditing the ACME client in 3.4-dev12, I noticed that
> acme_res_certificate() passes the raw httpclient response buffer
> to ssl_sock_load_pem_into_ckch(), which ends up calling
> BIO_new_mem_buf(buf, -1). With length -1, OpenSSL runs strlen()
> on the buffer, but the httpclient fills it via __b_putblk() and
> never writes a trailing NUL. That allows a malicious or compromised
> ACME CA to drive an out-of-bounds heap read past the response body,
> with two practical impacts: PEM-looking bytes lying in adjacent freed
> chunks may be loaded as additional intermediate certificates into the
> ckch_store, and an embedded NUL in the response silently truncates the
> installed certificate.
> The attached patch NUL-terminates the buffer at area[data] before
> handing it to the PEM loader, and fails cleanly if no room is left.
> I am not subscribed to the list -- please keep me in CC on any reply.
> Thanks,
> Omar

Thanks for your patch. Your description makes sense and the patch
looks correct. I'll just slightly edit the commit message below though:

> From 0a07fe9fe79483a842d66fe0938c03fa664c02d2 Mon Sep 17 00:00:00 2001
> From: CyberpsychoJacob <[email protected]>
> Date: Fri, 15 May 2026 11:27:15 +0400
> Subject: [PATCH] BUG/MEDIUM: acme: NUL terminate response buffer before PEM
>  parsing
> 
> acme_res_certificate() passes the httpclient response buffer to
> ssl_sock_load_pem_into_ckch(), which will then call BIO_new_mem_buf(buf, -1).
> The "-1" flag will make the OpenSSL PEM parser determine the length by
> using strlen(). However, the httpclient populates the response buffer with
> __b_putblk() without writing a trailing NUL to it. The byte at area[data]
> is whatever data previously resided there in the memory pool.
> 
> Thus, a malicious or compromised ACME CA can perform an arbitrary-length
> out-of-bounds read until hitting the first NULL byte past the response
> body. The OpenSSL PEM loader will try to iterate to load the chain
> certificates, thus the PEM-looking garbage found in freed memory chunks
> can be erroneously loaded as additional intermediate certificates. The
> presence of a single NUL inside the valid response body will result in
> silent truncation of the certificate.
> 
> Make sure that the area[data] contains a terminating NULL before passing
> the buffer to the parser. Fail on insufficient room for the NUL terminator.
> 
> No backport required: The ACME client has been added in 3.x and this
> code path didn't exist in 2.x.

Indeed, this code was already present in 3.2, so at least 3.2 and 3.3
will need this fix.

thank you!
Willy


Reply via email to