summaryrefslogtreecommitdiffstats
path: root/include/linux/compat.h
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2018-04-02 15:45:42 -0400
committerEric W. Biederman <ebiederm@xmission.com>2018-04-02 16:09:58 -0400
commit8420f71943ae96dcd78da5bd4a5c2827419d340c (patch)
tree674169df2a15ebd001533725a8b5e9d4f4d541e0 /include/linux/compat.h
parent266da65e9156d93e1126e185259a4aae68188d0e (diff)
signal: Correct the offset of si_pkey and si_lower in struct siginfo on m68k
The change moving addr_lsb into the _sigfault union failed to take into account that _sigfault._addr_bnd._lower being a pointer forced the entire union to have pointer alignment. The fix for _sigfault._addr_bnd._lower having pointer alignment failed to take into account that m68k has a pointer alignment less than the size of a pointer. So simply making the padding members pointers changed the location of later members in the structure. Fix this by directly computing the needed size of the padding members, and making the padding members char arrays of the needed size. AKA if __alignof__(void *) is 1 sizeof(short) otherwise __alignof__(void *). Which should be exactly the same rules the compiler whould have used when computing the padding. I have tested this change by adding BUILD_BUG_ONs to m68k to verify the offset of every member of struct siginfo, and with those testing that the offsets of the fields in struct siginfo is the same before I changed the generic _sigfault member and after the correction to the _sigfault member. I have also verified that the x86 with it's own BUILD_BUG_ONs to verify the offsets of the siginfo members also compiles cleanly. Cc: stable@vger.kernel.org Reported-by: Eugene Syromiatnikov <esyr@redhat.com> Fixes: 859d880cf544 ("signal: Correct the offset of si_pkey in struct siginfo") Fixes: b68a68d3dcc1 ("signal: Move addr_lsb into the _sigfault union for clarity") Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Diffstat (limited to 'include/linux/compat.h')
-rw-r--r--include/linux/compat.h6
1 files changed, 4 insertions, 2 deletions
diff --git a/include/linux/compat.h b/include/linux/compat.h
index e16d07eb08cf..d770e62632d7 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -221,6 +221,8 @@ typedef struct compat_siginfo {
221#ifdef __ARCH_SI_TRAPNO 221#ifdef __ARCH_SI_TRAPNO
222 int _trapno; /* TRAP # which caused the signal */ 222 int _trapno; /* TRAP # which caused the signal */
223#endif 223#endif
224#define __COMPAT_ADDR_BND_PKEY_PAD (__alignof__(compat_uptr_t) < sizeof(short) ? \
225 sizeof(short) : __alignof__(compat_uptr_t))
224 union { 226 union {
225 /* 227 /*
226 * used when si_code=BUS_MCEERR_AR or 228 * used when si_code=BUS_MCEERR_AR or
@@ -229,13 +231,13 @@ typedef struct compat_siginfo {
229 short int _addr_lsb; /* Valid LSB of the reported address. */ 231 short int _addr_lsb; /* Valid LSB of the reported address. */
230 /* used when si_code=SEGV_BNDERR */ 232 /* used when si_code=SEGV_BNDERR */
231 struct { 233 struct {
232 compat_uptr_t _dummy_bnd; 234 char _dummy_bnd[__COMPAT_ADDR_BND_PKEY_PAD];
233 compat_uptr_t _lower; 235 compat_uptr_t _lower;
234 compat_uptr_t _upper; 236 compat_uptr_t _upper;
235 } _addr_bnd; 237 } _addr_bnd;
236 /* used when si_code=SEGV_PKUERR */ 238 /* used when si_code=SEGV_PKUERR */
237 struct { 239 struct {
238 compat_uptr_t _dummy_pkey; 240 char _dummy_pkey[__COMPAT_ADDR_BND_PKEY_PAD];
239 u32 _pkey; 241 u32 _pkey;
240 } _addr_pkey; 242 } _addr_pkey;
241 }; 243 };