From 48273b962b3df184857eb2c4e7259ae59b445bf0 Mon Sep 17 00:00:00 2001 From: ndossche Date: Tue, 24 Feb 2026 15:43:25 +0100 Subject: [PATCH 1/2] Fix memory leak if sk_push fails If it fails, then the duplicated item is not freed. Solve it by making sure the push cannot fail by reserving the necessary stack size upfront. Example Valgrind trace: ``` 14,009 (384 direct, 13,625 indirect) bytes in 1 blocks are definitely lost in loss record 27,287 of 27,373 malloc (at /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) CRYPTO_zalloc (at /usr/lib/x86_64-linux-gnu/libcrypto.so.3) ASN1_item_new (at /usr/lib/x86_64-linux-gnu/libcrypto.so.3) *ossl_x509_alloc (ossl_x509cert.c:97) rb_class_new_instance_pass_kw (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_vm_exec (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_catch_obj (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_vm_exec (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_yield (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_ary_each (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_vm_exec (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_yield (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_ary_each (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_vm_exec (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_yield (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_ary_each (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_vm_exec (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_yield (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_ary_each (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_vm_exec (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_catch_obj (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) rb_vm_exec (at /usr/lib/x86_64-linux-gnu/libruby-3.2.so.3.2.3) ``` --- ext/openssl/ossl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 98127fcba..5ded6a47e 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -23,7 +23,7 @@ ossl_##name##_ary2sk0(VALUE ary) \ int i; \ \ Check_Type(ary, T_ARRAY); \ - sk = sk_##type##_new_null(); \ + sk = sk_##type##_new_reserve(NULL, RARRAY_LEN(ary)); \ if (!sk) ossl_raise(eOSSLError, NULL); \ \ for (i = 0; i < RARRAY_LEN(ary); i++) { \ From 29e3ab76fe3665c7f669b5d322f57b8f030f2c61 Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Wed, 25 Feb 2026 09:03:24 +0100 Subject: [PATCH 2/2] fixup! make compatible for libre --- ext/openssl/ossl.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index 5ded6a47e..d3270f31f 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -23,7 +23,7 @@ ossl_##name##_ary2sk0(VALUE ary) \ int i; \ \ Check_Type(ary, T_ARRAY); \ - sk = sk_##type##_new_reserve(NULL, RARRAY_LEN(ary)); \ + sk = sk_##type##_new_null(); \ if (!sk) ossl_raise(eOSSLError, NULL); \ \ for (i = 0; i < RARRAY_LEN(ary); i++) { \ @@ -34,7 +34,11 @@ ossl_##name##_ary2sk0(VALUE ary) \ " of class ##type##"); \ } \ x = dup(val); /* NEED TO DUP */ \ - sk_##type##_push(sk, x); \ + if (!sk_##type##_push(sk, x)) { \ + type##_free(x); \ + sk_##type##_pop_free(sk, type##_free); \ + ossl_raise(eOSSLError, NULL); \ + } \ } \ return (VALUE)sk; \ } \