diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2016-07-24 15:02:42 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2016-10-16 21:41:12 +0900 |
commit | c0c7db9336a4dc99e85192ce29ff549b8d92f8fc (patch) | |
tree | fd1cea494963820ab49fe9604329012001bae185 /ext | |
parent | 1dd7c25d53eca4ec7965bb9b9cf5e2b837555686 (diff) | |
download | ruby-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.c | 25 |
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; } /* |