summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-03-22 03:33:56 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-03-22 03:33:56 +0000
commitc2fdfb05a4db5cec1193ba3f5a2ef315d7698281 (patch)
tree1287d33034c2b5506e9158d4808b35025f71a812
parent85ddcb935791939d107cf11db7b3839f82b95cb0 (diff)
merge https://github.com/ruby/openssl/commit/3af2635f117f8da563d180bc1c58702aecb16e0c
patched by Kazuki Yamaguchi <k@rhe.jp> bio: prevent possible GC issue in ossl_obj2bio() Prevent the new object created by StringValue() from being GCed. Luckily, as none of the callers of ossl_obj2bio() reads from the returned BIO after possible triggering GC, this has not been a real problem. As a bonus, ossl_protect_obj2bio() function which is no longer used anywhere is removed. merge https://github.com/ruby/openssl/commit/f842b0d5c5e37527c11954a4b7a98c8d9cc57865 patched by Kazuki Yamaguchi <k@rhe.jp> bio: do not use the FILE BIO method in ossl_obj2bio() Read everything from an IO object into a String first and use the memory buffer BIO method just as we do for String inputs. For MSVC builds, the FILE BIO method uses the "UPLINK" interface that requires the application to provide OPENSSL_Applink() function. For us, the "application" means ruby.exe, in which we can't do anything. As a workaround, avoid using the FILE BIO method at all. Usually private keys or X.509 certificates aren't that large and the temporarily increased memory usage hopefully won't be an issue. ext/openssl/ossl_version.h (OpenSSL::VERSION): bump to 1.1.1. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_3@62885 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog33
-rw-r--r--ext/openssl/ossl_bio.c44
-rw-r--r--ext/openssl/ossl_bio.h3
-rw-r--r--ext/openssl/ossl_config.c2
-rw-r--r--ext/openssl/ossl_pkcs12.c2
-rw-r--r--ext/openssl/ossl_pkcs7.c14
-rw-r--r--ext/openssl/ossl_pkey.c2
-rw-r--r--ext/openssl/ossl_pkey_dh.c2
-rw-r--r--ext/openssl/ossl_pkey_dsa.c2
-rw-r--r--ext/openssl/ossl_pkey_ec.c6
-rw-r--r--ext/openssl/ossl_pkey_rsa.c2
-rw-r--r--ext/openssl/ossl_ssl_session.c2
-rw-r--r--ext/openssl/ossl_version.h2
-rw-r--r--ext/openssl/ossl_x509cert.c2
-rw-r--r--ext/openssl/ossl_x509crl.c2
-rw-r--r--ext/openssl/ossl_x509req.c2
-rw-r--r--test/openssl/test_x509cert.rb10
-rw-r--r--version.h2
18 files changed, 75 insertions, 59 deletions
diff --git a/ChangeLog b/ChangeLog
index 10675ff13f..fc12b75d38 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+Thu Mar 22 12:28:23 2018 NAKAMURA Usaku <usa@ruby-lang.org>
+
+ merge https://github.com/ruby/openssl/commit/3af2635f117f8da563d180bc1c58702aecb16e0c
+ patched by Kazuki Yamaguchi <k@rhe.jp>
+
+ bio: prevent possible GC issue in ossl_obj2bio()
+
+ Prevent the new object created by StringValue() from being GCed.
+ Luckily, as none of the callers of ossl_obj2bio() reads from the
+ returned BIO after possible triggering GC, this has not been a real
+ problem.
+
+ As a bonus, ossl_protect_obj2bio() function which is no longer used
+ anywhere is removed.
+
+ merge https://github.com/ruby/openssl/commit/f842b0d5c5e37527c11954a4b7a98c8d9cc57865
+ patched by Kazuki Yamaguchi <k@rhe.jp>
+
+ bio: do not use the FILE BIO method in ossl_obj2bio()
+
+ Read everything from an IO object into a String first and use the
+ memory buffer BIO method just as we do for String inputs.
+
+ For MSVC builds, the FILE BIO method uses the "UPLINK" interface that
+ requires the application to provide OPENSSL_Applink() function. For us,
+ the "application" means ruby.exe, in which we can't do anything. As a
+ workaround, avoid using the FILE BIO method at all.
+
+ Usually private keys or X.509 certificates aren't that large and the
+ temporarily increased memory usage hopefully won't be an issue.
+
+ ext/openssl/ossl_version.h (OpenSSL::VERSION): bump to 1.1.1.
+
Thu Mar 22 11:24:43 2018 NAKAMURA Usaku <usa@ruby-lang.org>
* win32/win32.c (set_pioinfo_extra): use more reliable way to search
diff --git a/ext/openssl/ossl_bio.c b/ext/openssl/ossl_bio.c
index cd2582646b..285d0533e7 100644
--- a/ext/openssl/ossl_bio.c
+++ b/ext/openssl/ossl_bio.c
@@ -13,48 +13,22 @@
#endif
BIO *
-ossl_obj2bio(VALUE obj)
+ossl_obj2bio(volatile VALUE *pobj)
{
+ VALUE obj = *pobj;
BIO *bio;
- if (RB_TYPE_P(obj, T_FILE)) {
- rb_io_t *fptr;
- FILE *fp;
- int fd;
-
- GetOpenFile(obj, fptr);
- rb_io_check_readable(fptr);
- if ((fd = rb_cloexec_dup(FPTR_TO_FD(fptr))) < 0){
- rb_sys_fail(0);
- }
- rb_update_max_fd(fd);
- if (!(fp = fdopen(fd, "r"))){
- int e = errno;
- close(fd);
- rb_syserr_fail(e, 0);
- }
- if (!(bio = BIO_new_fp(fp, BIO_CLOSE))){
- fclose(fp);
- ossl_raise(eOSSLError, NULL);
- }
- }
- else {
- StringValue(obj);
- bio = BIO_new_mem_buf(RSTRING_PTR(obj), RSTRING_LENINT(obj));
- if (!bio) ossl_raise(eOSSLError, NULL);
- }
+ if (RB_TYPE_P(obj, T_FILE))
+ obj = rb_funcallv(obj, rb_intern("read"), 0, NULL);
+ StringValue(obj);
+ bio = BIO_new_mem_buf(RSTRING_PTR(obj), RSTRING_LENINT(obj));
+ if (!bio)
+ ossl_raise(eOSSLError, "BIO_new_mem_buf");
+ *pobj = obj;
return bio;
}
-BIO *
-ossl_protect_obj2bio(VALUE obj, int *status)
-{
- BIO *ret = NULL;
- ret = (BIO*)rb_protect((VALUE(*)_((VALUE)))ossl_obj2bio, obj, status);
- return ret;
-}
-
VALUE
ossl_membio2str0(BIO *bio)
{
diff --git a/ext/openssl/ossl_bio.h b/ext/openssl/ossl_bio.h
index 1705d0ac89..2c3d952b38 100644
--- a/ext/openssl/ossl_bio.h
+++ b/ext/openssl/ossl_bio.h
@@ -10,8 +10,7 @@
#if !defined(_OSSL_BIO_H_)
#define _OSSL_BIO_H_
-BIO *ossl_obj2bio(VALUE);
-BIO *ossl_protect_obj2bio(VALUE,int*);
+BIO *ossl_obj2bio(volatile VALUE *);
VALUE ossl_membio2str0(BIO*);
VALUE ossl_membio2str(BIO*);
VALUE ossl_protect_membio2str(BIO*,int*);
diff --git a/ext/openssl/ossl_config.c b/ext/openssl/ossl_config.c
index 47d2658453..5748d514dd 100644
--- a/ext/openssl/ossl_config.c
+++ b/ext/openssl/ossl_config.c
@@ -41,7 +41,7 @@ DupConfigPtr(VALUE obj)
OSSL_Check_Kind(obj, cConfig);
str = rb_funcall(obj, rb_intern("to_s"), 0);
- bio = ossl_obj2bio(str);
+ bio = ossl_obj2bio(&str);
conf = NCONF_new(NULL);
if(!conf){
BIO_free(bio);
diff --git a/ext/openssl/ossl_pkcs12.c b/ext/openssl/ossl_pkcs12.c
index 2a42ee973b..f2edd99057 100644
--- a/ext/openssl/ossl_pkcs12.c
+++ b/ext/openssl/ossl_pkcs12.c
@@ -159,7 +159,7 @@ ossl_pkcs12_initialize(int argc, VALUE *argv, VALUE self)
if(rb_scan_args(argc, argv, "02", &arg, &pass) == 0) return self;
passphrase = NIL_P(pass) ? NULL : StringValuePtr(pass);
- in = ossl_obj2bio(arg);
+ in = ossl_obj2bio(&arg);
d2i_PKCS12_bio(in, &pkcs);
DATA_PTR(self) = pkcs;
BIO_free(in);
diff --git a/ext/openssl/ossl_pkcs7.c b/ext/openssl/ossl_pkcs7.c
index 04e41db598..62570a443a 100644
--- a/ext/openssl/ossl_pkcs7.c
+++ b/ext/openssl/ossl_pkcs7.c
@@ -193,7 +193,7 @@ ossl_pkcs7_s_read_smime(VALUE klass, VALUE arg)
VALUE ret, data;
ret = NewPKCS7(cPKCS7);
- in = ossl_obj2bio(arg);
+ in = ossl_obj2bio(&arg);
out = NULL;
pkcs7 = SMIME_read_PKCS7(in, &out);
BIO_free(in);
@@ -225,7 +225,7 @@ ossl_pkcs7_s_write_smime(int argc, VALUE *argv, VALUE klass)
SafeGetPKCS7(pkcs7, p7);
if(!NIL_P(data) && PKCS7_is_detached(p7))
flg |= PKCS7_DETACHED;
- in = NIL_P(data) ? NULL : ossl_obj2bio(data);
+ in = NIL_P(data) ? NULL : ossl_obj2bio(&data);
if(!(out = BIO_new(BIO_s_mem()))){
BIO_free(in);
ossl_raise(ePKCS7Error, NULL);
@@ -262,7 +262,7 @@ ossl_pkcs7_s_sign(int argc, VALUE *argv, VALUE klass)
pkey = GetPrivPKeyPtr(key); /* NO NEED TO DUP */
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
ret = NewPKCS7(cPKCS7);
- in = ossl_obj2bio(data);
+ in = ossl_obj2bio(&data);
if(NIL_P(certs)) x509s = NULL;
else{
x509s = ossl_protect_x509_ary2sk(certs, &status);
@@ -318,7 +318,7 @@ ossl_pkcs7_s_encrypt(int argc, VALUE *argv, VALUE klass)
else ciph = GetCipherPtr(cipher); /* NO NEED TO DUP */
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
ret = NewPKCS7(cPKCS7);
- in = ossl_obj2bio(data);
+ in = ossl_obj2bio(&data);
x509s = ossl_protect_x509_ary2sk(certs, &status);
if(status){
BIO_free(in);
@@ -369,7 +369,7 @@ ossl_pkcs7_initialize(int argc, VALUE *argv, VALUE self)
if(rb_scan_args(argc, argv, "01", &arg) == 0)
return self;
arg = ossl_to_der_if_possible(arg);
- in = ossl_obj2bio(arg);
+ in = ossl_obj2bio(&arg);
p7 = PEM_read_bio_PKCS7(in, &pkcs, NULL, NULL);
if (!p7) {
OSSL_BIO_reset(in);
@@ -760,7 +760,7 @@ ossl_pkcs7_verify(int argc, VALUE *argv, VALUE self)
x509st = GetX509StorePtr(store);
flg = NIL_P(flags) ? 0 : NUM2INT(flags);
if(NIL_P(indata)) indata = ossl_pkcs7_get_data(self);
- in = NIL_P(indata) ? NULL : ossl_obj2bio(indata);
+ in = NIL_P(indata) ? NULL : ossl_obj2bio(&indata);
if(NIL_P(certs)) x509s = NULL;
else{
x509s = ossl_protect_x509_ary2sk(certs, &status);
@@ -827,7 +827,7 @@ ossl_pkcs7_add_data(VALUE self, VALUE data)
if(!PKCS7_content_new(pkcs7, NID_pkcs7_data))
ossl_raise(ePKCS7Error, NULL);
}
- in = ossl_obj2bio(data);
+ in = ossl_obj2bio(&data);
if(!(out = PKCS7_dataInit(pkcs7, NULL))) goto err;
for(;;){
if((len = BIO_read(in, buf, sizeof(buf))) <= 0)
diff --git a/ext/openssl/ossl_pkey.c b/ext/openssl/ossl_pkey.c
index e758c9e331..c551a7d775 100644
--- a/ext/openssl/ossl_pkey.c
+++ b/ext/openssl/ossl_pkey.c
@@ -159,7 +159,7 @@ ossl_pkey_new_from_data(int argc, VALUE *argv, VALUE self)
rb_scan_args(argc, argv, "11", &data, &pass);
- bio = ossl_obj2bio(data);
+ bio = ossl_obj2bio(&data);
if (!(pkey = d2i_PrivateKey_bio(bio, NULL))) {
OSSL_BIO_reset(bio);
if (!NIL_P(pass)) {
diff --git a/ext/openssl/ossl_pkey_dh.c b/ext/openssl/ossl_pkey_dh.c
index 3668acb165..e1cf425bf9 100644
--- a/ext/openssl/ossl_pkey_dh.c
+++ b/ext/openssl/ossl_pkey_dh.c
@@ -225,7 +225,7 @@ ossl_dh_initialize(int argc, VALUE *argv, VALUE self)
}
else {
arg = ossl_to_der_if_possible(arg);
- in = ossl_obj2bio(arg);
+ in = ossl_obj2bio(&arg);
dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
if (!dh){
OSSL_BIO_reset(in);
diff --git a/ext/openssl/ossl_pkey_dsa.c b/ext/openssl/ossl_pkey_dsa.c
index 1fe5753a4e..2f0b43e26c 100644
--- a/ext/openssl/ossl_pkey_dsa.c
+++ b/ext/openssl/ossl_pkey_dsa.c
@@ -224,7 +224,7 @@ ossl_dsa_initialize(int argc, VALUE *argv, VALUE self)
else {
if (!NIL_P(pass)) passwd = StringValuePtr(pass);
arg = ossl_to_der_if_possible(arg);
- in = ossl_obj2bio(arg);
+ in = ossl_obj2bio(&arg);
dsa = PEM_read_bio_DSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
if (!dsa) {
OSSL_BIO_reset(in);
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c
index 09987e5426..a41c48d9c3 100644
--- a/ext/openssl/ossl_pkey_ec.c
+++ b/ext/openssl/ossl_pkey_ec.c
@@ -188,7 +188,7 @@ static VALUE ossl_ec_key_initialize(int argc, VALUE *argv, VALUE self)
ec = EC_KEY_new();
group = arg;
} else {
- BIO *in = ossl_obj2bio(arg);
+ BIO *in = ossl_obj2bio(&arg);
if (!NIL_P(pass)) {
passwd = StringValuePtr(pass);
@@ -792,7 +792,7 @@ static VALUE ossl_ec_group_initialize(int argc, VALUE *argv, VALUE self)
if ((group = EC_GROUP_dup(arg1_group)) == NULL)
ossl_raise(eEC_GROUP, "EC_GROUP_dup");
} else {
- BIO *in = ossl_obj2bio(arg1);
+ BIO *in = ossl_obj2bio(&arg1);
group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
if (!group) {
@@ -1307,7 +1307,7 @@ static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)
point = EC_POINT_bn2point(group, bn, NULL, ossl_bn_ctx);
} else {
- BIO *in = ossl_obj2bio(arg1);
+ BIO *in = ossl_obj2bio(&arg1);
/* BUG: finish me */
diff --git a/ext/openssl/ossl_pkey_rsa.c b/ext/openssl/ossl_pkey_rsa.c
index 26b1fbe1b6..0262fdafdc 100644
--- a/ext/openssl/ossl_pkey_rsa.c
+++ b/ext/openssl/ossl_pkey_rsa.c
@@ -220,7 +220,7 @@ ossl_rsa_initialize(int argc, VALUE *argv, VALUE self)
else {
if (!NIL_P(pass)) passwd = StringValuePtr(pass);
arg = ossl_to_der_if_possible(arg);
- in = ossl_obj2bio(arg);
+ in = ossl_obj2bio(&arg);
rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ossl_pem_passwd_cb, passwd);
if (!rsa) {
OSSL_BIO_reset(in);
diff --git a/ext/openssl/ossl_ssl_session.c b/ext/openssl/ossl_ssl_session.c
index e1bbc6fb54..360f9161ec 100644
--- a/ext/openssl/ossl_ssl_session.c
+++ b/ext/openssl/ossl_ssl_session.c
@@ -49,7 +49,7 @@ static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1)
if (!ssl || (ctx = SSL_get1_session(ssl)) == NULL)
ossl_raise(eSSLSession, "no session available");
} else {
- BIO *in = ossl_obj2bio(arg1);
+ BIO *in = ossl_obj2bio(&arg1);
ctx = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);
diff --git a/ext/openssl/ossl_version.h b/ext/openssl/ossl_version.h
index dcd026a19c..db5d6dc2d4 100644
--- a/ext/openssl/ossl_version.h
+++ b/ext/openssl/ossl_version.h
@@ -10,6 +10,6 @@
#if !defined(_OSSL_VERSION_H_)
#define _OSSL_VERSION_H_
-#define OSSL_VERSION "1.1.0"
+#define OSSL_VERSION "1.1.1"
#endif /* _OSSL_VERSION_H_ */
diff --git a/ext/openssl/ossl_x509cert.c b/ext/openssl/ossl_x509cert.c
index 4dafae17b9..9cf7405256 100644
--- a/ext/openssl/ossl_x509cert.c
+++ b/ext/openssl/ossl_x509cert.c
@@ -161,7 +161,7 @@ ossl_x509_initialize(int argc, VALUE *argv, VALUE self)
return self;
}
arg = ossl_to_der_if_possible(arg);
- in = ossl_obj2bio(arg);
+ in = ossl_obj2bio(&arg);
x509 = PEM_read_bio_X509(in, &x, NULL, NULL);
DATA_PTR(self) = x;
if (!x509) {
diff --git a/ext/openssl/ossl_x509crl.c b/ext/openssl/ossl_x509crl.c
index 3905762d3c..e5a5c6b183 100644
--- a/ext/openssl/ossl_x509crl.c
+++ b/ext/openssl/ossl_x509crl.c
@@ -115,7 +115,7 @@ ossl_x509crl_initialize(int argc, VALUE *argv, VALUE self)
return self;
}
arg = ossl_to_der_if_possible(arg);
- in = ossl_obj2bio(arg);
+ in = ossl_obj2bio(&arg);
crl = PEM_read_bio_X509_CRL(in, &x, NULL, NULL);
DATA_PTR(self) = x;
if (!crl) {
diff --git a/ext/openssl/ossl_x509req.c b/ext/openssl/ossl_x509req.c
index 0c13c8ca3e..71a7e0120c 100644
--- a/ext/openssl/ossl_x509req.c
+++ b/ext/openssl/ossl_x509req.c
@@ -123,7 +123,7 @@ ossl_x509req_initialize(int argc, VALUE *argv, VALUE self)
return self;
}
arg = ossl_to_der_if_possible(arg);
- in = ossl_obj2bio(arg);
+ in = ossl_obj2bio(&arg);
req = PEM_read_bio_X509_REQ(in, &x, NULL, NULL);
DATA_PTR(self) = x;
if (!req) {
diff --git a/test/openssl/test_x509cert.rb b/test/openssl/test_x509cert.rb
index 72cb9e6095..313f563a0d 100644
--- a/test/openssl/test_x509cert.rb
+++ b/test/openssl/test_x509cert.rb
@@ -215,6 +215,16 @@ class OpenSSL::TestX509Certificate < Test::Unit::TestCase
assert_equal(true, cert.check_private_key(@rsa2048))
end
+ def test_read_from_file
+ cert = issue_cert(@ca, @rsa2048, 1, Time.now, Time.now+3600, [],
+ nil, nil, OpenSSL::Digest::SHA1.new)
+ Tempfile.create("cert") { |f|
+ f << cert.to_pem
+ f.rewind
+ assert_equal cert.to_der, OpenSSL::X509::Certificate.new(f).to_der
+ }
+ end
+
private
def certificate_error_returns_false
diff --git a/version.h b/version.h
index 1947c9ce32..97e7eaec2d 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.3.7"
#define RUBY_RELEASE_DATE "2018-03-22"
-#define RUBY_PATCHLEVEL 431
+#define RUBY_PATCHLEVEL 432
#define RUBY_RELEASE_YEAR 2018
#define RUBY_RELEASE_MONTH 3