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

