This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] crypt: Fix strict aliasing warnings


This is an attempt to fix strict aliasing warnings in crypt/.  I've
made use of recent Roland's elfutils patch which addresses this problem
(32899ac4f69d4ca4856d5282464c1f9cee928c8a).  The md5.c part is the same,
the sha{512,256}.c parts are very similar.  I've tested this patch on
x86_64 (LE) and PPC64 (BE) with crypt/{md5,sha256,sha512}c-test.c and with
crypt/{md5,sha256,sha512}test.c.  It seems fine.

Alternatively, I can cook up a patch which just uses `-Wno-strict-aliasing'
or `-fno-strict-aliasing'.

Ok?

2011-07-18  Marek Polacek  <mpolacek@redhat.com>

	* crypt/md5.c (le64_copy): New function.
	(md5_finish_ctx): Use it.
	* crypt/sha256.c (be64_copy): New function.
	(__sha256_finish_ctx): Use it.
	(SWAP64): Remove unused macro.
	* crypt/sha512.c (be64_copy): New function.
	(__sha512_finish_ctx): Use it.

--- libc/crypt/md5.c.mp	2011-07-13 13:37:27.698796939 +0200
+++ libc/crypt/md5.c	2011-07-15 14:18:16.898700264 +0200
@@ -1,6 +1,6 @@
 /* Functions to compute MD5 message digest of files or memory blocks.
    according to the definition of MD5 in RFC 1321 from April 1992.
-   Copyright (C) 1995,1996,1997,1999,2000,2001,2005
+   Copyright (C) 1995,1996,1997,1999,2000,2001,2005,2011
 	Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -100,6 +100,16 @@ md5_read_ctx (ctx, resbuf)
   return resbuf;
 }
 
+static void
+le64_copy (char *dest, uint64_t x)
+{
+  for (size_t i = 0; i < 8; ++i)
+    {
+      dest[i] = (uint8_t) x;
+      x >>= 8;
+    }
+}
+
 /* Process the remaining bytes in the internal buffer and the usual
    prolog according to the standard and write the result to RESBUF.
 
@@ -123,9 +133,10 @@ md5_finish_ctx (ctx, resbuf)
   memcpy (&ctx->buffer[bytes], fillbuf, pad);
 
   /* Put the 64-bit file length in *bits* at the end of the buffer.  */
-  *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3);
-  *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) |
-							(ctx->total[0] >> 29));
+  const uint64_t bit_length = ((ctx->total[0] << 3)
+			       + ((uint64_t) ((ctx->total[1] << 3) |
+					      (ctx->total[0] >> 29)) << 32));
+  le64_copy (&ctx->buffer[bytes + pad], bit_length);
 
   /* Process last bytes.  */
   md5_process_block (ctx->buffer, bytes + pad + 8, ctx);
--- libc/crypt/sha256.c.mp	2011-07-14 15:21:48.560669655 +0200
+++ libc/crypt/sha256.c	2011-07-18 14:33:48.452669821 +0200
@@ -35,23 +35,12 @@
 # ifdef _LIBC
 #  include <byteswap.h>
 #  define SWAP(n) bswap_32 (n)
-#  define SWAP64(n) bswap_64 (n)
 # else
 #  define SWAP(n) \
     (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
-#  define SWAP64(n) \
-  (((n) << 56)					\
-   | (((n) & 0xff00) << 40)			\
-   | (((n) & 0xff0000) << 24)			\
-   | (((n) & 0xff000000) << 8)			\
-   | (((n) >> 8) & 0xff000000)			\
-   | (((n) >> 24) & 0xff0000)			\
-   | (((n) >> 40) & 0xff00)			\
-   | ((n) >> 56))
 # endif
 #else
 # define SWAP(n) (n)
-# define SWAP64(n) (n)
 #endif
 
 
@@ -199,6 +188,12 @@ __sha256_init_ctx (ctx)
   ctx->buflen = 0;
 }
 
+static void
+be64_copy (char *dest, uint64_t x)
+{
+  for (size_t i = 8; i-- > 0; x >>= 8)
+    dest[i] = (uint8_t) x;
+}
 
 /* Process the remaining bytes in the internal buffer and the usual
    prolog according to the standard and write the result to RESBUF.
@@ -222,13 +217,13 @@ __sha256_finish_ctx (ctx, resbuf)
 
   /* Put the 64-bit file length in *bits* at the end of the buffer.  */
 #ifdef _STRING_ARCH_unaligned
-  *(uint64_t *)  &ctx->buffer[bytes + pad] = SWAP64 (ctx->total64 << 3);
+  be64_copy (&ctx->buffer[bytes + pad], ctx->total64 << 3);
 #else
-  *(uint32_t *) &ctx->buffer[bytes + pad + 4]
-    = SWAP (ctx->total[TOTAL64_low] << 3);
-  *(uint32_t *) &ctx->buffer[bytes + pad]
-    = SWAP ((ctx->total[TOTAL64_high] << 3) |
-	    (ctx->total[TOTAL64_low] >> 29));
+  const uint64_t bit_length
+    = ((ctx->total[TOTAL64_low] << 3)
+       + ((uint64_t) ((ctx->total[TOTAL64_high] << 3) |
+		      (ctx->total[TOTAL64_low] >> 29)) << 32));
+  be64_copy (&ctx->buffer[bytes + pad], bit_length);
 #endif
 
   /* Process last bytes.  */
--- libc/crypt/sha512.c.mp	2011-07-18 13:46:51.387794691 +0200
+++ libc/crypt/sha512.c	2011-07-18 14:55:07.041669030 +0200
@@ -225,6 +225,12 @@ __sha512_init_ctx (ctx)
   ctx->buflen = 0;
 }
 
+static void
+be64_copy (char *dest, uint64_t x)
+{
+  for (size_t i = 8; i-- > 0; x >>= 8)
+    dest[i] = (uint8_t) x;
+}
 
 /* Process the remaining bytes in the internal buffer and the usual
    prolog according to the standard and write the result to RESBUF.
@@ -253,11 +259,9 @@ __sha512_finish_ctx (ctx, resbuf)
   memcpy (&ctx->buffer[bytes], fillbuf, pad);
 
   /* Put the 128-bit file length in *bits* at the end of the buffer.  */
-  *(uint64_t *) &ctx->buffer[bytes + pad + 8]
-    = SWAP (ctx->total[TOTAL128_low] << 3);
-  *(uint64_t *) &ctx->buffer[bytes + pad]
-    = SWAP ((ctx->total[TOTAL128_high] << 3) |
-	    (ctx->total[TOTAL128_low] >> 61));
+  be64_copy (&ctx->buffer[bytes + pad], (ctx->total[TOTAL128_high] << 3) |
+					(ctx->total[TOTAL128_low] >> 61));
+  be64_copy (&ctx->buffer[bytes + pad + 8], ctx->total[TOTAL128_low] << 3);
 
   /* Process last bytes.  */
   sha512_process_block (ctx->buffer, bytes + pad + 16, ctx);
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]