[前][次][番号順一覧][スレッド一覧]

ruby-changes:68494

From: Kazuki <ko1@a...>
Date: Sat, 16 Oct 2021 19:53:27 +0900 (JST)
Subject: [ruby-changes:68494] daeb914a52 (master): [ruby/openssl] ssl: temporary lock string buffer while reading

https://git.ruby-lang.org/ruby.git/commit/?id=daeb914a52

From daeb914a525dd7b9faf6ba9f4596deafa22b065a Mon Sep 17 00:00:00 2001
From: Kazuki Yamaguchi <k@r...>
Date: Mon, 30 Aug 2021 18:55:10 +0900
Subject: [ruby/openssl] ssl: temporary lock string buffer while reading

Similarly to SSLSocket#syswrite, the blocking SSLSocket#sysread allows
context switches. We must prevent other threads from modifying the
string buffer.

We can use rb_str_locktmp() and rb_str_unlocktmp() to temporarily
prohibit modification of the string.

https://github.com/ruby/openssl/commit/d38274949f
---
 ext/openssl/ossl_ssl.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 6d1d84aa5b..1b7586cc88 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -1806,26 +1806,36 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ssl.c#L1806
     io = rb_attr_get(self, id_i_io);
     GetOpenFile(io, fptr);
     if (ssl_started(ssl)) {
-	for (;;){
+        rb_str_locktmp(str);
+        for (;;) {
 	    nread = SSL_read(ssl, RSTRING_PTR(str), ilen);
 	    switch(ssl_get_error(ssl, nread)){
 	    case SSL_ERROR_NONE:
+                rb_str_unlocktmp(str);
 		goto end;
 	    case SSL_ERROR_ZERO_RETURN:
+                rb_str_unlocktmp(str);
 		if (no_exception_p(opts)) { return Qnil; }
 		rb_eof_error();
 	    case SSL_ERROR_WANT_WRITE:
-		if (no_exception_p(opts)) { return sym_wait_writable; }
-                write_would_block(nonblock);
+                if (nonblock) {
+                    rb_str_unlocktmp(str);
+                    if (no_exception_p(opts)) { return sym_wait_writable; }
+                    write_would_block(nonblock);
+                }
                 io_wait_writable(fptr);
                 continue;
 	    case SSL_ERROR_WANT_READ:
-		if (no_exception_p(opts)) { return sym_wait_readable; }
-                read_would_block(nonblock);
+                if (nonblock) {
+                    rb_str_unlocktmp(str);
+                    if (no_exception_p(opts)) { return sym_wait_readable; }
+                    read_would_block(nonblock);
+                }
                 io_wait_readable(fptr);
 		continue;
 	    case SSL_ERROR_SYSCALL:
 		if (!ERR_peek_error()) {
+                    rb_str_unlocktmp(str);
 		    if (errno)
 			rb_sys_fail(0);
 		    else {
@@ -1842,6 +1852,7 @@ ossl_ssl_read_internal(int argc, VALUE *argv, VALUE self, int nonblock) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_ssl.c#L1852
 		}
                 /* fall through */
 	    default:
+                rb_str_unlocktmp(str);
 		ossl_raise(eSSLError, "SSL_read");
 	    }
         }
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]