Patchwork Fix signed integer overflow in random_r (bug 17343)

login
register
mail settings
Submitter Joseph Myers
Date March 16, 2018, 5:33 p.m.
Message ID <alpine.DEB.2.20.1803161732060.20069@digraph.polyomino.org.uk>
Download mbox | patch
Permalink /patch/26341/
State New
Headers show

Comments

Joseph Myers - March 16, 2018, 5:33 p.m.
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.

2018-03-16  Joseph Myers  <joseph@codesourcery.com>

	[BZ #17343]
	* stdlib/random_r.c (__random_r): Use unsigned arithmetic for
	possibly overflowing computations.
Paul Eggert - March 17, 2018, 12:26 a.m.
Joseph Myers wrote:
>         int32_t val = state[0];
> -      val = ((state[0] * 1103515245) + 12345) & 0x7fffffff;
> +      val = ((state[0] * 1103515245U) + 12345U) & 0x7fffffff;

The first assignment to VAL (in the unchanged line) is unnecessary; I suggest 
coalescing the two lines.

Patch

diff --git a/stdlib/random_r.c b/stdlib/random_r.c
index 4d2f0d4..996f624 100644
--- a/stdlib/random_r.c
+++ b/stdlib/random_r.c
@@ -362,7 +362,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;
+      val = ((state[0] * 1103515245U) + 12345U) & 0x7fffffff;
       state[0] = val;
       *result = val;
     }
@@ -371,9 +371,9 @@  __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;
       ++fptr;