bufhelp: use 'may_alias' attribute unaligned pointer types
authorJussi Kivilinna <jussi.kivilinna@iki.fi>
Mon, 23 Jan 2017 17:48:28 +0000 (19:48 +0200)
committerJussi Kivilinna <jussi.kivilinna@iki.fi>
Mon, 23 Jan 2017 17:55:37 +0000 (19:55 +0200)
* configure.ac (gcry_cv_gcc_attribute_may_alias)
(HAVE_GCC_ATTRIBUTE_MAY_ALIAS): New check for 'may_alias' attribute.
* cipher/bufhelp.h (BUFHELP_FAST_UNALIGNED_ACCESS): Enable only if
HAVE_GCC_ATTRIBUTE_MAY_ALIAS is defined.
[BUFHELP_FAST_UNALIGNED_ACCESS] (bufhelp_int_t, bufhelp_u32_t)
(bufhelp_u64_t): Add 'may_alias' attribute.
* src/g10lib.h (fast_wipememory_t): Add HAVE_GCC_ATTRIBUTE_MAY_ALIAS
defined check; Add 'may_alias' attribute.
--

Attribute 'may_alias' was missing from bufhelp unaligned memory access
pointer types, and was causing problems with newer GCC versions (with
more aggressive optimization). This patch fixes broken Camellia-CFB
with '-O3 -flto' flags with GCC-6 on x86-64 and generic GCM with
default '-O2' on x32.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
cipher/bufhelp.h
configure.ac
src/g10lib.h

index df35594..3616515 100644 (file)
@@ -26,6 +26,7 @@
 #undef BUFHELP_FAST_UNALIGNED_ACCESS
 #if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \
     defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \
+    defined(HAVE_GCC_ATTRIBUTE_MAY_ALIAS) && \
     (defined(__i386__) || defined(__x86_64__) || \
      (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \
      defined(__aarch64__))
@@ -43,7 +44,7 @@
 typedef struct bufhelp_int_s
 {
   uintptr_t a;
-} __attribute__((packed, aligned(1))) bufhelp_int_t;
+} __attribute__((packed, aligned(1), may_alias)) bufhelp_int_t;
 #else
 /* Define type with default alignment for other architectures (unaligned
    accessed handled in per byte loops).
@@ -370,7 +371,7 @@ static inline void buf_put_le64(void *_buf, u64 val)
 typedef struct bufhelp_u32_s
 {
   u32 a;
-} __attribute__((packed, aligned(1))) bufhelp_u32_t;
+} __attribute__((packed, aligned(1), may_alias)) bufhelp_u32_t;
 
 /* Functions for loading and storing unaligned u32 values of different
    endianness.  */
@@ -400,7 +401,7 @@ static inline void buf_put_le32(void *_buf, u32 val)
 typedef struct bufhelp_u64_s
 {
   u64 a;
-} __attribute__((packed, aligned(1))) bufhelp_u64_t;
+} __attribute__((packed, aligned(1), may_alias)) bufhelp_u64_t;
 
 /* Functions for loading and storing unaligned u64 values of different
    endianness.  */
index 31c0d55..5dd27ca 100644 (file)
@@ -994,6 +994,21 @@ fi
 
 
 #
+# Check whether the compiler supports the GCC style may_alias attribute
+#
+AC_CACHE_CHECK([whether the GCC style may_alias attribute is supported],
+       [gcry_cv_gcc_attribute_may_alias],
+       [gcry_cv_gcc_attribute_may_alias=no
+        AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[struct { int a; } foo __attribute__ ((may_alias));]])],
+          [gcry_cv_gcc_attribute_may_alias=yes])])
+if test "$gcry_cv_gcc_attribute_may_alias" = "yes" ; then
+   AC_DEFINE(HAVE_GCC_ATTRIBUTE_MAY_ALIAS,1,
+     [Defined if a GCC style "__attribute__ ((may_alias))" is supported])
+fi
+
+
+#
 # Check whether the compiler supports 'asm' or '__asm__' keyword for
 # assembler blocks.
 #
index 1308cff..8ce84b8 100644 (file)
@@ -334,6 +334,7 @@ void __gcry_burn_stack (unsigned int bytes);
 /* Following architectures can handle unaligned accesses fast.  */
 #if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \
     defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \
+    defined(HAVE_GCC_ATTRIBUTE_MAY_ALIAS) && \
     (defined(__i386__) || defined(__x86_64__) || \
      defined(__powerpc__) || defined(__powerpc64__) || \
      (defined(__arm__) && defined(__ARM_FEATURE_UNALIGNED)) || \
@@ -342,7 +343,7 @@ void __gcry_burn_stack (unsigned int bytes);
 typedef struct fast_wipememory_s
 {
   FASTWIPE_T a;
-} __attribute__((packed, aligned(1))) fast_wipememory_t;
+} __attribute__((packed, aligned(1), may_alias)) fast_wipememory_t;
 #else
 #define fast_wipememory2_unaligned_head(_vptr,_vset,_vlen) do { \
               while((size_t)(_vptr)&(sizeof(FASTWIPE_T)-1) && _vlen) \