signal/x86: Include the field offsets in the build time checks
authorEric W. Biederman <ebiederm@xmission.com>
Tue, 6 Mar 2018 06:29:17 +0000 (00:29 -0600)
committerEric W. Biederman <ebiederm@xmission.com>
Tue, 6 Mar 2018 06:29:17 +0000 (00:29 -0600)
Due to an oversight when refactoring siginfo_t si_pkey has been in the
wrong position since 4.16-rc1.  Add an explicit check of the offset of
every user space field in siginfo_t and compat_siginfo_t to make a
mistake like this hard to make in the future.

I have run this code on 4.15 and 4.16-rc1 with the position of si_pkey
fixed and all of the fields show up in the same location.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
arch/x86/kernel/signal_compat.c

index ac057f9..0d930d8 100644 (file)
@@ -43,6 +43,13 @@ static inline void signal_compat_build_tests(void)
        BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields) != 3 * sizeof(int));
 #define CHECK_CSI_OFFSET(name)   BUILD_BUG_ON(_sifields_offset != offsetof(compat_siginfo_t, _sifields.name))
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_signo) != 0);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_errno) != 4);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_code)  != 8);
+
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_signo) != 0);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_errno) != 4);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_code)  != 8);
         /*
         * Ensure that the size of each si_field never changes.
         * If it does, it is a sign that the
@@ -63,36 +70,94 @@ static inline void signal_compat_build_tests(void)
        CHECK_CSI_SIZE  (_kill, 2*sizeof(int));
        CHECK_SI_SIZE   (_kill, 2*sizeof(int));
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_pid) != 0x10);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_uid) != 0x14);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid) != 0xC);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid) != 0x10);
+
        CHECK_CSI_OFFSET(_timer);
        CHECK_CSI_SIZE  (_timer, 3*sizeof(int));
        CHECK_SI_SIZE   (_timer, 6*sizeof(int));
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_tid)     != 0x10);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_overrun) != 0x14);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_value)   != 0x18);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_tid)     != 0x0C);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_overrun) != 0x10);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_value)   != 0x14);
+
        CHECK_CSI_OFFSET(_rt);
        CHECK_CSI_SIZE  (_rt, 3*sizeof(int));
        CHECK_SI_SIZE   (_rt, 4*sizeof(int));
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_pid)   != 0x10);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_uid)   != 0x14);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_value) != 0x18);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid)   != 0x0C);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid)   != 0x10);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_value) != 0x14);
+
        CHECK_CSI_OFFSET(_sigchld);
        CHECK_CSI_SIZE  (_sigchld, 5*sizeof(int));
        CHECK_SI_SIZE   (_sigchld, 8*sizeof(int));
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_pid)    != 0x10);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_uid)    != 0x14);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_status) != 0x18);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_utime)  != 0x20);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_stime)  != 0x28);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid)    != 0x0C);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid)    != 0x10);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_status) != 0x14);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_utime)  != 0x18);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_stime)  != 0x1C);
+
 #ifdef CONFIG_X86_X32_ABI
        CHECK_CSI_OFFSET(_sigchld_x32);
        CHECK_CSI_SIZE  (_sigchld_x32, 7*sizeof(int));
        /* no _sigchld_x32 in the generic siginfo_t */
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields._sigchld_x32._utime)  != 0x18);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields._sigchld_x32._stime)  != 0x20);
 #endif
 
        CHECK_CSI_OFFSET(_sigfault);
        CHECK_CSI_SIZE  (_sigfault, 4*sizeof(int));
        CHECK_SI_SIZE   (_sigfault, 8*sizeof(int));
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_addr) != 0x10);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr) != 0x0C);
+
+       BUILD_BUG_ON(offsetof(siginfo_t, si_addr_lsb) != 0x18);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr_lsb) != 0x10);
+
+       BUILD_BUG_ON(offsetof(siginfo_t, si_lower) != 0x20);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_upper) != 0x28);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_lower) != 0x14);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_upper) != 0x18);
+
+       BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x20);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pkey) != 0x14);
+
        CHECK_CSI_OFFSET(_sigpoll);
        CHECK_CSI_SIZE  (_sigpoll, 2*sizeof(int));
        CHECK_SI_SIZE   (_sigpoll, 4*sizeof(int));
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_band)   != 0x10);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_fd)     != 0x18);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_band) != 0x0C);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_fd)   != 0x10);
+
        CHECK_CSI_OFFSET(_sigsys);
        CHECK_CSI_SIZE  (_sigsys, 3*sizeof(int));
        CHECK_SI_SIZE   (_sigsys, 4*sizeof(int));
 
+       BUILD_BUG_ON(offsetof(siginfo_t, si_call_addr) != 0x10);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_syscall)   != 0x18);
+       BUILD_BUG_ON(offsetof(siginfo_t, si_arch)      != 0x1C);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_call_addr) != 0x0C);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_syscall)   != 0x10);
+       BUILD_BUG_ON(offsetof(compat_siginfo_t, si_arch)      != 0x14);
+
        /* any new si_fields should be added here */
 }