]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix signed integer overflow in random_r (bug 17343).
authorJoseph Myers <joseph@codesourcery.com>
Tue, 20 Mar 2018 18:25:24 +0000 (18:25 +0000)
committerFangrui Song <i@maskray.me>
Fri, 27 Aug 2021 23:22:09 +0000 (16:22 -0700)
Bug 17343 reports that stdlib/random_r.c has code with undefined
behavior because of signed integer overflow on int32_t.  This patch
changes the code so that the possibly overflowing computations use
unsigned arithmetic instead.

Note that the bug report refers to "Most code" in that file.  The
places changed in this patch are the only ones I found where I think
such overflow can occur.

Tested for x86_64 and x86.

[BZ #17343]
* stdlib/random_r.c (__random_r): Use unsigned arithmetic for
possibly overflowing computations.

(cherry picked from commit 8a07b0c43c46a480da070efd53a2720195e2256f)

ChangeLog
stdlib/random_r.c

index e81b39dafb771bdeb2e001b185f125251c3185e6..f9d7618431f1ae85e6cb4607d28851ea1395fb59 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-03-20  Joseph Myers  <joseph@codesourcery.com>
+
+       [BZ #17343]
+       * stdlib/random_r.c (__random_r): Use unsigned arithmetic for
+       possibly overflowing computations.
+
 2018-04-26  Aurelien Jarno  <aurelien@aurel32.net>
 
        * signal/tst-sigaction.c: New file to test BZ #23069.
index 4d2f0d472f3246b4c62b078c2db18ca6588635bd..b47c65c6d723bd852f439885c1ec56a2c559323c 100644 (file)
@@ -361,8 +361,7 @@ __random_r (struct random_data *buf, int32_t *result)
 
   if (buf->rand_type == TYPE_0)
     {
-      int32_t val = state[0];
-      val = ((state[0] * 1103515245) + 12345) & 0x7fffffff;
+      int32_t val = ((state[0] * 1103515245U) + 12345U) & 0x7fffffff;
       state[0] = val;
       *result = val;
     }
@@ -371,11 +370,11 @@ __random_r (struct random_data *buf, int32_t *result)
       int32_t *fptr = buf->fptr;
       int32_t *rptr = buf->rptr;
       int32_t *end_ptr = buf->end_ptr;
-      int32_t val;
+      uint32_t val;
 
-      val = *fptr += *rptr;
+      val = *fptr += (uint32_t) *rptr;
       /* Chucking least random bit.  */
-      *result = (val >> 1) & 0x7fffffff;
+      *result = val >> 1;
       ++fptr;
       if (fptr >= end_ptr)
        {