Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

signal: Remove kernel interal si_code magic

struct siginfo is a union and the kernel since 2.4 has been hiding a union
tag in the high 16bits of si_code using the values:
__SI_KILL
__SI_TIMER
__SI_POLL
__SI_FAULT
__SI_CHLD
__SI_RT
__SI_MESGQ
__SI_SYS

While this looks plausible on the surface, in practice this situation has
not worked well.

- Injected positive signals are not copied to user space properly
unless they have these magic high bits set.

- Injected positive signals are not reported properly by signalfd
unless they have these magic high bits set.

- These kernel internal values leaked to userspace via ptrace_peek_siginfo

- It was possible to inject these kernel internal values and cause the
the kernel to misbehave.

- Kernel developers got confused and expected these kernel internal values
in userspace in kernel self tests.

- Kernel developers got confused and set si_code to __SI_FAULT which
is SI_USER in userspace which causes userspace to think an ordinary user
sent the signal and that it was not kernel generated.

- The values make it impossible to reorganize the code to transform
siginfo_copy_to_user into a plain copy_to_user. As si_code must
be massaged before being passed to userspace.

So remove these kernel internal si codes and make the kernel code simpler
and more maintainable.

To replace these kernel internal magic si_codes introduce the helper
function siginfo_layout, that takes a signal number and an si_code and
computes which union member of siginfo is being used. Have
siginfo_layout return an enumeration so that gcc will have enough
information to warn if a switch statement does not handle all of union
members.

A couple of architectures have a messed up ABI that defines signal
specific duplications of SI_USER which causes more special cases in
siginfo_layout than I would like. The good news is only problem
architectures pay the cost.

Update all of the code that used the previous magic __SI_ values to
use the new SIL_ values and to call siginfo_layout to get those
values. Escept where not all of the cases are handled remove the
defaults in the switch statements so that if a new case is missed in
the future the lack will show up at compile time.

Modify the code that copies siginfo si_code to userspace to just copy
the value and not cast si_code to a short first. The high bits are no
longer used to hold a magic union member.

Fixup the siginfo header files to stop including the __SI_ values in
their constants and for the headers that were missing it to properly
update the number of si_codes for each signal type.

The fixes to copy_siginfo_from_user32 implementations has the
interesting property that several of them perviously should never have
worked as the __SI_ values they depended up where kernel internal.
With that dependency gone those implementations should work much
better.

The idea of not passing the __SI_ values out to userspace and then
not reinserting them has been tested with criu and criu worked without
changes.

Ref: 2.4.0-test1
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>

+257 -245
+2 -2
arch/alpha/include/uapi/asm/siginfo.h
··· 10 10 * SIGFPE si_codes 11 11 */ 12 12 #ifdef __KERNEL__ 13 - #define FPE_FIXME (__SI_FAULT|0) /* Broken dup of SI_USER */ 13 + #define FPE_FIXME 0 /* Broken dup of SI_USER */ 14 14 #endif /* __KERNEL__ */ 15 15 16 16 /* 17 17 * SIGTRAP si_codes 18 18 */ 19 19 #ifdef __KERNEL__ 20 - #define TRAP_FIXME (__SI_FAULT|0) /* Broken dup of SI_USER */ 20 + #define TRAP_FIXME 0 /* Broken dup of SI_USER */ 21 21 #endif /* __KERNEL__ */ 22 22 23 23 #endif
+9 -14
arch/arm64/kernel/signal32.c
··· 142 142 */ 143 143 err = __put_user(from->si_signo, &to->si_signo); 144 144 err |= __put_user(from->si_errno, &to->si_errno); 145 - err |= __put_user((short)from->si_code, &to->si_code); 145 + err |= __put_user(from->si_code, &to->si_code); 146 146 if (from->si_code < 0) 147 147 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, 148 148 SI_PAD_SIZE); 149 - else switch (from->si_code & __SI_MASK) { 150 - case __SI_KILL: 149 + else switch (siginfo_layout(from->si_signo, from->si_code)) { 150 + case SIL_KILL: 151 151 err |= __put_user(from->si_pid, &to->si_pid); 152 152 err |= __put_user(from->si_uid, &to->si_uid); 153 153 break; 154 - case __SI_TIMER: 154 + case SIL_TIMER: 155 155 err |= __put_user(from->si_tid, &to->si_tid); 156 156 err |= __put_user(from->si_overrun, &to->si_overrun); 157 157 err |= __put_user(from->si_int, &to->si_int); 158 158 break; 159 - case __SI_POLL: 159 + case SIL_POLL: 160 160 err |= __put_user(from->si_band, &to->si_band); 161 161 err |= __put_user(from->si_fd, &to->si_fd); 162 162 break; 163 - case __SI_FAULT: 163 + case SIL_FAULT: 164 164 err |= __put_user((compat_uptr_t)(unsigned long)from->si_addr, 165 165 &to->si_addr); 166 166 #ifdef BUS_MCEERR_AO ··· 173 173 err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb); 174 174 #endif 175 175 break; 176 - case __SI_CHLD: 176 + case SIL_CHLD: 177 177 err |= __put_user(from->si_pid, &to->si_pid); 178 178 err |= __put_user(from->si_uid, &to->si_uid); 179 179 err |= __put_user(from->si_status, &to->si_status); 180 180 err |= __put_user(from->si_utime, &to->si_utime); 181 181 err |= __put_user(from->si_stime, &to->si_stime); 182 182 break; 183 - case __SI_RT: /* This is not generated by the kernel as of now. */ 184 - case __SI_MESGQ: /* But this is */ 183 + case SIL_RT: 185 184 err |= __put_user(from->si_pid, &to->si_pid); 186 185 err |= __put_user(from->si_uid, &to->si_uid); 187 186 err |= __put_user(from->si_int, &to->si_int); 188 187 break; 189 - case __SI_SYS: 188 + case SIL_SYS: 190 189 err |= __put_user((compat_uptr_t)(unsigned long) 191 190 from->si_call_addr, &to->si_call_addr); 192 191 err |= __put_user(from->si_syscall, &to->si_syscall); 193 192 err |= __put_user(from->si_arch, &to->si_arch); 194 - break; 195 - default: /* this is just in case for now ... */ 196 - err |= __put_user(from->si_pid, &to->si_pid); 197 - err |= __put_user(from->si_uid, &to->si_uid); 198 193 break; 199 194 } 200 195 return err;
+19 -11
arch/blackfin/include/uapi/asm/siginfo.h
··· 14 14 15 15 #define si_uid16 _sifields._kill._uid 16 16 17 - #define ILL_ILLPARAOP (__SI_FAULT|2) /* illegal opcode combine ********** */ 18 - #define ILL_ILLEXCPT (__SI_FAULT|4) /* unrecoverable exception ********** */ 19 - #define ILL_CPLB_VI (__SI_FAULT|9) /* D/I CPLB protect violation ******** */ 20 - #define ILL_CPLB_MISS (__SI_FAULT|10) /* D/I CPLB miss ******** */ 21 - #define ILL_CPLB_MULHIT (__SI_FAULT|11) /* D/I CPLB multiple hit ******** */ 17 + #define ILL_ILLPARAOP 2 /* illegal opcode combine ********** */ 18 + #define ILL_ILLEXCPT 4 /* unrecoverable exception ********** */ 19 + #define ILL_CPLB_VI 9 /* D/I CPLB protect violation ******** */ 20 + #define ILL_CPLB_MISS 10 /* D/I CPLB miss ******** */ 21 + #define ILL_CPLB_MULHIT 11 /* D/I CPLB multiple hit ******** */ 22 + #undef NSIGILL 23 + #define NSIGILL 11 22 24 23 25 /* 24 26 * SIGBUS si_codes 25 27 */ 26 - #define BUS_OPFETCH (__SI_FAULT|4) /* error from instruction fetch ******** */ 28 + #define BUS_OPFETCH 4 /* error from instruction fetch ******** */ 29 + #undef NSIGBUS 30 + #define NSIGBUS 4 27 31 28 32 /* 29 33 * SIGTRAP si_codes 30 34 */ 31 - #define TRAP_STEP (__SI_FAULT|1) /* single-step breakpoint************* */ 32 - #define TRAP_TRACEFLOW (__SI_FAULT|2) /* trace buffer overflow ************* */ 33 - #define TRAP_WATCHPT (__SI_FAULT|3) /* watchpoint match ************* */ 34 - #define TRAP_ILLTRAP (__SI_FAULT|4) /* illegal trap ************* */ 35 + #define TRAP_STEP 1 /* single-step breakpoint************* */ 36 + #define TRAP_TRACEFLOW 2 /* trace buffer overflow ************* */ 37 + #define TRAP_WATCHPT 3 /* watchpoint match ************* */ 38 + #define TRAP_ILLTRAP 4 /* illegal trap ************* */ 39 + #undef NSIGTRAP 40 + #define NSIGTRAP 4 35 41 36 42 /* 37 43 * SIGSEGV si_codes 38 44 */ 39 - #define SEGV_STACKFLOW (__SI_FAULT|3) /* stack overflow */ 45 + #define SEGV_STACKFLOW 3 /* stack overflow */ 46 + #undef NSIGSEGV 47 + #define NSIGSEGV 3 40 48 41 49 #endif /* _UAPI_BFIN_SIGINFO_H */
+1 -1
arch/frv/include/uapi/asm/siginfo.h
··· 4 4 #include <linux/types.h> 5 5 #include <asm-generic/siginfo.h> 6 6 7 - #define FPE_MDAOVF (__SI_FAULT|9) /* media overflow */ 7 + #define FPE_MDAOVF 9 /* media overflow */ 8 8 #undef NSIGFPE 9 9 #define NSIGFPE 9 10 10
+10 -10
arch/ia64/include/uapi/asm/siginfo.h
··· 98 98 /* 99 99 * SIGILL si_codes 100 100 */ 101 - #define ILL_BADIADDR (__SI_FAULT|9) /* unimplemented instruction address */ 102 - #define __ILL_BREAK (__SI_FAULT|10) /* illegal break */ 103 - #define __ILL_BNDMOD (__SI_FAULT|11) /* bundle-update (modification) in progress */ 101 + #define ILL_BADIADDR 9 /* unimplemented instruction address */ 102 + #define __ILL_BREAK 10 /* illegal break */ 103 + #define __ILL_BNDMOD 11 /* bundle-update (modification) in progress */ 104 104 #undef NSIGILL 105 105 #define NSIGILL 11 106 106 ··· 108 108 * SIGFPE si_codes 109 109 */ 110 110 #ifdef __KERNEL__ 111 - #define FPE_FIXME (__SI_FAULT|0) /* Broken dup of SI_USER */ 111 + #define FPE_FIXME 0 /* Broken dup of SI_USER */ 112 112 #endif /* __KERNEL__ */ 113 - #define __FPE_DECOVF (__SI_FAULT|9) /* decimal overflow */ 114 - #define __FPE_DECDIV (__SI_FAULT|10) /* decimal division by zero */ 115 - #define __FPE_DECERR (__SI_FAULT|11) /* packed decimal error */ 116 - #define __FPE_INVASC (__SI_FAULT|12) /* invalid ASCII digit */ 117 - #define __FPE_INVDEC (__SI_FAULT|13) /* invalid decimal digit */ 113 + #define __FPE_DECOVF 9 /* decimal overflow */ 114 + #define __FPE_DECDIV 10 /* decimal division by zero */ 115 + #define __FPE_DECERR 11 /* packed decimal error */ 116 + #define __FPE_INVASC 12 /* invalid ASCII digit */ 117 + #define __FPE_INVDEC 13 /* invalid decimal digit */ 118 118 #undef NSIGFPE 119 119 #define NSIGFPE 13 120 120 121 121 /* 122 122 * SIGSEGV si_codes 123 123 */ 124 - #define __SEGV_PSTKOVF (__SI_FAULT|4) /* paragraph stack overflow */ 124 + #define __SEGV_PSTKOVF 4 /* paragraph stack overflow */ 125 125 #undef NSIGSEGV 126 126 #define NSIGSEGV 4 127 127
+8 -9
arch/ia64/kernel/signal.c
··· 124 124 */ 125 125 err = __put_user(from->si_signo, &to->si_signo); 126 126 err |= __put_user(from->si_errno, &to->si_errno); 127 - err |= __put_user((short)from->si_code, &to->si_code); 128 - switch (from->si_code >> 16) { 129 - case __SI_FAULT >> 16: 127 + err |= __put_user(from->si_code, &to->si_code); 128 + switch (siginfo_layout(from->si_signo, from->si_code)) { 129 + case SIL_FAULT: 130 130 err |= __put_user(from->si_flags, &to->si_flags); 131 131 err |= __put_user(from->si_isr, &to->si_isr); 132 - case __SI_POLL >> 16: 132 + case SIL_POLL: 133 133 err |= __put_user(from->si_addr, &to->si_addr); 134 134 err |= __put_user(from->si_imm, &to->si_imm); 135 135 break; 136 - case __SI_TIMER >> 16: 136 + case SIL_TIMER: 137 137 err |= __put_user(from->si_tid, &to->si_tid); 138 138 err |= __put_user(from->si_overrun, &to->si_overrun); 139 139 err |= __put_user(from->si_ptr, &to->si_ptr); 140 140 break; 141 - case __SI_RT >> 16: /* Not generated by the kernel as of now. */ 142 - case __SI_MESGQ >> 16: 141 + case SIL_RT: 143 142 err |= __put_user(from->si_uid, &to->si_uid); 144 143 err |= __put_user(from->si_pid, &to->si_pid); 145 144 err |= __put_user(from->si_ptr, &to->si_ptr); 146 145 break; 147 - case __SI_CHLD >> 16: 146 + case SIL_CHLD: 148 147 err |= __put_user(from->si_utime, &to->si_utime); 149 148 err |= __put_user(from->si_stime, &to->si_stime); 150 149 err |= __put_user(from->si_status, &to->si_status); 151 - default: 150 + case SIL_KILL: 152 151 err |= __put_user(from->si_uid, &to->si_uid); 153 152 err |= __put_user(from->si_pid, &to->si_pid); 154 153 break;
+3 -3
arch/mips/include/uapi/asm/siginfo.h
··· 120 120 #undef SI_TIMER 121 121 #undef SI_MESGQ 122 122 #define SI_ASYNCIO -2 /* sent by AIO completion */ 123 - #define SI_TIMER __SI_CODE(__SI_TIMER, -3) /* sent by timer expiration */ 124 - #define SI_MESGQ __SI_CODE(__SI_MESGQ, -4) /* sent by real time mesq state change */ 123 + #define SI_TIMER -3 /* sent by timer expiration */ 124 + #define SI_MESGQ -4 /* sent by real time mesq state change */ 125 125 126 126 /* 127 127 * SIGFPE si_codes 128 128 */ 129 129 #ifdef __KERNEL__ 130 - #define FPE_FIXME (__SI_FAULT|0) /* Broken dup of SI_USER */ 130 + #define FPE_FIXME 0 /* Broken dup of SI_USER */ 131 131 #endif /* __KERNEL__ */ 132 132 133 133 #endif /* _UAPI_ASM_SIGINFO_H */
+9 -10
arch/mips/kernel/signal32.c
··· 93 93 at the same time. */ 94 94 err = __put_user(from->si_signo, &to->si_signo); 95 95 err |= __put_user(from->si_errno, &to->si_errno); 96 - err |= __put_user((short)from->si_code, &to->si_code); 96 + err |= __put_user(from->si_code, &to->si_code); 97 97 if (from->si_code < 0) 98 98 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); 99 99 else { 100 - switch (from->si_code >> 16) { 101 - case __SI_TIMER >> 16: 100 + switch (siginfo_layout(from->si_signo, from->si_code)) { 101 + case SIL_TIMER: 102 102 err |= __put_user(from->si_tid, &to->si_tid); 103 103 err |= __put_user(from->si_overrun, &to->si_overrun); 104 104 err |= __put_user(from->si_int, &to->si_int); 105 105 break; 106 - case __SI_CHLD >> 16: 106 + case SIL_CHLD: 107 107 err |= __put_user(from->si_utime, &to->si_utime); 108 108 err |= __put_user(from->si_stime, &to->si_stime); 109 109 err |= __put_user(from->si_status, &to->si_status); 110 - default: 110 + case SIL_KILL: 111 111 err |= __put_user(from->si_pid, &to->si_pid); 112 112 err |= __put_user(from->si_uid, &to->si_uid); 113 113 break; 114 - case __SI_FAULT >> 16: 114 + case SIL_FAULT: 115 115 err |= __put_user((unsigned long)from->si_addr, &to->si_addr); 116 116 break; 117 - case __SI_POLL >> 16: 117 + case SIL_POLL: 118 118 err |= __put_user(from->si_band, &to->si_band); 119 119 err |= __put_user(from->si_fd, &to->si_fd); 120 120 break; 121 - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ 122 - case __SI_MESGQ >> 16: 121 + case SIL_RT: 123 122 err |= __put_user(from->si_pid, &to->si_pid); 124 123 err |= __put_user(from->si_uid, &to->si_uid); 125 124 err |= __put_user(from->si_int, &to->si_int); 126 125 break; 127 - case __SI_SYS >> 16: 126 + case SIL_SYS: 128 127 err |= __copy_to_user(&to->si_call_addr, &from->si_call_addr, 129 128 sizeof(compat_uptr_t)); 130 129 err |= __put_user(from->si_syscall, &to->si_syscall);
+15 -16
arch/parisc/kernel/signal32.c
··· 290 290 if (to->si_code < 0) 291 291 err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); 292 292 else { 293 - switch (to->si_code >> 16) { 294 - case __SI_CHLD >> 16: 293 + switch (siginfo_layout(to->si_signo, to->si_code)) { 294 + case SIL_CHLD: 295 295 err |= __get_user(to->si_utime, &from->si_utime); 296 296 err |= __get_user(to->si_stime, &from->si_stime); 297 297 err |= __get_user(to->si_status, &from->si_status); 298 298 default: 299 + case SIL_KILL: 299 300 err |= __get_user(to->si_pid, &from->si_pid); 300 301 err |= __get_user(to->si_uid, &from->si_uid); 301 302 break; 302 - case __SI_FAULT >> 16: 303 + case SIL_FAULT: 303 304 err |= __get_user(addr, &from->si_addr); 304 305 to->si_addr = compat_ptr(addr); 305 306 break; 306 - case __SI_POLL >> 16: 307 + case SIL_POLL: 307 308 err |= __get_user(to->si_band, &from->si_band); 308 309 err |= __get_user(to->si_fd, &from->si_fd); 309 310 break; 310 - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ 311 - case __SI_MESGQ >> 16: 311 + case SIL_RT: 312 312 err |= __get_user(to->si_pid, &from->si_pid); 313 313 err |= __get_user(to->si_uid, &from->si_uid); 314 314 err |= __get_user(to->si_int, &from->si_int); ··· 337 337 at the same time. */ 338 338 err = __put_user(from->si_signo, &to->si_signo); 339 339 err |= __put_user(from->si_errno, &to->si_errno); 340 - err |= __put_user((short)from->si_code, &to->si_code); 340 + err |= __put_user(from->si_code, &to->si_code); 341 341 if (from->si_code < 0) 342 342 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); 343 343 else { 344 - switch (from->si_code >> 16) { 345 - case __SI_CHLD >> 16: 344 + switch (siginfo_layout(from->si_signo, from->si_code)) { 345 + case SIL_CHLD: 346 346 err |= __put_user(from->si_utime, &to->si_utime); 347 347 err |= __put_user(from->si_stime, &to->si_stime); 348 348 err |= __put_user(from->si_status, &to->si_status); 349 - default: 349 + case SIL_KILL: 350 350 err |= __put_user(from->si_pid, &to->si_pid); 351 351 err |= __put_user(from->si_uid, &to->si_uid); 352 352 break; 353 - case __SI_FAULT >> 16: 353 + case SIL_FAULT: 354 354 addr = ptr_to_compat(from->si_addr); 355 355 err |= __put_user(addr, &to->si_addr); 356 356 break; 357 - case __SI_POLL >> 16: 357 + case SIL_POLL: 358 358 err |= __put_user(from->si_band, &to->si_band); 359 359 err |= __put_user(from->si_fd, &to->si_fd); 360 360 break; 361 - case __SI_TIMER >> 16: 361 + case SIL_TIMER: 362 362 err |= __put_user(from->si_tid, &to->si_tid); 363 363 err |= __put_user(from->si_overrun, &to->si_overrun); 364 364 val = (compat_int_t)from->si_int; 365 365 err |= __put_user(val, &to->si_int); 366 366 break; 367 - case __SI_RT >> 16: /* Not generated by the kernel as of now. */ 368 - case __SI_MESGQ >> 16: 367 + case SIL_RT: 369 368 err |= __put_user(from->si_uid, &to->si_uid); 370 369 err |= __put_user(from->si_pid, &to->si_pid); 371 370 val = (compat_int_t)from->si_int; 372 371 err |= __put_user(val, &to->si_int); 373 372 break; 374 - case __SI_SYS >> 16: 373 + case SIL_SYS: 375 374 err |= __put_user(ptr_to_compat(from->si_call_addr), &to->si_call_addr); 376 375 err |= __put_user(from->si_syscall, &to->si_syscall); 377 376 err |= __put_user(from->si_arch, &to->si_arch);
+9 -11
arch/powerpc/kernel/signal_32.c
··· 913 913 */ 914 914 err = __put_user(s->si_signo, &d->si_signo); 915 915 err |= __put_user(s->si_errno, &d->si_errno); 916 - err |= __put_user((short)s->si_code, &d->si_code); 916 + err |= __put_user(s->si_code, &d->si_code); 917 917 if (s->si_code < 0) 918 918 err |= __copy_to_user(&d->_sifields._pad, &s->_sifields._pad, 919 919 SI_PAD_SIZE32); 920 - else switch(s->si_code >> 16) { 921 - case __SI_CHLD >> 16: 920 + else switch(siginfo_layout(s->si_signo, s->si_code)) { 921 + case SIL_CHLD: 922 922 err |= __put_user(s->si_pid, &d->si_pid); 923 923 err |= __put_user(s->si_uid, &d->si_uid); 924 924 err |= __put_user(s->si_utime, &d->si_utime); 925 925 err |= __put_user(s->si_stime, &d->si_stime); 926 926 err |= __put_user(s->si_status, &d->si_status); 927 927 break; 928 - case __SI_FAULT >> 16: 928 + case SIL_FAULT: 929 929 err |= __put_user((unsigned int)(unsigned long)s->si_addr, 930 930 &d->si_addr); 931 931 break; 932 - case __SI_POLL >> 16: 932 + case SIL_POLL: 933 933 err |= __put_user(s->si_band, &d->si_band); 934 934 err |= __put_user(s->si_fd, &d->si_fd); 935 935 break; 936 - case __SI_TIMER >> 16: 936 + case SIL_TIMER: 937 937 err |= __put_user(s->si_tid, &d->si_tid); 938 938 err |= __put_user(s->si_overrun, &d->si_overrun); 939 939 err |= __put_user(s->si_int, &d->si_int); 940 940 break; 941 - case __SI_SYS >> 16: 941 + case SIL_SYS: 942 942 err |= __put_user(ptr_to_compat(s->si_call_addr), &d->si_call_addr); 943 943 err |= __put_user(s->si_syscall, &d->si_syscall); 944 944 err |= __put_user(s->si_arch, &d->si_arch); 945 945 break; 946 - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ 947 - case __SI_MESGQ >> 16: 946 + case SIL_RT: 948 947 err |= __put_user(s->si_int, &d->si_int); 949 948 /* fallthrough */ 950 - case __SI_KILL >> 16: 951 - default: 949 + case SIL_KILL: 952 950 err |= __put_user(s->si_pid, &d->si_pid); 953 951 err |= __put_user(s->si_uid, &d->si_uid); 954 952 break;
+15 -17
arch/s390/kernel/compat_signal.c
··· 75 75 at the same time. */ 76 76 err = __put_user(from->si_signo, &to->si_signo); 77 77 err |= __put_user(from->si_errno, &to->si_errno); 78 - err |= __put_user((short)from->si_code, &to->si_code); 78 + err |= __put_user(from->si_code, &to->si_code); 79 79 if (from->si_code < 0) 80 80 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); 81 81 else { 82 - switch (from->si_code >> 16) { 83 - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ 84 - case __SI_MESGQ >> 16: 82 + switch (siginfo_layout(from->si_signo, from->si_code)) { 83 + case SIL_RT: 85 84 err |= __put_user(from->si_int, &to->si_int); 86 85 /* fallthrough */ 87 - case __SI_KILL >> 16: 86 + case SIL_KILL: 88 87 err |= __put_user(from->si_pid, &to->si_pid); 89 88 err |= __put_user(from->si_uid, &to->si_uid); 90 89 break; 91 - case __SI_CHLD >> 16: 90 + case SIL_CHLD: 92 91 err |= __put_user(from->si_pid, &to->si_pid); 93 92 err |= __put_user(from->si_uid, &to->si_uid); 94 93 err |= __put_user(from->si_utime, &to->si_utime); 95 94 err |= __put_user(from->si_stime, &to->si_stime); 96 95 err |= __put_user(from->si_status, &to->si_status); 97 96 break; 98 - case __SI_FAULT >> 16: 97 + case SIL_FAULT: 99 98 err |= __put_user((unsigned long) from->si_addr, 100 99 &to->si_addr); 101 100 break; 102 - case __SI_POLL >> 16: 101 + case SIL_POLL: 103 102 err |= __put_user(from->si_band, &to->si_band); 104 103 err |= __put_user(from->si_fd, &to->si_fd); 105 104 break; 106 - case __SI_TIMER >> 16: 105 + case SIL_TIMER: 107 106 err |= __put_user(from->si_tid, &to->si_tid); 108 107 err |= __put_user(from->si_overrun, &to->si_overrun); 109 108 err |= __put_user(from->si_int, &to->si_int); ··· 126 127 if (to->si_code < 0) 127 128 err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); 128 129 else { 129 - switch (to->si_code >> 16) { 130 - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ 131 - case __SI_MESGQ >> 16: 130 + switch (siginfo_layout(to->si_signo, to->si_code)) { 131 + case SIL_RT: 132 132 err |= __get_user(to->si_int, &from->si_int); 133 133 /* fallthrough */ 134 - case __SI_KILL >> 16: 134 + case SIL_KILL: 135 135 err |= __get_user(to->si_pid, &from->si_pid); 136 136 err |= __get_user(to->si_uid, &from->si_uid); 137 137 break; 138 - case __SI_CHLD >> 16: 138 + case SIL_CHLD: 139 139 err |= __get_user(to->si_pid, &from->si_pid); 140 140 err |= __get_user(to->si_uid, &from->si_uid); 141 141 err |= __get_user(to->si_utime, &from->si_utime); 142 142 err |= __get_user(to->si_stime, &from->si_stime); 143 143 err |= __get_user(to->si_status, &from->si_status); 144 144 break; 145 - case __SI_FAULT >> 16: 145 + case SIL_FAULT: 146 146 err |= __get_user(tmp, &from->si_addr); 147 147 to->si_addr = (void __force __user *) 148 148 (u64) (tmp & PSW32_ADDR_INSN); 149 149 break; 150 - case __SI_POLL >> 16: 150 + case SIL_POLL: 151 151 err |= __get_user(to->si_band, &from->si_band); 152 152 err |= __get_user(to->si_fd, &from->si_fd); 153 153 break; 154 - case __SI_TIMER >> 16: 154 + case SIL_TIMER: 155 155 err |= __get_user(to->si_tid, &from->si_tid); 156 156 err |= __get_user(to->si_overrun, &from->si_overrun); 157 157 err |= __get_user(to->si_int, &from->si_int);
+2 -2
arch/sparc/include/uapi/asm/siginfo.h
··· 20 20 * SIGFPE si_codes 21 21 */ 22 22 #ifdef __KERNEL__ 23 - #define FPE_FIXME (__SI_FAULT|0) /* Broken dup of SI_USER */ 23 + #define FPE_FIXME 0 /* Broken dup of SI_USER */ 24 24 #endif /* __KERNEL__ */ 25 25 26 26 /* 27 27 * SIGEMT si_codes 28 28 */ 29 - #define EMT_TAGOVF (__SI_FAULT|1) /* tag overflow */ 29 + #define EMT_TAGOVF 1 /* tag overflow */ 30 30 #define NSIGEMT 1 31 31 32 32 #endif /* _UAPI__SPARC_SIGINFO_H */
+8 -8
arch/sparc/kernel/signal32.c
··· 85 85 at the same time. */ 86 86 err = __put_user(from->si_signo, &to->si_signo); 87 87 err |= __put_user(from->si_errno, &to->si_errno); 88 - err |= __put_user((short)from->si_code, &to->si_code); 88 + err |= __put_user(from->si_code, &to->si_code); 89 89 if (from->si_code < 0) 90 90 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); 91 91 else { 92 - switch (from->si_code >> 16) { 93 - case __SI_TIMER >> 16: 92 + switch (siginfo_layout(from->si_signo, from->si_code)) { 93 + case SIL_TIMER: 94 94 err |= __put_user(from->si_tid, &to->si_tid); 95 95 err |= __put_user(from->si_overrun, &to->si_overrun); 96 96 err |= __put_user(from->si_int, &to->si_int); 97 97 break; 98 - case __SI_CHLD >> 16: 98 + case SIL_CHLD: 99 99 err |= __put_user(from->si_utime, &to->si_utime); 100 100 err |= __put_user(from->si_stime, &to->si_stime); 101 101 err |= __put_user(from->si_status, &to->si_status); 102 102 default: 103 + case SIL_KILL: 103 104 err |= __put_user(from->si_pid, &to->si_pid); 104 105 err |= __put_user(from->si_uid, &to->si_uid); 105 106 break; 106 - case __SI_FAULT >> 16: 107 + case SIL_FAULT: 107 108 err |= __put_user(from->si_trapno, &to->si_trapno); 108 109 err |= __put_user((unsigned long)from->si_addr, &to->si_addr); 109 110 break; 110 - case __SI_POLL >> 16: 111 + case SIL_POLL: 111 112 err |= __put_user(from->si_band, &to->si_band); 112 113 err |= __put_user(from->si_fd, &to->si_fd); 113 114 break; 114 - case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ 115 - case __SI_MESGQ >> 16: 115 + case SIL_RT: 116 116 err |= __put_user(from->si_pid, &to->si_pid); 117 117 err |= __put_user(from->si_uid, &to->si_uid); 118 118 err |= __put_user(from->si_int, &to->si_int);
+2 -2
arch/tile/include/uapi/asm/siginfo.h
··· 26 26 /* 27 27 * Additional Tile-specific SIGILL si_codes 28 28 */ 29 - #define ILL_DBLFLT (__SI_FAULT|9) /* double fault */ 30 - #define ILL_HARDWALL (__SI_FAULT|10) /* user networks hardwall violation */ 29 + #define ILL_DBLFLT 9 /* double fault */ 30 + #define ILL_HARDWALL 10 /* user networks hardwall violation */ 31 31 #undef NSIGILL 32 32 #define NSIGILL 10 33 33
+8 -10
arch/tile/kernel/compat_signal.c
··· 64 64 3 ints plus the relevant union member. */ 65 65 err = __put_user(from->si_signo, &to->si_signo); 66 66 err |= __put_user(from->si_errno, &to->si_errno); 67 - err |= __put_user((short)from->si_code, &to->si_code); 67 + err |= __put_user(from->si_code, &to->si_code); 68 68 69 69 if (from->si_code < 0) { 70 70 err |= __put_user(from->si_pid, &to->si_pid); ··· 77 77 */ 78 78 err |= __put_user(from->_sifields._pad[0], 79 79 &to->_sifields._pad[0]); 80 - switch (from->si_code >> 16) { 81 - case __SI_FAULT >> 16: 80 + switch (siginfo_layout(from->si_signo, from->si_code)) { 81 + case SIL_FAULT: 82 82 break; 83 - case __SI_CHLD >> 16: 83 + case SIL_CHLD: 84 84 err |= __put_user(from->si_utime, &to->si_utime); 85 85 err |= __put_user(from->si_stime, &to->si_stime); 86 86 err |= __put_user(from->si_status, &to->si_status); 87 87 /* FALL THROUGH */ 88 88 default: 89 - case __SI_KILL >> 16: 89 + case SIL_KILL: 90 90 err |= __put_user(from->si_uid, &to->si_uid); 91 91 break; 92 - case __SI_POLL >> 16: 92 + case SIL_POLL: 93 93 err |= __put_user(from->si_fd, &to->si_fd); 94 94 break; 95 - case __SI_TIMER >> 16: 95 + case SIL_TIMER: 96 96 err |= __put_user(from->si_overrun, &to->si_overrun); 97 97 err |= __put_user(from->si_int, &to->si_int); 98 98 break; 99 - /* This is not generated by the kernel as of now. */ 100 - case __SI_RT >> 16: 101 - case __SI_MESGQ >> 16: 99 + case SIL_RT: 102 100 err |= __put_user(from->si_uid, &to->si_uid); 103 101 err |= __put_user(from->si_int, &to->si_int); 104 102 break;
+1 -1
arch/tile/kernel/traps.c
··· 188 188 189 189 /* Make it the requested signal. */ 190 190 *sigp = sig; 191 - *codep = code | __SI_FAULT; 191 + *codep = code; 192 192 return 1; 193 193 } 194 194
+9 -12
arch/x86/kernel/signal_compat.c
··· 129 129 3 ints plus the relevant union member. */ 130 130 put_user_ex(from->si_signo, &to->si_signo); 131 131 put_user_ex(from->si_errno, &to->si_errno); 132 - put_user_ex((short)from->si_code, &to->si_code); 132 + put_user_ex(from->si_code, &to->si_code); 133 133 134 134 if (from->si_code < 0) { 135 135 put_user_ex(from->si_pid, &to->si_pid); ··· 142 142 */ 143 143 put_user_ex(from->_sifields._pad[0], 144 144 &to->_sifields._pad[0]); 145 - switch (from->si_code >> 16) { 146 - case __SI_FAULT >> 16: 145 + switch (siginfo_layout(from->si_signo, from->si_code)) { 146 + case SIL_FAULT: 147 147 if (from->si_signo == SIGBUS && 148 148 (from->si_code == BUS_MCEERR_AR || 149 149 from->si_code == BUS_MCEERR_AO)) ··· 160 160 put_user_ex(from->si_pkey, &to->si_pkey); 161 161 } 162 162 break; 163 - case __SI_SYS >> 16: 163 + case SIL_SYS: 164 164 put_user_ex(from->si_syscall, &to->si_syscall); 165 165 put_user_ex(from->si_arch, &to->si_arch); 166 166 break; 167 - case __SI_CHLD >> 16: 167 + case SIL_CHLD: 168 168 if (!x32_ABI) { 169 169 put_user_ex(from->si_utime, &to->si_utime); 170 170 put_user_ex(from->si_stime, &to->si_stime); ··· 174 174 } 175 175 put_user_ex(from->si_status, &to->si_status); 176 176 /* FALL THROUGH */ 177 - default: 178 - case __SI_KILL >> 16: 177 + case SIL_KILL: 179 178 put_user_ex(from->si_uid, &to->si_uid); 180 179 break; 181 - case __SI_POLL >> 16: 180 + case SIL_POLL: 182 181 put_user_ex(from->si_fd, &to->si_fd); 183 182 break; 184 - case __SI_TIMER >> 16: 183 + case SIL_TIMER: 185 184 put_user_ex(from->si_overrun, &to->si_overrun); 186 185 put_user_ex(ptr_to_compat(from->si_ptr), 187 186 &to->si_ptr); 188 187 break; 189 - /* This is not generated by the kernel as of now. */ 190 - case __SI_RT >> 16: 191 - case __SI_MESGQ >> 16: 188 + case SIL_RT: 192 189 put_user_ex(from->si_uid, &to->si_uid); 193 190 put_user_ex(from->si_int, &to->si_int); 194 191 break;
+8 -14
fs/signalfd.c
··· 95 95 */ 96 96 err |= __put_user(kinfo->si_signo, &uinfo->ssi_signo); 97 97 err |= __put_user(kinfo->si_errno, &uinfo->ssi_errno); 98 - err |= __put_user((short) kinfo->si_code, &uinfo->ssi_code); 99 - switch (kinfo->si_code & __SI_MASK) { 100 - case __SI_KILL: 98 + err |= __put_user(kinfo->si_code, &uinfo->ssi_code); 99 + switch (siginfo_layout(kinfo->si_signo, kinfo->si_code)) { 100 + case SIL_KILL: 101 101 err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid); 102 102 err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid); 103 103 break; 104 - case __SI_TIMER: 104 + case SIL_TIMER: 105 105 err |= __put_user(kinfo->si_tid, &uinfo->ssi_tid); 106 106 err |= __put_user(kinfo->si_overrun, &uinfo->ssi_overrun); 107 107 err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr); 108 108 err |= __put_user(kinfo->si_int, &uinfo->ssi_int); 109 109 break; 110 - case __SI_POLL: 110 + case SIL_POLL: 111 111 err |= __put_user(kinfo->si_band, &uinfo->ssi_band); 112 112 err |= __put_user(kinfo->si_fd, &uinfo->ssi_fd); 113 113 break; 114 - case __SI_FAULT: 114 + case SIL_FAULT: 115 115 err |= __put_user((long) kinfo->si_addr, &uinfo->ssi_addr); 116 116 #ifdef __ARCH_SI_TRAPNO 117 117 err |= __put_user(kinfo->si_trapno, &uinfo->ssi_trapno); ··· 128 128 &uinfo->ssi_addr_lsb); 129 129 #endif 130 130 break; 131 - case __SI_CHLD: 131 + case SIL_CHLD: 132 132 err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid); 133 133 err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid); 134 134 err |= __put_user(kinfo->si_status, &uinfo->ssi_status); 135 135 err |= __put_user(kinfo->si_utime, &uinfo->ssi_utime); 136 136 err |= __put_user(kinfo->si_stime, &uinfo->ssi_stime); 137 137 break; 138 - case __SI_RT: /* This is not generated by the kernel as of now. */ 139 - case __SI_MESGQ: /* But this is */ 140 - err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid); 141 - err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid); 142 - err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr); 143 - err |= __put_user(kinfo->si_int, &uinfo->ssi_int); 144 - break; 138 + case SIL_RT: 145 139 default: 146 140 /* 147 141 * This case catches also the signals queued by sigqueue().
+14
include/linux/signal.h
··· 21 21 22 22 int copy_siginfo_to_user(struct siginfo __user *to, const struct siginfo *from); 23 23 24 + enum siginfo_layout { 25 + SIL_KILL, 26 + SIL_TIMER, 27 + SIL_POLL, 28 + SIL_FAULT, 29 + SIL_CHLD, 30 + SIL_RT, 31 + #ifdef __ARCH_SIGSYS 32 + SIL_SYS, 33 + #endif 34 + }; 35 + 36 + enum siginfo_layout siginfo_layout(int sig, int si_code); 37 + 24 38 /* 25 39 * Define some primitives to manipulate sigset_t. 26 40 */
+46 -69
include/uapi/asm-generic/siginfo.h
··· 151 151 #define si_arch _sifields._sigsys._arch 152 152 #endif 153 153 154 - #ifdef __KERNEL__ 155 - #define __SI_MASK 0xffff0000u 156 - #define __SI_KILL (0 << 16) 157 - #define __SI_TIMER (1 << 16) 158 - #define __SI_POLL (2 << 16) 159 - #define __SI_FAULT (3 << 16) 160 - #define __SI_CHLD (4 << 16) 161 - #define __SI_RT (5 << 16) 162 - #define __SI_MESGQ (6 << 16) 163 - #define __SI_SYS (7 << 16) 164 - #define __SI_CODE(T,N) ((T) | ((N) & 0xffff)) 165 - #else /* __KERNEL__ */ 166 - #define __SI_KILL 0 167 - #define __SI_TIMER 0 168 - #define __SI_POLL 0 169 - #define __SI_FAULT 0 170 - #define __SI_CHLD 0 171 - #define __SI_RT 0 172 - #define __SI_MESGQ 0 173 - #define __SI_SYS 0 174 - #define __SI_CODE(T,N) (N) 175 - #endif /* __KERNEL__ */ 176 - 177 154 /* 178 155 * si_code values 179 156 * Digital reserves positive values for kernel-generated signals. ··· 158 181 #define SI_USER 0 /* sent by kill, sigsend, raise */ 159 182 #define SI_KERNEL 0x80 /* sent by the kernel from somewhere */ 160 183 #define SI_QUEUE -1 /* sent by sigqueue */ 161 - #define SI_TIMER __SI_CODE(__SI_TIMER,-2) /* sent by timer expiration */ 162 - #define SI_MESGQ __SI_CODE(__SI_MESGQ,-3) /* sent by real time mesq state change */ 184 + #define SI_TIMER -2 /* sent by timer expiration */ 185 + #define SI_MESGQ -3 /* sent by real time mesq state change */ 163 186 #define SI_ASYNCIO -4 /* sent by AIO completion */ 164 - #define SI_SIGIO __SI_CODE(__SI_POLL,-5) /* sent by queued SIGIO */ 187 + #define SI_SIGIO -5 /* sent by queued SIGIO */ 165 188 #define SI_TKILL -6 /* sent by tkill system call */ 166 189 #define SI_DETHREAD -7 /* sent by execve() killing subsidiary threads */ 167 190 ··· 171 194 /* 172 195 * SIGILL si_codes 173 196 */ 174 - #define ILL_ILLOPC (__SI_FAULT|1) /* illegal opcode */ 175 - #define ILL_ILLOPN (__SI_FAULT|2) /* illegal operand */ 176 - #define ILL_ILLADR (__SI_FAULT|3) /* illegal addressing mode */ 177 - #define ILL_ILLTRP (__SI_FAULT|4) /* illegal trap */ 178 - #define ILL_PRVOPC (__SI_FAULT|5) /* privileged opcode */ 179 - #define ILL_PRVREG (__SI_FAULT|6) /* privileged register */ 180 - #define ILL_COPROC (__SI_FAULT|7) /* coprocessor error */ 181 - #define ILL_BADSTK (__SI_FAULT|8) /* internal stack error */ 197 + #define ILL_ILLOPC 1 /* illegal opcode */ 198 + #define ILL_ILLOPN 2 /* illegal operand */ 199 + #define ILL_ILLADR 3 /* illegal addressing mode */ 200 + #define ILL_ILLTRP 4 /* illegal trap */ 201 + #define ILL_PRVOPC 5 /* privileged opcode */ 202 + #define ILL_PRVREG 6 /* privileged register */ 203 + #define ILL_COPROC 7 /* coprocessor error */ 204 + #define ILL_BADSTK 8 /* internal stack error */ 182 205 #define NSIGILL 8 183 206 184 207 /* 185 208 * SIGFPE si_codes 186 209 */ 187 - #define FPE_INTDIV (__SI_FAULT|1) /* integer divide by zero */ 188 - #define FPE_INTOVF (__SI_FAULT|2) /* integer overflow */ 189 - #define FPE_FLTDIV (__SI_FAULT|3) /* floating point divide by zero */ 190 - #define FPE_FLTOVF (__SI_FAULT|4) /* floating point overflow */ 191 - #define FPE_FLTUND (__SI_FAULT|5) /* floating point underflow */ 192 - #define FPE_FLTRES (__SI_FAULT|6) /* floating point inexact result */ 193 - #define FPE_FLTINV (__SI_FAULT|7) /* floating point invalid operation */ 194 - #define FPE_FLTSUB (__SI_FAULT|8) /* subscript out of range */ 210 + #define FPE_INTDIV 1 /* integer divide by zero */ 211 + #define FPE_INTOVF 2 /* integer overflow */ 212 + #define FPE_FLTDIV 3 /* floating point divide by zero */ 213 + #define FPE_FLTOVF 4 /* floating point overflow */ 214 + #define FPE_FLTUND 5 /* floating point underflow */ 215 + #define FPE_FLTRES 6 /* floating point inexact result */ 216 + #define FPE_FLTINV 7 /* floating point invalid operation */ 217 + #define FPE_FLTSUB 8 /* subscript out of range */ 195 218 #define NSIGFPE 8 196 219 197 220 /* 198 221 * SIGSEGV si_codes 199 222 */ 200 - #define SEGV_MAPERR (__SI_FAULT|1) /* address not mapped to object */ 201 - #define SEGV_ACCERR (__SI_FAULT|2) /* invalid permissions for mapped object */ 202 - #define SEGV_BNDERR (__SI_FAULT|3) /* failed address bound checks */ 203 - #define SEGV_PKUERR (__SI_FAULT|4) /* failed protection key checks */ 223 + #define SEGV_MAPERR 1 /* address not mapped to object */ 224 + #define SEGV_ACCERR 2 /* invalid permissions for mapped object */ 225 + #define SEGV_BNDERR 3 /* failed address bound checks */ 226 + #define SEGV_PKUERR 4 /* failed protection key checks */ 204 227 #define NSIGSEGV 4 205 228 206 229 /* 207 230 * SIGBUS si_codes 208 231 */ 209 - #define BUS_ADRALN (__SI_FAULT|1) /* invalid address alignment */ 210 - #define BUS_ADRERR (__SI_FAULT|2) /* non-existent physical address */ 211 - #define BUS_OBJERR (__SI_FAULT|3) /* object specific hardware error */ 232 + #define BUS_ADRALN 1 /* invalid address alignment */ 233 + #define BUS_ADRERR 2 /* non-existent physical address */ 234 + #define BUS_OBJERR 3 /* object specific hardware error */ 212 235 /* hardware memory error consumed on a machine check: action required */ 213 - #define BUS_MCEERR_AR (__SI_FAULT|4) 236 + #define BUS_MCEERR_AR 4 214 237 /* hardware memory error detected in process but not consumed: action optional*/ 215 - #define BUS_MCEERR_AO (__SI_FAULT|5) 238 + #define BUS_MCEERR_AO 5 216 239 #define NSIGBUS 5 217 240 218 241 /* 219 242 * SIGTRAP si_codes 220 243 */ 221 - #define TRAP_BRKPT (__SI_FAULT|1) /* process breakpoint */ 222 - #define TRAP_TRACE (__SI_FAULT|2) /* process trace trap */ 223 - #define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */ 224 - #define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint/watchpoint */ 244 + #define TRAP_BRKPT 1 /* process breakpoint */ 245 + #define TRAP_TRACE 2 /* process trace trap */ 246 + #define TRAP_BRANCH 3 /* process taken branch trap */ 247 + #define TRAP_HWBKPT 4 /* hardware breakpoint/watchpoint */ 225 248 #define NSIGTRAP 4 226 249 227 250 /* 228 251 * SIGCHLD si_codes 229 252 */ 230 - #define CLD_EXITED (__SI_CHLD|1) /* child has exited */ 231 - #define CLD_KILLED (__SI_CHLD|2) /* child was killed */ 232 - #define CLD_DUMPED (__SI_CHLD|3) /* child terminated abnormally */ 233 - #define CLD_TRAPPED (__SI_CHLD|4) /* traced child has trapped */ 234 - #define CLD_STOPPED (__SI_CHLD|5) /* child has stopped */ 235 - #define CLD_CONTINUED (__SI_CHLD|6) /* stopped child has continued */ 253 + #define CLD_EXITED 1 /* child has exited */ 254 + #define CLD_KILLED 2 /* child was killed */ 255 + #define CLD_DUMPED 3 /* child terminated abnormally */ 256 + #define CLD_TRAPPED 4 /* traced child has trapped */ 257 + #define CLD_STOPPED 5 /* child has stopped */ 258 + #define CLD_CONTINUED 6 /* stopped child has continued */ 236 259 #define NSIGCHLD 6 237 260 238 261 /* 239 262 * SIGPOLL (or any other signal without signal specific si_codes) si_codes 240 263 */ 241 - #define POLL_IN (__SI_POLL|1) /* data input available */ 242 - #define POLL_OUT (__SI_POLL|2) /* output buffers available */ 243 - #define POLL_MSG (__SI_POLL|3) /* input message available */ 244 - #define POLL_ERR (__SI_POLL|4) /* i/o error */ 245 - #define POLL_PRI (__SI_POLL|5) /* high priority input available */ 246 - #define POLL_HUP (__SI_POLL|6) /* device disconnected */ 264 + #define POLL_IN 1 /* data input available */ 265 + #define POLL_OUT 2 /* output buffers available */ 266 + #define POLL_MSG 3 /* input message available */ 267 + #define POLL_ERR 4 /* i/o error */ 268 + #define POLL_PRI 5 /* high priority input available */ 269 + #define POLL_HUP 6 /* device disconnected */ 247 270 #define NSIGPOLL 6 248 271 249 272 /* 250 273 * SIGSYS si_codes 251 274 */ 252 - #define SYS_SECCOMP (__SI_SYS|1) /* seccomp triggered */ 253 - #define NSIGSYS 1 275 + #define SYS_SECCOMP 1 /* seccomp triggered */ 276 + #define NSIGSYS 1 254 277 255 278 /* 256 279 * sigevent definitions
+2 -2
kernel/exit.c
··· 1616 1616 user_access_begin(); 1617 1617 unsafe_put_user(signo, &infop->si_signo, Efault); 1618 1618 unsafe_put_user(0, &infop->si_errno, Efault); 1619 - unsafe_put_user((short)info.cause, &infop->si_code, Efault); 1619 + unsafe_put_user(info.cause, &infop->si_code, Efault); 1620 1620 unsafe_put_user(info.pid, &infop->si_pid, Efault); 1621 1621 unsafe_put_user(info.uid, &infop->si_uid, Efault); 1622 1622 unsafe_put_user(info.status, &infop->si_status, Efault); ··· 1742 1742 user_access_begin(); 1743 1743 unsafe_put_user(signo, &infop->si_signo, Efault); 1744 1744 unsafe_put_user(0, &infop->si_errno, Efault); 1745 - unsafe_put_user((short)info.cause, &infop->si_code, Efault); 1745 + unsafe_put_user(info.cause, &infop->si_code, Efault); 1746 1746 unsafe_put_user(info.pid, &infop->si_pid, Efault); 1747 1747 unsafe_put_user(info.uid, &infop->si_uid, Efault); 1748 1748 unsafe_put_user(info.status, &infop->si_status, Efault);
+2 -4
kernel/ptrace.c
··· 728 728 if (unlikely(in_compat_syscall())) { 729 729 compat_siginfo_t __user *uinfo = compat_ptr(data); 730 730 731 - if (copy_siginfo_to_user32(uinfo, &info) || 732 - __put_user(info.si_code, &uinfo->si_code)) { 731 + if (copy_siginfo_to_user32(uinfo, &info)) { 733 732 ret = -EFAULT; 734 733 break; 735 734 } ··· 738 739 { 739 740 siginfo_t __user *uinfo = (siginfo_t __user *) data; 740 741 741 - if (copy_siginfo_to_user(uinfo, &info) || 742 - __put_user(info.si_code, &uinfo->si_code)) { 742 + if (copy_siginfo_to_user(uinfo, &info)) { 743 743 ret = -EFAULT; 744 744 break; 745 745 }
+55 -17
kernel/signal.c
··· 2682 2682 } 2683 2683 #endif 2684 2684 2685 + enum siginfo_layout siginfo_layout(int sig, int si_code) 2686 + { 2687 + enum siginfo_layout layout = SIL_KILL; 2688 + if ((si_code > SI_USER) && (si_code < SI_KERNEL)) { 2689 + static const struct { 2690 + unsigned char limit, layout; 2691 + } filter[] = { 2692 + [SIGILL] = { NSIGILL, SIL_FAULT }, 2693 + [SIGFPE] = { NSIGFPE, SIL_FAULT }, 2694 + [SIGSEGV] = { NSIGSEGV, SIL_FAULT }, 2695 + [SIGBUS] = { NSIGBUS, SIL_FAULT }, 2696 + [SIGTRAP] = { NSIGTRAP, SIL_FAULT }, 2697 + #if defined(SIGMET) && defined(NSIGEMT) 2698 + [SIGEMT] = { NSIGEMT, SIL_FAULT }, 2699 + #endif 2700 + [SIGCHLD] = { NSIGCHLD, SIL_CHLD }, 2701 + [SIGPOLL] = { NSIGPOLL, SIL_POLL }, 2702 + #ifdef __ARCH_SIGSYS 2703 + [SIGSYS] = { NSIGSYS, SIL_SYS }, 2704 + #endif 2705 + }; 2706 + if ((sig < ARRAY_SIZE(filter)) && (si_code <= filter[sig].limit)) 2707 + layout = filter[sig].layout; 2708 + else if (si_code <= NSIGPOLL) 2709 + layout = SIL_POLL; 2710 + } else { 2711 + if (si_code == SI_TIMER) 2712 + layout = SIL_TIMER; 2713 + else if (si_code == SI_SIGIO) 2714 + layout = SIL_POLL; 2715 + else if (si_code < 0) 2716 + layout = SIL_RT; 2717 + /* Tests to support buggy kernel ABIs */ 2718 + #ifdef TRAP_FIXME 2719 + if ((sig == SIGTRAP) && (si_code == TRAP_FIXME)) 2720 + layout = SIL_FAULT; 2721 + #endif 2722 + #ifdef FPE_FIXME 2723 + if ((sig == SIGFPE) && (si_code == FPE_FIXME)) 2724 + layout = SIL_FAULT; 2725 + #endif 2726 + } 2727 + return layout; 2728 + } 2729 + 2685 2730 #ifndef HAVE_ARCH_COPY_SIGINFO_TO_USER 2686 2731 2687 2732 int copy_siginfo_to_user(siginfo_t __user *to, const siginfo_t *from) ··· 2749 2704 */ 2750 2705 err = __put_user(from->si_signo, &to->si_signo); 2751 2706 err |= __put_user(from->si_errno, &to->si_errno); 2752 - err |= __put_user((short)from->si_code, &to->si_code); 2753 - switch (from->si_code & __SI_MASK) { 2754 - case __SI_KILL: 2707 + err |= __put_user(from->si_code, &to->si_code); 2708 + switch (siginfo_layout(from->si_signo, from->si_code)) { 2709 + case SIL_KILL: 2755 2710 err |= __put_user(from->si_pid, &to->si_pid); 2756 2711 err |= __put_user(from->si_uid, &to->si_uid); 2757 2712 break; 2758 - case __SI_TIMER: 2759 - err |= __put_user(from->si_tid, &to->si_tid); 2760 - err |= __put_user(from->si_overrun, &to->si_overrun); 2761 - err |= __put_user(from->si_ptr, &to->si_ptr); 2713 + case SIL_TIMER: 2714 + /* Unreached SI_TIMER is negative */ 2762 2715 break; 2763 - case __SI_POLL: 2716 + case SIL_POLL: 2764 2717 err |= __put_user(from->si_band, &to->si_band); 2765 2718 err |= __put_user(from->si_fd, &to->si_fd); 2766 2719 break; 2767 - case __SI_FAULT: 2720 + case SIL_FAULT: 2768 2721 err |= __put_user(from->si_addr, &to->si_addr); 2769 2722 #ifdef __ARCH_SI_TRAPNO 2770 2723 err |= __put_user(from->si_trapno, &to->si_trapno); ··· 2787 2744 err |= __put_user(from->si_pkey, &to->si_pkey); 2788 2745 #endif 2789 2746 break; 2790 - case __SI_CHLD: 2747 + case SIL_CHLD: 2791 2748 err |= __put_user(from->si_pid, &to->si_pid); 2792 2749 err |= __put_user(from->si_uid, &to->si_uid); 2793 2750 err |= __put_user(from->si_status, &to->si_status); 2794 2751 err |= __put_user(from->si_utime, &to->si_utime); 2795 2752 err |= __put_user(from->si_stime, &to->si_stime); 2796 2753 break; 2797 - case __SI_RT: /* This is not generated by the kernel as of now. */ 2798 - case __SI_MESGQ: /* But this is */ 2754 + case SIL_RT: 2799 2755 err |= __put_user(from->si_pid, &to->si_pid); 2800 2756 err |= __put_user(from->si_uid, &to->si_uid); 2801 2757 err |= __put_user(from->si_ptr, &to->si_ptr); 2802 2758 break; 2803 2759 #ifdef __ARCH_SIGSYS 2804 - case __SI_SYS: 2760 + case SIL_SYS: 2805 2761 err |= __put_user(from->si_call_addr, &to->si_call_addr); 2806 2762 err |= __put_user(from->si_syscall, &to->si_syscall); 2807 2763 err |= __put_user(from->si_arch, &to->si_arch); 2808 2764 break; 2809 2765 #endif 2810 - default: /* this is just in case for now ... */ 2811 - err |= __put_user(from->si_pid, &to->si_pid); 2812 - err |= __put_user(from->si_uid, &to->si_uid); 2813 - break; 2814 2766 } 2815 2767 return err; 2816 2768 }