Re: [tip:x86/x32] x32: Fix alignment fail in struct compat_siginfo

From: H. Peter Anvin
Date: Wed Apr 18 2012 - 17:24:15 EST


Something like this works for you?

Note: we should promote __compat_[us]64 to a global type when we do the
cleanup work requested by Linus (change __[us]64 to explicitly aligned
types, with all users that require the old types using __compat_[us]64),
but we need the compiler warning to do that, realistically.

-hpa

diff --git a/arch/x86/include/asm/siginfo.h b/arch/x86/include/asm/siginfo.h
index fc1aa55..eb91735 100644
--- a/arch/x86/include/asm/siginfo.h
+++ b/arch/x86/include/asm/siginfo.h
@@ -1,8 +1,14 @@
#ifndef _ASM_X86_SIGINFO_H
#define _ASM_X86_SIGINFO_H

+#include <linux/types.h>
+
#ifdef __x86_64__
-# define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
+# ifdef __ILP32__
+# define __ARCH_SI_CLOCK_T __compat_s64 /* x32 */
+# else
+# define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int))
+# endif
#endif

#include <asm-generic/siginfo.h>
diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h
index 8e8c23f..89d461b 100644
--- a/arch/x86/include/asm/types.h
+++ b/arch/x86/include/asm/types.h
@@ -3,4 +3,7 @@

#include <asm-generic/types.h>

+typedef __u64 __attribute__((aligned(4))) __compat_u64;
+typedef __s64 __attribute__((aligned(4))) __compat_s64;
+
#endif /* _ASM_X86_TYPES_H */
diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h
index 0dd4e87..4ed2ed0 100644
--- a/include/asm-generic/siginfo.h
+++ b/include/asm-generic/siginfo.h
@@ -35,6 +35,10 @@ typedef union sigval {
#define __ARCH_SI_BAND_T long
#endif

+#ifndef __ARCH_SI_CLOCK_T
+#define __ARCH_SI_CLOCK_T __kernel_clock_t
+#endif
+
#ifndef HAVE_ARCH_SIGINFO_T

typedef struct siginfo {
@@ -72,8 +76,8 @@ typedef struct siginfo {
__kernel_pid_t _pid; /* which child */
__ARCH_SI_UID_T _uid; /* sender's uid */
int _status; /* exit code */
- __kernel_clock_t _utime;
- __kernel_clock_t _stime;
+ __ARCH_SI_CLOCK_T _utime;
+ __ARCH_SI_CLOCK_T _stime;
} _sigchld;

/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */