summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--ext/openssl/ossl_pkey.c7
-rw-r--r--test/openssl/test_pkey_rsa.rb30
-rw-r--r--test/ruby/envutil.rb4
-rw-r--r--version.h8
5 files changed, 48 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index cf886a708f..15ffc26ba8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Thu May 8 01:51:19 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * ext/openssl/ossl_pkey.c (ossl_pkey_verify): as EVP_VerifyFinal()
+ finalizes only a copy of the digest context, the context must be
+ cleaned up after initialization by EVP_MD_CTX_cleanup() or a
+ memory leak will occur. [ruby-core:62038] [Bug #9743]
+
Wed Apr 30 16:39:43 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/readline/extconf.rb (rl_hook_func_t): check pointer type.
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index 0004d9d9b5..878b221270 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -318,13 +318,16 @@ ossl_pkey_verify(VALUE self, VALUE digest, VALUE sig, VALUE data)
{
EVP_PKEY *pkey;
EVP_MD_CTX ctx;
+ int result;
GetPKey(self, pkey);
- EVP_VerifyInit(&ctx, GetDigestPtr(digest));
StringValue(sig);
StringValue(data);
+ EVP_VerifyInit(&ctx, GetDigestPtr(digest));
EVP_VerifyUpdate(&ctx, RSTRING_PTR(data), RSTRING_LEN(data));
- switch (EVP_VerifyFinal(&ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey)) {
+ result = EVP_VerifyFinal(&ctx, (unsigned char *)RSTRING_PTR(sig), RSTRING_LENINT(sig), pkey);
+ EVP_MD_CTX_cleanup(&ctx);
+ switch (result) {
case 0:
return Qfalse;
case 1:
diff --git a/test/openssl/test_pkey_rsa.rb b/test/openssl/test_pkey_rsa.rb
index 1881525c02..ce9bd60c2f 100644
--- a/test/openssl/test_pkey_rsa.rb
+++ b/test/openssl/test_pkey_rsa.rb
@@ -75,6 +75,36 @@ class OpenSSL::TestPKeyRSA < Test::Unit::TestCase
assert(key.verify(digest, sig, data))
end
+ def test_sign_verify_memory_leak
+ bug9743 = '[ruby-core:62038] [Bug #9743]'
+ assert_no_memory_leak(%w[-ropenssl], <<-PREP, <<-CODE, bug9743, rss: true)
+ data = 'Sign me!'
+ digest = OpenSSL::Digest::SHA512.new
+ pkey = OpenSSL::PKey::RSA.new(2048)
+ signature = pkey.sign(digest, data)
+ pub_key = pkey.public_key
+ PREP
+ 20_000.times {
+ pub_key.verify(digest, signature, data)
+ }
+ CODE
+
+ assert_no_memory_leak(%w[-ropenssl], <<-PREP, <<-CODE, bug9743, rss: true)
+ data = 'Sign me!'
+ digest = OpenSSL::Digest::SHA512.new
+ pkey = OpenSSL::PKey::RSA.new(2048)
+ signature = pkey.sign(digest, data)
+ pub_key = pkey.public_key
+ PREP
+ 20_000.times {
+ begin
+ pub_key.verify(digest, signature, 1)
+ rescue TypeError
+ end
+ }
+ CODE
+ end
+
def test_digest_state_irrelevant_sign
key = OpenSSL::TestUtils::TEST_KEY_RSA1024
digest1 = OpenSSL::Digest::SHA1.new
diff --git a/test/ruby/envutil.rb b/test/ruby/envutil.rb
index cacb609a18..fc196f4b30 100644
--- a/test/ruby/envutil.rb
+++ b/test/ruby/envutil.rb
@@ -340,7 +340,7 @@ eom
assert_warning(*args) {$VERBOSE = false; yield}
end
- def assert_no_memory_leak(args, prepare, code, message=nil, limit: 2.0)
+ def assert_no_memory_leak(args, prepare, code, message=nil, limit: 2.0, rss: false)
require_relative 'memory_status'
token = "\e[7;1m#{$$.to_s}:#{Time.now.strftime('%s.%L')}:#{rand(0x10000).to_s(16)}:\e[m"
token_dump = token.dump
@@ -363,7 +363,7 @@ eom
before = err.sub!(/^#{token_re}START=(\{.*\})\n/, '') && Memory::Status.parse($1)
after = err.sub!(/^#{token_re}FINAL=(\{.*\})\n/, '') && Memory::Status.parse($1)
assert_equal([true, ""], [status.success?, err], message)
- ([:size, :rss] & after.members).each do |n|
+ ([:size, (rss && :rss)] & after.members).each do |n|
b = before[n]
a = after[n]
next unless a > 0 and b > 0
diff --git a/version.h b/version.h
index d74ce7e8fb..2362cc81cb 100644
--- a/version.h
+++ b/version.h
@@ -1,10 +1,10 @@
#define RUBY_VERSION "2.0.0"
-#define RUBY_RELEASE_DATE "2014-04-30"
-#define RUBY_PATCHLEVEL 477
+#define RUBY_RELEASE_DATE "2014-05-08"
+#define RUBY_PATCHLEVEL 478
#define RUBY_RELEASE_YEAR 2014
-#define RUBY_RELEASE_MONTH 4
-#define RUBY_RELEASE_DAY 30
+#define RUBY_RELEASE_MONTH 5
+#define RUBY_RELEASE_DAY 8
#include "ruby/version.h"