On 06/20/2018 02:34 PM, Bruce Korb wrote:
diff --git a/lib/random_r.c b/lib/random_r.c
index 697ca5f..cd2537a 100644
--- a/lib/random_r.c
+++ b/lib/random_r.c
@@ -286,7 +286,7 @@ __initstate_r (unsigned int seed, char *arg_state,
size_t n,
   buf->rand_type = type;
   buf->rand_sep = separation;
   buf->rand_deg = degree;
-  state = &((int32_t *) arg_state)[1];  /* First location.  */
+  state = &((int32_t *) (unsigned long) arg_state)[1];  /* First location.

Shouldn't that be (uintptr_t) rather than (unsigned long), to be safe on machines where long is 32 bits but pointers are 64 (hello Windows)?

libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I.. -g -O2 -Wcast-align
-Wmissing-prototypes -Wpointer-arith -Wshadow -Wstrict-prototypes
-Wwrite-strings -Wno-format -fno-strict-aliasing -Wstrict-aliasing=2 -MT
random_r.lo -MD -MP -MF .deps/random_r.Tpo -c random_r.c  -fno-common -DPIC
-o .libs/random_r.o
random_r.c:289:13: warning: cast from 'char *' to 'int32_t *' (aka 'int *')
increases required alignment from 1 to 4
       [-Wcast-align]
   state = &((int32_t *) arg_state)[1];  /* First location.  */
             ^~~~~~~~~~~~~~~~~~~~~

Eww. Adding your cast is silencing the warning but is NOT fixing the alignment bug. You cannot blindly dereference an unaligned byte pointer as though it were an int pointer, because that will SIGBUS on architectures that do not support unaligned pointers (x86 has spoiled you). You'll have to memcpy, or use unions to enforce proper alignment, or something similar to get this code to work correctly; a mere cast is NOT the solution.

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

Reply via email to