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

ruby-changes:49174

From: mame <ko1@a...>
Date: Sat, 16 Dec 2017 09:39:38 +0900 (JST)
Subject: [ruby-changes:49174] mame:r61292 (trunk): random.c: make sure that Random.urandom returns required-length buffer

mame	2017-12-16 09:39:34 +0900 (Sat, 16 Dec 2017)

  New Revision: 61292

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61292

  Log:
    random.c: make sure that Random.urandom returns required-length buffer
    
    getrandom(2) and read(2) (from /dev/urandom) may return a random buffer
    whose length is shorter than required.  This change makes sure that they
    get enough buffer by using a loop.

  Modified files:
    trunk/random.c
Index: random.c
===================================================================
--- random.c	(revision 61291)
+++ random.c	(revision 61292)
@@ -447,14 +447,21 @@ fill_random_bytes_urandom(void *seed, si https://github.com/ruby/ruby/blob/trunk/random.c#L447
 			     O_RDONLY, 0);
     struct stat statbuf;
     ssize_t ret = 0;
+    size_t offset = 0;
 
     if (fd < 0) return -1;
     rb_update_max_fd(fd);
     if (fstat(fd, &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) {
-	ret = read(fd, seed, size);
+	do {
+	    ret = read(fd, ((char*)seed) + offset, size - offset);
+	    if (ret < 0) {
+		close(fd);
+		return -1;
+	    }
+	    offset += (size_t)ret;
+	} while(offset < size);
     }
     close(fd);
-    if (ret < 0 || (size_t)ret < size) return -1;
     return 0;
 }
 #else
@@ -518,16 +525,20 @@ fill_random_bytes_syscall(void *seed, si https://github.com/ruby/ruby/blob/trunk/random.c#L525
     static rb_atomic_t try_syscall = 1;
     if (try_syscall) {
 	long ret;
+	size_t offset = 0;
 	int flags = 0;
 	if (!need_secure)
 	    flags = GRND_NONBLOCK;
-	errno = 0;
-	ret = syscall(__NR_getrandom, seed, size, flags);
-	if (errno == ENOSYS) {
-	    ATOMIC_SET(try_syscall, 0);
-	    return -1;
-	}
-	if ((size_t)ret == size) return 0;
+	do {
+	    errno = 0;
+	    ret = syscall(__NR_getrandom, ((char*)seed) + offset, size - offset, flags);
+	    if (ret == -1) {
+		ATOMIC_SET(try_syscall, 0);
+		return -1;
+	    }
+	    offset += (size_t)ret;
+	} while(offset < size);
+	return 0;
     }
     return -1;
 }

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

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