From: Nikola Pajkovsky Date: Tue, 19 May 2026 09:39:41 +0000 (+0200) Subject: avoid mismatched d2i callbacks in PEM readers X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f6efce32a024298a1b3d87ec4914d49bcab34366;p=thirdparty%2Fopenssl.git avoid mismatched d2i callbacks in PEM readers decode PEM payloads through the generated typed d2i_* functions in the PEM read macros instead of routing them through the d2i_of_void callback path. This avoids UBSan function type mismatch reports while preserving the public PEM reader APIs. Signed-off-by: Nikola Pajkovsky Reviewed-by: Neil Horman Reviewed-by: Milan Broz MergeDate: Thu Jun 25 12:12:57 2026 (Merged from https://github.com/openssl/openssl/pull/31523) --- diff --git a/include/openssl/pem.h b/include/openssl/pem.h index ccde1b93d54..115c8f27331 100644 --- a/include/openssl/pem.h +++ b/include/openssl/pem.h @@ -117,8 +117,26 @@ extern "C" { #define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u) \ { \ - return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str, fp, \ - (void **)x, cb, u); \ + BIO *b; \ + const unsigned char *p = NULL; \ + unsigned char *data = NULL; \ + long len; \ + type *ret = NULL; \ + \ + if ((b = BIO_new(BIO_s_file())) == NULL) { \ + ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); \ + return NULL; \ + } \ + BIO_set_fp(b, fp, BIO_NOCLOSE); \ + if (PEM_bytes_read_bio(&data, &len, NULL, str, b, cb, u)) { \ + p = data; \ + ret = d2i_##asn1(x, &p, len); \ + if (ret == NULL) \ + ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB); \ + } \ + BIO_free(b); \ + OPENSSL_free(data); \ + return ret; \ } #define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ @@ -146,12 +164,24 @@ extern "C" { #endif #endif -#define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ - type *PEM_read_bio_##name(BIO *bp, type **x, \ - pem_password_cb *cb, void *u) \ - { \ - return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str, bp, \ - (void **)x, cb, u); \ +#define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ + type *PEM_read_bio_##name(BIO *bp, type **x, \ + pem_password_cb *cb, void *u) \ + { \ + const unsigned char *p = NULL; \ + unsigned char *data = NULL; \ + long len; \ + type *ret = NULL; \ + \ + if (!PEM_bytes_read_bio(&data, &len, NULL, str, \ + bp, cb, u)) \ + return NULL; \ + p = data; \ + ret = d2i_##asn1(x, &p, len); \ + if (ret == NULL) \ + ERR_raise(ERR_LIB_PEM, ERR_R_ASN1_LIB); \ + OPENSSL_free(data); \ + return ret; \ } #define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \