From 8ca0afb30a6d068161a5d9245f55a1579e0b0915 Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Sun, 19 Apr 2026 15:14:49 +0200 Subject: [PATCH 1/2] x509attr: check for errors of sk_ASN1_TYPE_push() This function returns 0 on error. --- ext/openssl/ossl_x509attr.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c index b0773e7a7..e6329815b 100644 --- a/ext/openssl/ossl_x509attr.c +++ b/ext/openssl/ossl_x509attr.c @@ -239,9 +239,12 @@ ossl_x509attr_get_value(VALUE self) if (!(sk = sk_ASN1_TYPE_new_null())) ossl_raise(eX509AttrError, "sk_new"); - count = X509_ATTRIBUTE_count(attr); - for (i = 0; i < count; i++) - sk_ASN1_TYPE_push(sk, (ASN1_TYPE *)X509_ATTRIBUTE_get0_type(attr, i)); + for (i = 0; i < count; i++) { + if (!sk_ASN1_TYPE_push(sk, (ASN1_TYPE *)X509_ATTRIBUTE_get0_type(attr, i))) { + sk_ASN1_TYPE_free(sk); + ossl_raise(eX509AttrError, NULL); + } + } if ((len = i2d_ASN1_SET_ANY(sk, NULL)) <= 0) { sk_ASN1_TYPE_free(sk); From 0966d0466e153224a3d1cdbf6341823915b75ef3 Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Sun, 19 Apr 2026 15:15:02 +0200 Subject: [PATCH 2/2] x509attr: use sk_ASN1_TYPE_new_reserve() This should avoid reallocations and prevent the main error condition of the push call. --- ext/openssl/extconf.rb | 4 ++++ ext/openssl/ossl_x509attr.c | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index 06ed4f6ac..1f3298094 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -135,6 +135,7 @@ def find_openssl_library evp_h = "openssl/evp.h".freeze ts_h = "openssl/ts.h".freeze ssl_h = "openssl/ssl.h".freeze +stack_h = "openssl/stack.h".freeze # compile options have_func("RAND_egd()", "openssl/rand.h") @@ -150,6 +151,9 @@ def find_openssl_library # added in OpenSSL 1.1.1 and LibreSSL 3.5.0, then removed in LibreSSL 4.0.0 have_func("EVP_PKEY_check(NULL)", evp_h) +# added in OpenSSL 1.1.1, currently not in LibreSSL +have_func("OPENSSL_sk_new_reserve(NULL, 0)", stack_h) + # added in 3.0.0 have_func("SSL_CTX_set0_tmp_dh_pkey(NULL, NULL)", ssl_h) have_func("ERR_get_error_all(NULL, NULL, NULL, NULL, NULL)", "openssl/err.h") diff --git a/ext/openssl/ossl_x509attr.c b/ext/openssl/ossl_x509attr.c index e6329815b..38600b9b0 100644 --- a/ext/openssl/ossl_x509attr.c +++ b/ext/openssl/ossl_x509attr.c @@ -235,9 +235,15 @@ ossl_x509attr_get_value(VALUE self) unsigned char *p; GetX509Attr(self, attr); + count = X509_ATTRIBUTE_count(attr); /* there is no X509_ATTRIBUTE_get0_set() :( */ +#ifdef HAVE_OPENSSL_SK_NEW_RESERVE + if (!(sk = sk_ASN1_TYPE_new_reserve(NULL, count))) + ossl_raise(eX509AttrError, "sk_new_reserve"); +#else if (!(sk = sk_ASN1_TYPE_new_null())) ossl_raise(eX509AttrError, "sk_new"); +#endif for (i = 0; i < count; i++) { if (!sk_ASN1_TYPE_push(sk, (ASN1_TYPE *)X509_ATTRIBUTE_get0_type(attr, i))) {