aboutsummaryrefslogtreecommitdiffstats
path: root/ext
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2016-07-24 15:02:42 +0900
committerKazuki Yamaguchi <k@rhe.jp>2016-10-16 21:41:12 +0900
commitc0c7db9336a4dc99e85192ce29ff549b8d92f8fc (patch)
treefd1cea494963820ab49fe9604329012001bae185 /ext
parent1dd7c25d53eca4ec7965bb9b9cf5e2b837555686 (diff)
downloadruby-openssl-c0c7db9336a4dc99e85192ce29ff549b8d92f8fc.tar.gz
pkey: fix possible memory leak in ossl_pkey_new()
The ownership of the EVP_PKEY object given as the argument is moved to ossl_pkey_new(). So, the function must not raise an exception without freeing it on failure.
Diffstat (limited to 'ext')
-rw-r--r--ext/openssl/ossl_pkey.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index 9e262da0..9e6c6157 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -70,12 +70,12 @@ const rb_data_type_t ossl_evp_pkey_type = {
0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
};
-VALUE
-ossl_pkey_new(EVP_PKEY *pkey)
+static VALUE
+pkey_new0(EVP_PKEY *pkey)
{
- if (!pkey) {
- ossl_raise(ePKeyError, "Cannot make new key from NULL.");
- }
+ if (!pkey)
+ ossl_raise(ePKeyError, "cannot make new key from NULL");
+
switch (EVP_PKEY_base_id(pkey)) {
#if !defined(OPENSSL_NO_RSA)
case EVP_PKEY_RSA:
@@ -96,8 +96,21 @@ ossl_pkey_new(EVP_PKEY *pkey)
default:
ossl_raise(ePKeyError, "unsupported key type");
}
+}
- UNREACHABLE;
+VALUE
+ossl_pkey_new(EVP_PKEY *pkey)
+{
+ VALUE obj;
+ int status;
+
+ obj = rb_protect((VALUE (*)(VALUE))pkey_new0, (VALUE)pkey, &status);
+ if (status) {
+ EVP_PKEY_free(pkey);
+ rb_jump_tag(status);
+ }
+
+ return obj;
}
/*