about summary refs log tree commit diff
path: root/stdlib/random_r.c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2018-05-17 14:04:58 +0200
committerFlorian Weimer <fweimer@redhat.com>2018-05-17 14:04:58 +0200
commit02f0dd83a4abf190f13eef8d70811a7c8ec896ad (patch)
tree07d3d11f0bf0bf4540ea3e72e19f475e95537bc3 /stdlib/random_r.c
parent3241353ab20b4cc8798088d456ffa9aace1514de (diff)
downloadglibc-02f0dd83a4abf190f13eef8d70811a7c8ec896ad.tar.gz
glibc-02f0dd83a4abf190f13eef8d70811a7c8ec896ad.tar.xz
glibc-02f0dd83a4abf190f13eef8d70811a7c8ec896ad.zip
Fix signed integer overflow in random_r (bug 17343).
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)
Diffstat (limited to 'stdlib/random_r.c')
-rw-r--r--stdlib/random_r.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/stdlib/random_r.c b/stdlib/random_r.c
index c3f6f9aede..150fa9bb34 100644
--- a/stdlib/random_r.c
+++ b/stdlib/random_r.c
@@ -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)
 	{