]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
stdlib: Fix UB on erand48/jrand48
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Tue, 22 Apr 2025 17:06:33 +0000 (14:06 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Wed, 7 May 2025 17:21:21 +0000 (14:21 -0300)
With glibc built with ubsan it triggers:

UBSAN: Undefined behaviour in jrand48_r.c:29:34 left shift of 41612 by 16 cannot be represented in type 'int'
UBSAN: Undefined behaviour in erand48_r.c:39:45 left shift of 3972 by 20 cannot be represented in type 'int'

Fix by casting to uint32_t for the shift operation.

stdlib/erand48_r.c
stdlib/jrand48_r.c

index ae68a5b5a06592b86676df595d5eaf9a93b5d9d7..6d540cb2c05b129ec12b55d936ca6ae07440f901 100644 (file)
@@ -36,7 +36,8 @@ __erand48_r (unsigned short int xsubi[3], struct drand48_data *buffer,
   temp.ieee.negative = 0;
   temp.ieee.exponent = IEEE754_DOUBLE_BIAS;
   temp.ieee.mantissa0 = (xsubi[2] << 4) | (xsubi[1] >> 12);
-  temp.ieee.mantissa1 = ((xsubi[1] & 0xfff) << 20) | (xsubi[0] << 4);
+  temp.ieee.mantissa1 = (((uint32_t)xsubi[1] & 0xfff) << 20)
+    | ((uint32_t)xsubi[0] << 4);
 
   /* Please note the lower 4 bits of mantissa1 are always 0.  */
   *result = temp.d - 1.0;
index 6fe2863bef5bf5c74ca984cb5d03cb6cdf88fbe1..aa9d7de316d1fe1d9e4653f95389b2fa6e5d21fa 100644 (file)
@@ -26,7 +26,7 @@ __jrand48_r (unsigned short int xsubi[3], struct drand48_data *buffer,
     return -1;
 
   /* Store the result.  */
-  *result = (int32_t) ((xsubi[2] << 16) | xsubi[1]);
+  *result = (int32_t) (((uint32_t)xsubi[2] << 16) | (uint32_t)xsubi[1]);
 
   return 0;
 }