diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-24 06:22:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-24 06:22:39 -0400 |
commit | ba9f6f8954afa5224e3ed60332f7b92242b7ed0f (patch) | |
tree | e6513afc476231dc2242728ffbf51353936b46af | |
parent | a978a5b8d83f795e107a2ff759b28643739be70e (diff) | |
parent | a36700589b85443e28170be59fa11c8a104130a5 (diff) |
Merge branch 'siginfo-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull siginfo updates from Eric Biederman:
"I have been slowly sorting out siginfo and this is the culmination of
that work.
The primary result is in several ways the signal infrastructure has
been made less error prone. The code has been updated so that manually
specifying SEND_SIG_FORCED is never necessary. The conversion to the
new siginfo sending functions is now complete, which makes it
difficult to send a signal without filling in the proper siginfo
fields.
At the tail end of the patchset comes the optimization of decreasing
the size of struct siginfo in the kernel from 128 bytes to about 48
bytes on 64bit. The fundamental observation that enables this is by
definition none of the known ways to use struct siginfo uses the extra
bytes.
This comes at the cost of a small user space observable difference.
For the rare case of siginfo being injected into the kernel only what
can be copied into kernel_siginfo is delivered to the destination, the
rest of the bytes are set to 0. For cases where the signal and the
si_code are known this is safe, because we know those bytes are not
used. For cases where the signal and si_code combination is unknown
the bits that won't fit into struct kernel_siginfo are tested to
verify they are zero, and the send fails if they are not.
I made an extensive search through userspace code and I could not find
anything that would break because of the above change. If it turns out
I did break something it will take just the revert of a single change
to restore kernel_siginfo to the same size as userspace siginfo.
Testing did reveal dependencies on preferring the signo passed to
sigqueueinfo over si->signo, so bit the bullet and added the
complexity necessary to handle that case.
Testing also revealed bad things can happen if a negative signal
number is passed into the system calls. Something no sane application
will do but something a malicious program or a fuzzer might do. So I
have fixed the code that performs the bounds checks to ensure negative
signal numbers are handled"
* 'siginfo-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: (80 commits)
signal: Guard against negative signal numbers in copy_siginfo_from_user32
signal: Guard against negative signal numbers in copy_siginfo_from_user
signal: In sigqueueinfo prefer sig not si_signo
signal: Use a smaller struct siginfo in the kernel
signal: Distinguish between kernel_siginfo and siginfo
signal: Introduce copy_siginfo_from_user and use it's return value
signal: Remove the need for __ARCH_SI_PREABLE_SIZE and SI_PAD_SIZE
signal: Fail sigqueueinfo if si_signo != sig
signal/sparc: Move EMT_TAGOVF into the generic siginfo.h
signal/unicore32: Use force_sig_fault where appropriate
signal/unicore32: Generate siginfo in ucs32_notify_die
signal/unicore32: Use send_sig_fault where appropriate
signal/arc: Use force_sig_fault where appropriate
signal/arc: Push siginfo generation into unhandled_exception
signal/ia64: Use force_sig_fault where appropriate
signal/ia64: Use the force_sig(SIGSEGV,...) in ia64_rt_sigreturn
signal/ia64: Use the generic force_sigsegv in setup_frame
signal/arm/kvm: Use send_sig_mceerr
signal/arm: Use send_sig_fault where appropriate
signal/arm: Use force_sig_fault where appropriate
...
98 files changed, 925 insertions, 1328 deletions
diff --git a/arch/alpha/include/uapi/asm/siginfo.h b/arch/alpha/include/uapi/asm/siginfo.h index db3f0138536f..6e1a2af2f962 100644 --- a/arch/alpha/include/uapi/asm/siginfo.h +++ b/arch/alpha/include/uapi/asm/siginfo.h | |||
@@ -2,7 +2,6 @@ | |||
2 | #ifndef _ALPHA_SIGINFO_H | 2 | #ifndef _ALPHA_SIGINFO_H |
3 | #define _ALPHA_SIGINFO_H | 3 | #define _ALPHA_SIGINFO_H |
4 | 4 | ||
5 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | ||
6 | #define __ARCH_SI_TRAPNO | 5 | #define __ARCH_SI_TRAPNO |
7 | 6 | ||
8 | #include <asm-generic/siginfo.h> | 7 | #include <asm-generic/siginfo.h> |
diff --git a/arch/arc/kernel/traps.c b/arch/arc/kernel/traps.c index b123558bf0bb..a7fcbc0d3943 100644 --- a/arch/arc/kernel/traps.c +++ b/arch/arc/kernel/traps.c | |||
@@ -42,21 +42,22 @@ void die(const char *str, struct pt_regs *regs, unsigned long address) | |||
42 | * -for kernel, chk if due to copy_(to|from)_user, otherwise die() | 42 | * -for kernel, chk if due to copy_(to|from)_user, otherwise die() |
43 | */ | 43 | */ |
44 | static noinline int | 44 | static noinline int |
45 | unhandled_exception(const char *str, struct pt_regs *regs, siginfo_t *info) | 45 | unhandled_exception(const char *str, struct pt_regs *regs, |
46 | int signo, int si_code, void __user *addr) | ||
46 | { | 47 | { |
47 | if (user_mode(regs)) { | 48 | if (user_mode(regs)) { |
48 | struct task_struct *tsk = current; | 49 | struct task_struct *tsk = current; |
49 | 50 | ||
50 | tsk->thread.fault_address = (__force unsigned int)info->si_addr; | 51 | tsk->thread.fault_address = (__force unsigned int)addr; |
51 | 52 | ||
52 | force_sig_info(info->si_signo, info, tsk); | 53 | force_sig_fault(signo, si_code, addr, tsk); |
53 | 54 | ||
54 | } else { | 55 | } else { |
55 | /* If not due to copy_(to|from)_user, we are doomed */ | 56 | /* If not due to copy_(to|from)_user, we are doomed */ |
56 | if (fixup_exception(regs)) | 57 | if (fixup_exception(regs)) |
57 | return 0; | 58 | return 0; |
58 | 59 | ||
59 | die(str, regs, (unsigned long)info->si_addr); | 60 | die(str, regs, (unsigned long)addr); |
60 | } | 61 | } |
61 | 62 | ||
62 | return 1; | 63 | return 1; |
@@ -64,16 +65,9 @@ unhandled_exception(const char *str, struct pt_regs *regs, siginfo_t *info) | |||
64 | 65 | ||
65 | #define DO_ERROR_INFO(signr, str, name, sicode) \ | 66 | #define DO_ERROR_INFO(signr, str, name, sicode) \ |
66 | int name(unsigned long address, struct pt_regs *regs) \ | 67 | int name(unsigned long address, struct pt_regs *regs) \ |
67 | { \ | 68 | { \ |
68 | siginfo_t info; \ | 69 | return unhandled_exception(str, regs, signr, sicode, \ |
69 | \ | 70 | (void __user *)address); \ |
70 | clear_siginfo(&info); \ | ||
71 | info.si_signo = signr; \ | ||
72 | info.si_errno = 0; \ | ||
73 | info.si_code = sicode; \ | ||
74 | info.si_addr = (void __user *)address; \ | ||
75 | \ | ||
76 | return unhandled_exception(str, regs, &info);\ | ||
77 | } | 71 | } |
78 | 72 | ||
79 | /* | 73 | /* |
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c index db6913094be3..c9da6102eb4f 100644 --- a/arch/arc/mm/fault.c +++ b/arch/arc/mm/fault.c | |||
@@ -66,14 +66,12 @@ void do_page_fault(unsigned long address, struct pt_regs *regs) | |||
66 | struct vm_area_struct *vma = NULL; | 66 | struct vm_area_struct *vma = NULL; |
67 | struct task_struct *tsk = current; | 67 | struct task_struct *tsk = current; |
68 | struct mm_struct *mm = tsk->mm; | 68 | struct mm_struct *mm = tsk->mm; |
69 | siginfo_t info; | 69 | int si_code; |
70 | int ret; | 70 | int ret; |
71 | vm_fault_t fault; | 71 | vm_fault_t fault; |
72 | int write = regs->ecr_cause & ECR_C_PROTV_STORE; /* ST/EX */ | 72 | int write = regs->ecr_cause & ECR_C_PROTV_STORE; /* ST/EX */ |
73 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; | 73 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; |
74 | 74 | ||
75 | clear_siginfo(&info); | ||
76 | |||
77 | /* | 75 | /* |
78 | * We fault-in kernel-space virtual memory on-demand. The | 76 | * We fault-in kernel-space virtual memory on-demand. The |
79 | * 'reference' page table is init_mm.pgd. | 77 | * 'reference' page table is init_mm.pgd. |
@@ -91,7 +89,7 @@ void do_page_fault(unsigned long address, struct pt_regs *regs) | |||
91 | return; | 89 | return; |
92 | } | 90 | } |
93 | 91 | ||
94 | info.si_code = SEGV_MAPERR; | 92 | si_code = SEGV_MAPERR; |
95 | 93 | ||
96 | /* | 94 | /* |
97 | * If we're in an interrupt or have no user | 95 | * If we're in an interrupt or have no user |
@@ -119,7 +117,7 @@ retry: | |||
119 | * we can handle it.. | 117 | * we can handle it.. |
120 | */ | 118 | */ |
121 | good_area: | 119 | good_area: |
122 | info.si_code = SEGV_ACCERR; | 120 | si_code = SEGV_ACCERR; |
123 | 121 | ||
124 | /* Handle protection violation, execute on heap or stack */ | 122 | /* Handle protection violation, execute on heap or stack */ |
125 | 123 | ||
@@ -199,11 +197,7 @@ bad_area_nosemaphore: | |||
199 | /* User mode accesses just cause a SIGSEGV */ | 197 | /* User mode accesses just cause a SIGSEGV */ |
200 | if (user_mode(regs)) { | 198 | if (user_mode(regs)) { |
201 | tsk->thread.fault_address = address; | 199 | tsk->thread.fault_address = address; |
202 | info.si_signo = SIGSEGV; | 200 | force_sig_fault(SIGSEGV, si_code, (void __user *)address, tsk); |
203 | info.si_errno = 0; | ||
204 | /* info.si_code has been set above */ | ||
205 | info.si_addr = (void __user *)address; | ||
206 | force_sig_info(SIGSEGV, &info, tsk); | ||
207 | return; | 201 | return; |
208 | } | 202 | } |
209 | 203 | ||
@@ -238,9 +232,5 @@ do_sigbus: | |||
238 | goto no_context; | 232 | goto no_context; |
239 | 233 | ||
240 | tsk->thread.fault_address = address; | 234 | tsk->thread.fault_address = address; |
241 | info.si_signo = SIGBUS; | 235 | force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)address, tsk); |
242 | info.si_errno = 0; | ||
243 | info.si_code = BUS_ADRERR; | ||
244 | info.si_addr = (void __user *)address; | ||
245 | force_sig_info(SIGBUS, &info, tsk); | ||
246 | } | 236 | } |
diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h index 237aa52d8733..36c951dd23b8 100644 --- a/arch/arm/include/asm/bug.h +++ b/arch/arm/include/asm/bug.h | |||
@@ -62,8 +62,8 @@ do { \ | |||
62 | struct pt_regs; | 62 | struct pt_regs; |
63 | void die(const char *msg, struct pt_regs *regs, int err); | 63 | void die(const char *msg, struct pt_regs *regs, int err); |
64 | 64 | ||
65 | struct siginfo; | 65 | void arm_notify_die(const char *str, struct pt_regs *regs, |
66 | void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, | 66 | int signo, int si_code, void __user *addr, |
67 | unsigned long err, unsigned long trap); | 67 | unsigned long err, unsigned long trap); |
68 | 68 | ||
69 | #ifdef CONFIG_ARM_LPAE | 69 | #ifdef CONFIG_ARM_LPAE |
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 36718a424358..6fa5b6387556 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
@@ -203,15 +203,8 @@ void ptrace_disable(struct task_struct *child) | |||
203 | */ | 203 | */ |
204 | void ptrace_break(struct task_struct *tsk, struct pt_regs *regs) | 204 | void ptrace_break(struct task_struct *tsk, struct pt_regs *regs) |
205 | { | 205 | { |
206 | siginfo_t info; | 206 | force_sig_fault(SIGTRAP, TRAP_BRKPT, |
207 | 207 | (void __user *)instruction_pointer(regs), tsk); | |
208 | clear_siginfo(&info); | ||
209 | info.si_signo = SIGTRAP; | ||
210 | info.si_errno = 0; | ||
211 | info.si_code = TRAP_BRKPT; | ||
212 | info.si_addr = (void __user *)instruction_pointer(regs); | ||
213 | |||
214 | force_sig_info(SIGTRAP, &info, tsk); | ||
215 | } | 208 | } |
216 | 209 | ||
217 | static int break_trap(struct pt_regs *regs, unsigned int instr) | 210 | static int break_trap(struct pt_regs *regs, unsigned int instr) |
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c index 80517f293eb9..a188d5e8ab7f 100644 --- a/arch/arm/kernel/swp_emulate.c +++ b/arch/arm/kernel/swp_emulate.c | |||
@@ -98,22 +98,20 @@ static int proc_status_show(struct seq_file *m, void *v) | |||
98 | */ | 98 | */ |
99 | static void set_segfault(struct pt_regs *regs, unsigned long addr) | 99 | static void set_segfault(struct pt_regs *regs, unsigned long addr) |
100 | { | 100 | { |
101 | siginfo_t info; | 101 | int si_code; |
102 | 102 | ||
103 | clear_siginfo(&info); | ||
104 | down_read(¤t->mm->mmap_sem); | 103 | down_read(¤t->mm->mmap_sem); |
105 | if (find_vma(current->mm, addr) == NULL) | 104 | if (find_vma(current->mm, addr) == NULL) |
106 | info.si_code = SEGV_MAPERR; | 105 | si_code = SEGV_MAPERR; |
107 | else | 106 | else |
108 | info.si_code = SEGV_ACCERR; | 107 | si_code = SEGV_ACCERR; |
109 | up_read(¤t->mm->mmap_sem); | 108 | up_read(¤t->mm->mmap_sem); |
110 | 109 | ||
111 | info.si_signo = SIGSEGV; | ||
112 | info.si_errno = 0; | ||
113 | info.si_addr = (void *) instruction_pointer(regs); | ||
114 | |||
115 | pr_debug("SWP{B} emulation: access caused memory abort!\n"); | 110 | pr_debug("SWP{B} emulation: access caused memory abort!\n"); |
116 | arm_notify_die("Illegal memory access", regs, &info, 0, 0); | 111 | arm_notify_die("Illegal memory access", regs, |
112 | SIGSEGV, si_code, | ||
113 | (void __user *)instruction_pointer(regs), | ||
114 | 0, 0); | ||
117 | 115 | ||
118 | abtcounter++; | 116 | abtcounter++; |
119 | } | 117 | } |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index badf02ca3693..2d668cff8ef4 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -365,13 +365,14 @@ void die(const char *str, struct pt_regs *regs, int err) | |||
365 | } | 365 | } |
366 | 366 | ||
367 | void arm_notify_die(const char *str, struct pt_regs *regs, | 367 | void arm_notify_die(const char *str, struct pt_regs *regs, |
368 | struct siginfo *info, unsigned long err, unsigned long trap) | 368 | int signo, int si_code, void __user *addr, |
369 | unsigned long err, unsigned long trap) | ||
369 | { | 370 | { |
370 | if (user_mode(regs)) { | 371 | if (user_mode(regs)) { |
371 | current->thread.error_code = err; | 372 | current->thread.error_code = err; |
372 | current->thread.trap_no = trap; | 373 | current->thread.trap_no = trap; |
373 | 374 | ||
374 | force_sig_info(info->si_signo, info, current); | 375 | force_sig_fault(signo, si_code, addr, current); |
375 | } else { | 376 | } else { |
376 | die(str, regs, err); | 377 | die(str, regs, err); |
377 | } | 378 | } |
@@ -438,10 +439,8 @@ int call_undef_hook(struct pt_regs *regs, unsigned int instr) | |||
438 | asmlinkage void do_undefinstr(struct pt_regs *regs) | 439 | asmlinkage void do_undefinstr(struct pt_regs *regs) |
439 | { | 440 | { |
440 | unsigned int instr; | 441 | unsigned int instr; |
441 | siginfo_t info; | ||
442 | void __user *pc; | 442 | void __user *pc; |
443 | 443 | ||
444 | clear_siginfo(&info); | ||
445 | pc = (void __user *)instruction_pointer(regs); | 444 | pc = (void __user *)instruction_pointer(regs); |
446 | 445 | ||
447 | if (processor_mode(regs) == SVC_MODE) { | 446 | if (processor_mode(regs) == SVC_MODE) { |
@@ -485,13 +484,8 @@ die_sig: | |||
485 | dump_instr(KERN_INFO, regs); | 484 | dump_instr(KERN_INFO, regs); |
486 | } | 485 | } |
487 | #endif | 486 | #endif |
488 | 487 | arm_notify_die("Oops - undefined instruction", regs, | |
489 | info.si_signo = SIGILL; | 488 | SIGILL, ILL_ILLOPC, pc, 0, 6); |
490 | info.si_errno = 0; | ||
491 | info.si_code = ILL_ILLOPC; | ||
492 | info.si_addr = pc; | ||
493 | |||
494 | arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6); | ||
495 | } | 489 | } |
496 | NOKPROBE_SYMBOL(do_undefinstr) | 490 | NOKPROBE_SYMBOL(do_undefinstr) |
497 | 491 | ||
@@ -539,9 +533,6 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason) | |||
539 | 533 | ||
540 | static int bad_syscall(int n, struct pt_regs *regs) | 534 | static int bad_syscall(int n, struct pt_regs *regs) |
541 | { | 535 | { |
542 | siginfo_t info; | ||
543 | |||
544 | clear_siginfo(&info); | ||
545 | if ((current->personality & PER_MASK) != PER_LINUX) { | 536 | if ((current->personality & PER_MASK) != PER_LINUX) { |
546 | send_sig(SIGSEGV, current, 1); | 537 | send_sig(SIGSEGV, current, 1); |
547 | return regs->ARM_r0; | 538 | return regs->ARM_r0; |
@@ -555,13 +546,10 @@ static int bad_syscall(int n, struct pt_regs *regs) | |||
555 | } | 546 | } |
556 | #endif | 547 | #endif |
557 | 548 | ||
558 | info.si_signo = SIGILL; | 549 | arm_notify_die("Oops - bad syscall", regs, SIGILL, ILL_ILLTRP, |
559 | info.si_errno = 0; | 550 | (void __user *)instruction_pointer(regs) - |
560 | info.si_code = ILL_ILLTRP; | 551 | (thumb_mode(regs) ? 2 : 4), |
561 | info.si_addr = (void __user *)instruction_pointer(regs) - | 552 | n, 0); |
562 | (thumb_mode(regs) ? 2 : 4); | ||
563 | |||
564 | arm_notify_die("Oops - bad syscall", regs, &info, n, 0); | ||
565 | 553 | ||
566 | return regs->ARM_r0; | 554 | return regs->ARM_r0; |
567 | } | 555 | } |
@@ -607,20 +595,13 @@ do_cache_op(unsigned long start, unsigned long end, int flags) | |||
607 | #define NR(x) ((__ARM_NR_##x) - __ARM_NR_BASE) | 595 | #define NR(x) ((__ARM_NR_##x) - __ARM_NR_BASE) |
608 | asmlinkage int arm_syscall(int no, struct pt_regs *regs) | 596 | asmlinkage int arm_syscall(int no, struct pt_regs *regs) |
609 | { | 597 | { |
610 | siginfo_t info; | ||
611 | |||
612 | clear_siginfo(&info); | ||
613 | if ((no >> 16) != (__ARM_NR_BASE>> 16)) | 598 | if ((no >> 16) != (__ARM_NR_BASE>> 16)) |
614 | return bad_syscall(no, regs); | 599 | return bad_syscall(no, regs); |
615 | 600 | ||
616 | switch (no & 0xffff) { | 601 | switch (no & 0xffff) { |
617 | case 0: /* branch through 0 */ | 602 | case 0: /* branch through 0 */ |
618 | info.si_signo = SIGSEGV; | 603 | arm_notify_die("branch through zero", regs, |
619 | info.si_errno = 0; | 604 | SIGSEGV, SEGV_MAPERR, NULL, 0, 0); |
620 | info.si_code = SEGV_MAPERR; | ||
621 | info.si_addr = NULL; | ||
622 | |||
623 | arm_notify_die("branch through zero", regs, &info, 0, 0); | ||
624 | return 0; | 605 | return 0; |
625 | 606 | ||
626 | case NR(breakpoint): /* SWI BREAK_POINT */ | 607 | case NR(breakpoint): /* SWI BREAK_POINT */ |
@@ -688,13 +669,10 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) | |||
688 | } | 669 | } |
689 | } | 670 | } |
690 | #endif | 671 | #endif |
691 | info.si_signo = SIGILL; | 672 | arm_notify_die("Oops - bad syscall(2)", regs, SIGILL, ILL_ILLTRP, |
692 | info.si_errno = 0; | 673 | (void __user *)instruction_pointer(regs) - |
693 | info.si_code = ILL_ILLTRP; | 674 | (thumb_mode(regs) ? 2 : 4), |
694 | info.si_addr = (void __user *)instruction_pointer(regs) - | 675 | no, 0); |
695 | (thumb_mode(regs) ? 2 : 4); | ||
696 | |||
697 | arm_notify_die("Oops - bad syscall(2)", regs, &info, no, 0); | ||
698 | return 0; | 676 | return 0; |
699 | } | 677 | } |
700 | 678 | ||
@@ -744,9 +722,6 @@ asmlinkage void | |||
744 | baddataabort(int code, unsigned long instr, struct pt_regs *regs) | 722 | baddataabort(int code, unsigned long instr, struct pt_regs *regs) |
745 | { | 723 | { |
746 | unsigned long addr = instruction_pointer(regs); | 724 | unsigned long addr = instruction_pointer(regs); |
747 | siginfo_t info; | ||
748 | |||
749 | clear_siginfo(&info); | ||
750 | 725 | ||
751 | #ifdef CONFIG_DEBUG_USER | 726 | #ifdef CONFIG_DEBUG_USER |
752 | if (user_debug & UDBG_BADABORT) { | 727 | if (user_debug & UDBG_BADABORT) { |
@@ -757,12 +732,8 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs) | |||
757 | } | 732 | } |
758 | #endif | 733 | #endif |
759 | 734 | ||
760 | info.si_signo = SIGILL; | 735 | arm_notify_die("unknown data abort code", regs, |
761 | info.si_errno = 0; | 736 | SIGILL, ILL_ILLOPC, (void __user *)addr, instr, 0); |
762 | info.si_code = ILL_ILLOPC; | ||
763 | info.si_addr = (void __user *)addr; | ||
764 | |||
765 | arm_notify_die("unknown data abort code", regs, &info, instr, 0); | ||
766 | } | 737 | } |
767 | 738 | ||
768 | void __readwrite_bug(const char *fn) | 739 | void __readwrite_bug(const char *fn) |
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index bd2c739d8083..b54f8f8def36 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c | |||
@@ -948,15 +948,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
948 | goto fixup; | 948 | goto fixup; |
949 | 949 | ||
950 | if (ai_usermode & UM_SIGNAL) { | 950 | if (ai_usermode & UM_SIGNAL) { |
951 | siginfo_t si; | 951 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr, current); |
952 | |||
953 | clear_siginfo(&si); | ||
954 | si.si_signo = SIGBUS; | ||
955 | si.si_errno = 0; | ||
956 | si.si_code = BUS_ADRALN; | ||
957 | si.si_addr = (void __user *)addr; | ||
958 | |||
959 | force_sig_info(si.si_signo, &si, current); | ||
960 | } else { | 952 | } else { |
961 | /* | 953 | /* |
962 | * We're about to disable the alignment trap and return to | 954 | * We're about to disable the alignment trap and return to |
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 3232afb6fdc0..f4ea4c62c613 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c | |||
@@ -161,13 +161,9 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr, | |||
161 | unsigned int fsr, unsigned int sig, int code, | 161 | unsigned int fsr, unsigned int sig, int code, |
162 | struct pt_regs *regs) | 162 | struct pt_regs *regs) |
163 | { | 163 | { |
164 | struct siginfo si; | ||
165 | |||
166 | if (addr > TASK_SIZE) | 164 | if (addr > TASK_SIZE) |
167 | harden_branch_predictor(); | 165 | harden_branch_predictor(); |
168 | 166 | ||
169 | clear_siginfo(&si); | ||
170 | |||
171 | #ifdef CONFIG_DEBUG_USER | 167 | #ifdef CONFIG_DEBUG_USER |
172 | if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) || | 168 | if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) || |
173 | ((user_debug & UDBG_BUS) && (sig == SIGBUS))) { | 169 | ((user_debug & UDBG_BUS) && (sig == SIGBUS))) { |
@@ -181,11 +177,7 @@ __do_user_fault(struct task_struct *tsk, unsigned long addr, | |||
181 | tsk->thread.address = addr; | 177 | tsk->thread.address = addr; |
182 | tsk->thread.error_code = fsr; | 178 | tsk->thread.error_code = fsr; |
183 | tsk->thread.trap_no = 14; | 179 | tsk->thread.trap_no = 14; |
184 | si.si_signo = sig; | 180 | force_sig_fault(sig, code, (void __user *)addr, tsk); |
185 | si.si_errno = 0; | ||
186 | si.si_code = code; | ||
187 | si.si_addr = (void __user *)addr; | ||
188 | force_sig_info(sig, &si, tsk); | ||
189 | } | 181 | } |
190 | 182 | ||
191 | void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | 183 | void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) |
@@ -554,7 +546,6 @@ asmlinkage void | |||
554 | do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | 546 | do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) |
555 | { | 547 | { |
556 | const struct fsr_info *inf = fsr_info + fsr_fs(fsr); | 548 | const struct fsr_info *inf = fsr_info + fsr_fs(fsr); |
557 | struct siginfo info; | ||
558 | 549 | ||
559 | if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs)) | 550 | if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs)) |
560 | return; | 551 | return; |
@@ -563,12 +554,8 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
563 | inf->name, fsr, addr); | 554 | inf->name, fsr, addr); |
564 | show_pte(current->mm, addr); | 555 | show_pte(current->mm, addr); |
565 | 556 | ||
566 | clear_siginfo(&info); | 557 | arm_notify_die("", regs, inf->sig, inf->code, (void __user *)addr, |
567 | info.si_signo = inf->sig; | 558 | fsr, 0); |
568 | info.si_errno = 0; | ||
569 | info.si_code = inf->code; | ||
570 | info.si_addr = (void __user *)addr; | ||
571 | arm_notify_die("", regs, &info, fsr, 0); | ||
572 | } | 559 | } |
573 | 560 | ||
574 | void __init | 561 | void __init |
@@ -588,7 +575,6 @@ asmlinkage void | |||
588 | do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs) | 575 | do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs) |
589 | { | 576 | { |
590 | const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr); | 577 | const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr); |
591 | struct siginfo info; | ||
592 | 578 | ||
593 | if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs)) | 579 | if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs)) |
594 | return; | 580 | return; |
@@ -596,12 +582,8 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs) | |||
596 | pr_alert("Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n", | 582 | pr_alert("Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n", |
597 | inf->name, ifsr, addr); | 583 | inf->name, ifsr, addr); |
598 | 584 | ||
599 | clear_siginfo(&info); | 585 | arm_notify_die("", regs, inf->sig, inf->code, (void __user *)addr, |
600 | info.si_signo = inf->sig; | 586 | ifsr, 0); |
601 | info.si_errno = 0; | ||
602 | info.si_code = inf->code; | ||
603 | info.si_addr = (void __user *)addr; | ||
604 | arm_notify_die("", regs, &info, ifsr, 0); | ||
605 | } | 587 | } |
606 | 588 | ||
607 | /* | 589 | /* |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 2b287d0d6bc2..aff6e6eadc70 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -216,13 +216,6 @@ static struct notifier_block vfp_notifier_block = { | |||
216 | */ | 216 | */ |
217 | static void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) | 217 | static void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) |
218 | { | 218 | { |
219 | siginfo_t info; | ||
220 | |||
221 | clear_siginfo(&info); | ||
222 | info.si_signo = SIGFPE; | ||
223 | info.si_code = sicode; | ||
224 | info.si_addr = (void __user *)(instruction_pointer(regs) - 4); | ||
225 | |||
226 | /* | 219 | /* |
227 | * This is the same as NWFPE, because it's not clear what | 220 | * This is the same as NWFPE, because it's not clear what |
228 | * this is used for | 221 | * this is used for |
@@ -230,7 +223,9 @@ static void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) | |||
230 | current->thread.error_code = 0; | 223 | current->thread.error_code = 0; |
231 | current->thread.trap_no = 6; | 224 | current->thread.trap_no = 6; |
232 | 225 | ||
233 | send_sig_info(SIGFPE, &info, current); | 226 | send_sig_fault(SIGFPE, sicode, |
227 | (void __user *)(instruction_pointer(regs) - 4), | ||
228 | current); | ||
234 | } | 229 | } |
235 | 230 | ||
236 | static void vfp_panic(char *reason, u32 inst) | 231 | static void vfp_panic(char *reason, u32 inst) |
diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h index 28893a0b141d..0e2a0ecaf484 100644 --- a/arch/arm64/include/asm/system_misc.h +++ b/arch/arm64/include/asm/system_misc.h | |||
@@ -33,7 +33,8 @@ void die(const char *msg, struct pt_regs *regs, int err); | |||
33 | 33 | ||
34 | struct siginfo; | 34 | struct siginfo; |
35 | void arm64_notify_die(const char *str, struct pt_regs *regs, | 35 | void arm64_notify_die(const char *str, struct pt_regs *regs, |
36 | struct siginfo *info, int err); | 36 | int signo, int sicode, void __user *addr, |
37 | int err); | ||
37 | 38 | ||
38 | void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned int, | 39 | void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned int, |
39 | struct pt_regs *), | 40 | struct pt_regs *), |
diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h index c320f3bf6c57..f9c1aa6167d2 100644 --- a/arch/arm64/include/asm/traps.h +++ b/arch/arm64/include/asm/traps.h | |||
@@ -37,8 +37,9 @@ void register_undef_hook(struct undef_hook *hook); | |||
37 | void unregister_undef_hook(struct undef_hook *hook); | 37 | void unregister_undef_hook(struct undef_hook *hook); |
38 | void force_signal_inject(int signal, int code, unsigned long address); | 38 | void force_signal_inject(int signal, int code, unsigned long address); |
39 | void arm64_notify_segfault(unsigned long addr); | 39 | void arm64_notify_segfault(unsigned long addr); |
40 | void arm64_force_sig_info(struct siginfo *info, const char *str, | 40 | void arm64_force_sig_fault(int signo, int code, void __user *addr, const char *str); |
41 | struct task_struct *tsk); | 41 | void arm64_force_sig_mceerr(int code, void __user *addr, short lsb, const char *str); |
42 | void arm64_force_sig_ptrace_errno_trap(int errno, void __user *addr, const char *str); | ||
42 | 43 | ||
43 | /* | 44 | /* |
44 | * Move regs->pc to next instruction and do necessary setup before it | 45 | * Move regs->pc to next instruction and do necessary setup before it |
diff --git a/arch/arm64/include/uapi/asm/Kbuild b/arch/arm64/include/uapi/asm/Kbuild index 198afbf0688f..6c5adf458690 100644 --- a/arch/arm64/include/uapi/asm/Kbuild +++ b/arch/arm64/include/uapi/asm/Kbuild | |||
@@ -19,3 +19,4 @@ generic-y += swab.h | |||
19 | generic-y += termbits.h | 19 | generic-y += termbits.h |
20 | generic-y += termios.h | 20 | generic-y += termios.h |
21 | generic-y += types.h | 21 | generic-y += types.h |
22 | generic-y += siginfo.h | ||
diff --git a/arch/arm64/include/uapi/asm/siginfo.h b/arch/arm64/include/uapi/asm/siginfo.h deleted file mode 100644 index 574d12f86039..000000000000 --- a/arch/arm64/include/uapi/asm/siginfo.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | ||
2 | /* | ||
3 | * Copyright (C) 2012 ARM Ltd. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | #ifndef __ASM_SIGINFO_H | ||
18 | #define __ASM_SIGINFO_H | ||
19 | |||
20 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | ||
21 | |||
22 | #include <asm-generic/siginfo.h> | ||
23 | |||
24 | #endif | ||
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index 06ca574495af..d7bb6aefae0a 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c | |||
@@ -210,13 +210,6 @@ NOKPROBE_SYMBOL(call_step_hook); | |||
210 | static void send_user_sigtrap(int si_code) | 210 | static void send_user_sigtrap(int si_code) |
211 | { | 211 | { |
212 | struct pt_regs *regs = current_pt_regs(); | 212 | struct pt_regs *regs = current_pt_regs(); |
213 | siginfo_t info; | ||
214 | |||
215 | clear_siginfo(&info); | ||
216 | info.si_signo = SIGTRAP; | ||
217 | info.si_errno = 0; | ||
218 | info.si_code = si_code; | ||
219 | info.si_addr = (void __user *)instruction_pointer(regs); | ||
220 | 213 | ||
221 | if (WARN_ON(!user_mode(regs))) | 214 | if (WARN_ON(!user_mode(regs))) |
222 | return; | 215 | return; |
@@ -224,7 +217,9 @@ static void send_user_sigtrap(int si_code) | |||
224 | if (interrupts_enabled(regs)) | 217 | if (interrupts_enabled(regs)) |
225 | local_irq_enable(); | 218 | local_irq_enable(); |
226 | 219 | ||
227 | arm64_force_sig_info(&info, "User debug trap", current); | 220 | arm64_force_sig_fault(SIGTRAP, si_code, |
221 | (void __user *)instruction_pointer(regs), | ||
222 | "User debug trap"); | ||
228 | } | 223 | } |
229 | 224 | ||
230 | static int single_step_handler(unsigned long addr, unsigned int esr, | 225 | static int single_step_handler(unsigned long addr, unsigned int esr, |
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 58c53bc96928..5ebe73b69961 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c | |||
@@ -842,7 +842,6 @@ asmlinkage void do_fpsimd_acc(unsigned int esr, struct pt_regs *regs) | |||
842 | */ | 842 | */ |
843 | asmlinkage void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs) | 843 | asmlinkage void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs) |
844 | { | 844 | { |
845 | siginfo_t info; | ||
846 | unsigned int si_code = FPE_FLTUNK; | 845 | unsigned int si_code = FPE_FLTUNK; |
847 | 846 | ||
848 | if (esr & ESR_ELx_FP_EXC_TFV) { | 847 | if (esr & ESR_ELx_FP_EXC_TFV) { |
@@ -858,12 +857,9 @@ asmlinkage void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs) | |||
858 | si_code = FPE_FLTRES; | 857 | si_code = FPE_FLTRES; |
859 | } | 858 | } |
860 | 859 | ||
861 | clear_siginfo(&info); | 860 | send_sig_fault(SIGFPE, si_code, |
862 | info.si_signo = SIGFPE; | 861 | (void __user *)instruction_pointer(regs), |
863 | info.si_code = si_code; | 862 | current); |
864 | info.si_addr = (void __user *)instruction_pointer(regs); | ||
865 | |||
866 | send_sig_info(SIGFPE, &info, current); | ||
867 | } | 863 | } |
868 | 864 | ||
869 | void fpsimd_thread_switch(struct task_struct *next) | 865 | void fpsimd_thread_switch(struct task_struct *next) |
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 6219486fa25f..1710a2d01669 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c | |||
@@ -182,13 +182,7 @@ static void ptrace_hbptriggered(struct perf_event *bp, | |||
182 | struct pt_regs *regs) | 182 | struct pt_regs *regs) |
183 | { | 183 | { |
184 | struct arch_hw_breakpoint *bkpt = counter_arch_bp(bp); | 184 | struct arch_hw_breakpoint *bkpt = counter_arch_bp(bp); |
185 | siginfo_t info; | 185 | const char *desc = "Hardware breakpoint trap (ptrace)"; |
186 | |||
187 | clear_siginfo(&info); | ||
188 | info.si_signo = SIGTRAP; | ||
189 | info.si_errno = 0; | ||
190 | info.si_code = TRAP_HWBKPT; | ||
191 | info.si_addr = (void __user *)(bkpt->trigger); | ||
192 | 186 | ||
193 | #ifdef CONFIG_COMPAT | 187 | #ifdef CONFIG_COMPAT |
194 | if (is_compat_task()) { | 188 | if (is_compat_task()) { |
@@ -208,10 +202,14 @@ static void ptrace_hbptriggered(struct perf_event *bp, | |||
208 | break; | 202 | break; |
209 | } | 203 | } |
210 | } | 204 | } |
211 | force_sig_ptrace_errno_trap(si_errno, (void __user *)bkpt->trigger); | 205 | arm64_force_sig_ptrace_errno_trap(si_errno, |
206 | (void __user *)bkpt->trigger, | ||
207 | desc); | ||
212 | } | 208 | } |
213 | #endif | 209 | #endif |
214 | arm64_force_sig_info(&info, "Hardware breakpoint trap (ptrace)", current); | 210 | arm64_force_sig_fault(SIGTRAP, TRAP_HWBKPT, |
211 | (void __user *)(bkpt->trigger), | ||
212 | desc); | ||
215 | } | 213 | } |
216 | 214 | ||
217 | /* | 215 | /* |
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c index a6109825eeb9..32653d156747 100644 --- a/arch/arm64/kernel/sys_compat.c +++ b/arch/arm64/kernel/sys_compat.c | |||
@@ -68,8 +68,8 @@ do_compat_cache_op(unsigned long start, unsigned long end, int flags) | |||
68 | */ | 68 | */ |
69 | long compat_arm_syscall(struct pt_regs *regs) | 69 | long compat_arm_syscall(struct pt_regs *regs) |
70 | { | 70 | { |
71 | siginfo_t info; | ||
72 | unsigned int no = regs->regs[7]; | 71 | unsigned int no = regs->regs[7]; |
72 | void __user *addr; | ||
73 | 73 | ||
74 | switch (no) { | 74 | switch (no) { |
75 | /* | 75 | /* |
@@ -112,13 +112,10 @@ long compat_arm_syscall(struct pt_regs *regs) | |||
112 | break; | 112 | break; |
113 | } | 113 | } |
114 | 114 | ||
115 | clear_siginfo(&info); | 115 | addr = (void __user *)instruction_pointer(regs) - |
116 | info.si_signo = SIGILL; | 116 | (compat_thumb_mode(regs) ? 2 : 4); |
117 | info.si_errno = 0; | ||
118 | info.si_code = ILL_ILLTRP; | ||
119 | info.si_addr = (void __user *)instruction_pointer(regs) - | ||
120 | (compat_thumb_mode(regs) ? 2 : 4); | ||
121 | 117 | ||
122 | arm64_notify_die("Oops - bad compat syscall(2)", regs, &info, no); | 118 | arm64_notify_die("Oops - bad compat syscall(2)", regs, |
119 | SIGILL, ILL_ILLTRP, addr, no); | ||
123 | return 0; | 120 | return 0; |
124 | } | 121 | } |
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 4066da7f1e5e..5f4d9acb32f5 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c | |||
@@ -224,24 +224,19 @@ void die(const char *str, struct pt_regs *regs, int err) | |||
224 | do_exit(SIGSEGV); | 224 | do_exit(SIGSEGV); |
225 | } | 225 | } |
226 | 226 | ||
227 | static bool show_unhandled_signals_ratelimited(void) | 227 | static void arm64_show_signal(int signo, const char *str) |
228 | { | 228 | { |
229 | static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, | 229 | static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, |
230 | DEFAULT_RATELIMIT_BURST); | 230 | DEFAULT_RATELIMIT_BURST); |
231 | return show_unhandled_signals && __ratelimit(&rs); | 231 | struct task_struct *tsk = current; |
232 | } | ||
233 | |||
234 | void arm64_force_sig_info(struct siginfo *info, const char *str, | ||
235 | struct task_struct *tsk) | ||
236 | { | ||
237 | unsigned int esr = tsk->thread.fault_code; | 232 | unsigned int esr = tsk->thread.fault_code; |
238 | struct pt_regs *regs = task_pt_regs(tsk); | 233 | struct pt_regs *regs = task_pt_regs(tsk); |
239 | 234 | ||
240 | if (!unhandled_signal(tsk, info->si_signo)) | 235 | /* Leave if the signal won't be shown */ |
241 | goto send_sig; | 236 | if (!show_unhandled_signals || |
242 | 237 | !unhandled_signal(tsk, signo) || | |
243 | if (!show_unhandled_signals_ratelimited()) | 238 | !__ratelimit(&rs)) |
244 | goto send_sig; | 239 | return; |
245 | 240 | ||
246 | pr_info("%s[%d]: unhandled exception: ", tsk->comm, task_pid_nr(tsk)); | 241 | pr_info("%s[%d]: unhandled exception: ", tsk->comm, task_pid_nr(tsk)); |
247 | if (esr) | 242 | if (esr) |
@@ -251,19 +246,39 @@ void arm64_force_sig_info(struct siginfo *info, const char *str, | |||
251 | print_vma_addr(KERN_CONT " in ", regs->pc); | 246 | print_vma_addr(KERN_CONT " in ", regs->pc); |
252 | pr_cont("\n"); | 247 | pr_cont("\n"); |
253 | __show_regs(regs); | 248 | __show_regs(regs); |
249 | } | ||
250 | |||
251 | void arm64_force_sig_fault(int signo, int code, void __user *addr, | ||
252 | const char *str) | ||
253 | { | ||
254 | arm64_show_signal(signo, str); | ||
255 | force_sig_fault(signo, code, addr, current); | ||
256 | } | ||
254 | 257 | ||
255 | send_sig: | 258 | void arm64_force_sig_mceerr(int code, void __user *addr, short lsb, |
256 | force_sig_info(info->si_signo, info, tsk); | 259 | const char *str) |
260 | { | ||
261 | arm64_show_signal(SIGBUS, str); | ||
262 | force_sig_mceerr(code, addr, lsb, current); | ||
263 | } | ||
264 | |||
265 | void arm64_force_sig_ptrace_errno_trap(int errno, void __user *addr, | ||
266 | const char *str) | ||
267 | { | ||
268 | arm64_show_signal(SIGTRAP, str); | ||
269 | force_sig_ptrace_errno_trap(errno, addr); | ||
257 | } | 270 | } |
258 | 271 | ||
259 | void arm64_notify_die(const char *str, struct pt_regs *regs, | 272 | void arm64_notify_die(const char *str, struct pt_regs *regs, |
260 | struct siginfo *info, int err) | 273 | int signo, int sicode, void __user *addr, |
274 | int err) | ||
261 | { | 275 | { |
262 | if (user_mode(regs)) { | 276 | if (user_mode(regs)) { |
263 | WARN_ON(regs != current_pt_regs()); | 277 | WARN_ON(regs != current_pt_regs()); |
264 | current->thread.fault_address = 0; | 278 | current->thread.fault_address = 0; |
265 | current->thread.fault_code = err; | 279 | current->thread.fault_code = err; |
266 | arm64_force_sig_info(info, str, current); | 280 | |
281 | arm64_force_sig_fault(signo, sicode, addr, str); | ||
267 | } else { | 282 | } else { |
268 | die(str, regs, err); | 283 | die(str, regs, err); |
269 | } | 284 | } |
@@ -350,15 +365,12 @@ exit: | |||
350 | 365 | ||
351 | void force_signal_inject(int signal, int code, unsigned long address) | 366 | void force_signal_inject(int signal, int code, unsigned long address) |
352 | { | 367 | { |
353 | siginfo_t info; | ||
354 | const char *desc; | 368 | const char *desc; |
355 | struct pt_regs *regs = current_pt_regs(); | 369 | struct pt_regs *regs = current_pt_regs(); |
356 | 370 | ||
357 | if (WARN_ON(!user_mode(regs))) | 371 | if (WARN_ON(!user_mode(regs))) |
358 | return; | 372 | return; |
359 | 373 | ||
360 | clear_siginfo(&info); | ||
361 | |||
362 | switch (signal) { | 374 | switch (signal) { |
363 | case SIGILL: | 375 | case SIGILL: |
364 | desc = "undefined instruction"; | 376 | desc = "undefined instruction"; |
@@ -377,12 +389,7 @@ void force_signal_inject(int signal, int code, unsigned long address) | |||
377 | signal = SIGKILL; | 389 | signal = SIGKILL; |
378 | } | 390 | } |
379 | 391 | ||
380 | info.si_signo = signal; | 392 | arm64_notify_die(desc, regs, signal, code, (void __user *)address, 0); |
381 | info.si_errno = 0; | ||
382 | info.si_code = code; | ||
383 | info.si_addr = (void __user *)address; | ||
384 | |||
385 | arm64_notify_die(desc, regs, &info, 0); | ||
386 | } | 393 | } |
387 | 394 | ||
388 | /* | 395 | /* |
@@ -799,19 +806,13 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr) | |||
799 | */ | 806 | */ |
800 | asmlinkage void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr) | 807 | asmlinkage void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr) |
801 | { | 808 | { |
802 | siginfo_t info; | ||
803 | void __user *pc = (void __user *)instruction_pointer(regs); | 809 | void __user *pc = (void __user *)instruction_pointer(regs); |
804 | 810 | ||
805 | clear_siginfo(&info); | ||
806 | info.si_signo = SIGILL; | ||
807 | info.si_errno = 0; | ||
808 | info.si_code = ILL_ILLOPC; | ||
809 | info.si_addr = pc; | ||
810 | |||
811 | current->thread.fault_address = 0; | 811 | current->thread.fault_address = 0; |
812 | current->thread.fault_code = esr; | 812 | current->thread.fault_code = esr; |
813 | 813 | ||
814 | arm64_force_sig_info(&info, "Bad EL0 synchronous exception", current); | 814 | arm64_force_sig_fault(SIGILL, ILL_ILLOPC, pc, |
815 | "Bad EL0 synchronous exception"); | ||
815 | } | 816 | } |
816 | 817 | ||
817 | #ifdef CONFIG_VMAP_STACK | 818 | #ifdef CONFIG_VMAP_STACK |
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index d0e638ef3af6..7d9571f4ae3d 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c | |||
@@ -303,9 +303,9 @@ static void __do_kernel_fault(unsigned long addr, unsigned int esr, | |||
303 | die_kernel_fault(msg, addr, esr, regs); | 303 | die_kernel_fault(msg, addr, esr, regs); |
304 | } | 304 | } |
305 | 305 | ||
306 | static void __do_user_fault(struct siginfo *info, unsigned int esr) | 306 | static void set_thread_esr(unsigned long address, unsigned int esr) |
307 | { | 307 | { |
308 | current->thread.fault_address = (unsigned long)info->si_addr; | 308 | current->thread.fault_address = address; |
309 | 309 | ||
310 | /* | 310 | /* |
311 | * If the faulting address is in the kernel, we must sanitize the ESR. | 311 | * If the faulting address is in the kernel, we must sanitize the ESR. |
@@ -358,7 +358,6 @@ static void __do_user_fault(struct siginfo *info, unsigned int esr) | |||
358 | } | 358 | } |
359 | 359 | ||
360 | current->thread.fault_code = esr; | 360 | current->thread.fault_code = esr; |
361 | arm64_force_sig_info(info, esr_to_fault_info(esr)->name, current); | ||
362 | } | 361 | } |
363 | 362 | ||
364 | static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *regs) | 363 | static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *regs) |
@@ -369,14 +368,10 @@ static void do_bad_area(unsigned long addr, unsigned int esr, struct pt_regs *re | |||
369 | */ | 368 | */ |
370 | if (user_mode(regs)) { | 369 | if (user_mode(regs)) { |
371 | const struct fault_info *inf = esr_to_fault_info(esr); | 370 | const struct fault_info *inf = esr_to_fault_info(esr); |
372 | struct siginfo si; | ||
373 | 371 | ||
374 | clear_siginfo(&si); | 372 | set_thread_esr(addr, esr); |
375 | si.si_signo = inf->sig; | 373 | arm64_force_sig_fault(inf->sig, inf->code, (void __user *)addr, |
376 | si.si_code = inf->code; | 374 | inf->name); |
377 | si.si_addr = (void __user *)addr; | ||
378 | |||
379 | __do_user_fault(&si, esr); | ||
380 | } else { | 375 | } else { |
381 | __do_kernel_fault(addr, esr, regs); | 376 | __do_kernel_fault(addr, esr, regs); |
382 | } | 377 | } |
@@ -430,9 +425,9 @@ static bool is_el0_instruction_abort(unsigned int esr) | |||
430 | static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, | 425 | static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, |
431 | struct pt_regs *regs) | 426 | struct pt_regs *regs) |
432 | { | 427 | { |
428 | const struct fault_info *inf; | ||
433 | struct task_struct *tsk; | 429 | struct task_struct *tsk; |
434 | struct mm_struct *mm; | 430 | struct mm_struct *mm; |
435 | struct siginfo si; | ||
436 | vm_fault_t fault, major = 0; | 431 | vm_fault_t fault, major = 0; |
437 | unsigned long vm_flags = VM_READ | VM_WRITE; | 432 | unsigned long vm_flags = VM_READ | VM_WRITE; |
438 | unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; | 433 | unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; |
@@ -568,37 +563,35 @@ retry: | |||
568 | return 0; | 563 | return 0; |
569 | } | 564 | } |
570 | 565 | ||
571 | clear_siginfo(&si); | 566 | inf = esr_to_fault_info(esr); |
572 | si.si_addr = (void __user *)addr; | 567 | set_thread_esr(addr, esr); |
573 | |||
574 | if (fault & VM_FAULT_SIGBUS) { | 568 | if (fault & VM_FAULT_SIGBUS) { |
575 | /* | 569 | /* |
576 | * We had some memory, but were unable to successfully fix up | 570 | * We had some memory, but were unable to successfully fix up |
577 | * this page fault. | 571 | * this page fault. |
578 | */ | 572 | */ |
579 | si.si_signo = SIGBUS; | 573 | arm64_force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)addr, |
580 | si.si_code = BUS_ADRERR; | 574 | inf->name); |
581 | } else if (fault & VM_FAULT_HWPOISON_LARGE) { | 575 | } else if (fault & (VM_FAULT_HWPOISON_LARGE | VM_FAULT_HWPOISON)) { |
582 | unsigned int hindex = VM_FAULT_GET_HINDEX(fault); | 576 | unsigned int lsb; |
583 | 577 | ||
584 | si.si_signo = SIGBUS; | 578 | lsb = PAGE_SHIFT; |
585 | si.si_code = BUS_MCEERR_AR; | 579 | if (fault & VM_FAULT_HWPOISON_LARGE) |
586 | si.si_addr_lsb = hstate_index_to_shift(hindex); | 580 | lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault)); |
587 | } else if (fault & VM_FAULT_HWPOISON) { | 581 | |
588 | si.si_signo = SIGBUS; | 582 | arm64_force_sig_mceerr(BUS_MCEERR_AR, (void __user *)addr, lsb, |
589 | si.si_code = BUS_MCEERR_AR; | 583 | inf->name); |
590 | si.si_addr_lsb = PAGE_SHIFT; | ||
591 | } else { | 584 | } else { |
592 | /* | 585 | /* |
593 | * Something tried to access memory that isn't in our memory | 586 | * Something tried to access memory that isn't in our memory |
594 | * map. | 587 | * map. |
595 | */ | 588 | */ |
596 | si.si_signo = SIGSEGV; | 589 | arm64_force_sig_fault(SIGSEGV, |
597 | si.si_code = fault == VM_FAULT_BADACCESS ? | 590 | fault == VM_FAULT_BADACCESS ? SEGV_ACCERR : SEGV_MAPERR, |
598 | SEGV_ACCERR : SEGV_MAPERR; | 591 | (void __user *)addr, |
592 | inf->name); | ||
599 | } | 593 | } |
600 | 594 | ||
601 | __do_user_fault(&si, esr); | ||
602 | return 0; | 595 | return 0; |
603 | 596 | ||
604 | no_context: | 597 | no_context: |
@@ -631,8 +624,8 @@ static int do_bad(unsigned long addr, unsigned int esr, struct pt_regs *regs) | |||
631 | 624 | ||
632 | static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs) | 625 | static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs) |
633 | { | 626 | { |
634 | struct siginfo info; | ||
635 | const struct fault_info *inf; | 627 | const struct fault_info *inf; |
628 | void __user *siaddr; | ||
636 | 629 | ||
637 | inf = esr_to_fault_info(esr); | 630 | inf = esr_to_fault_info(esr); |
638 | 631 | ||
@@ -651,15 +644,11 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs) | |||
651 | nmi_exit(); | 644 | nmi_exit(); |
652 | } | 645 | } |
653 | 646 | ||
654 | clear_siginfo(&info); | ||
655 | info.si_signo = inf->sig; | ||
656 | info.si_errno = 0; | ||
657 | info.si_code = inf->code; | ||
658 | if (esr & ESR_ELx_FnV) | 647 | if (esr & ESR_ELx_FnV) |
659 | info.si_addr = NULL; | 648 | siaddr = NULL; |
660 | else | 649 | else |
661 | info.si_addr = (void __user *)addr; | 650 | siaddr = (void __user *)addr; |
662 | arm64_notify_die(inf->name, regs, &info, esr); | 651 | arm64_notify_die(inf->name, regs, inf->sig, inf->code, siaddr, esr); |
663 | 652 | ||
664 | return 0; | 653 | return 0; |
665 | } | 654 | } |
@@ -740,7 +729,6 @@ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr, | |||
740 | struct pt_regs *regs) | 729 | struct pt_regs *regs) |
741 | { | 730 | { |
742 | const struct fault_info *inf = esr_to_fault_info(esr); | 731 | const struct fault_info *inf = esr_to_fault_info(esr); |
743 | struct siginfo info; | ||
744 | 732 | ||
745 | if (!inf->fn(addr, esr, regs)) | 733 | if (!inf->fn(addr, esr, regs)) |
746 | return; | 734 | return; |
@@ -751,12 +739,8 @@ asmlinkage void __exception do_mem_abort(unsigned long addr, unsigned int esr, | |||
751 | show_pte(addr); | 739 | show_pte(addr); |
752 | } | 740 | } |
753 | 741 | ||
754 | clear_siginfo(&info); | 742 | arm64_notify_die(inf->name, regs, |
755 | info.si_signo = inf->sig; | 743 | inf->sig, inf->code, (void __user *)addr, esr); |
756 | info.si_errno = 0; | ||
757 | info.si_code = inf->code; | ||
758 | info.si_addr = (void __user *)addr; | ||
759 | arm64_notify_die(inf->name, regs, &info, esr); | ||
760 | } | 744 | } |
761 | 745 | ||
762 | asmlinkage void __exception do_el0_irq_bp_hardening(void) | 746 | asmlinkage void __exception do_el0_irq_bp_hardening(void) |
@@ -786,20 +770,14 @@ asmlinkage void __exception do_sp_pc_abort(unsigned long addr, | |||
786 | unsigned int esr, | 770 | unsigned int esr, |
787 | struct pt_regs *regs) | 771 | struct pt_regs *regs) |
788 | { | 772 | { |
789 | struct siginfo info; | ||
790 | |||
791 | if (user_mode(regs)) { | 773 | if (user_mode(regs)) { |
792 | if (instruction_pointer(regs) > TASK_SIZE) | 774 | if (instruction_pointer(regs) > TASK_SIZE) |
793 | arm64_apply_bp_hardening(); | 775 | arm64_apply_bp_hardening(); |
794 | local_daif_restore(DAIF_PROCCTX); | 776 | local_daif_restore(DAIF_PROCCTX); |
795 | } | 777 | } |
796 | 778 | ||
797 | clear_siginfo(&info); | 779 | arm64_notify_die("SP/PC alignment exception", regs, |
798 | info.si_signo = SIGBUS; | 780 | SIGBUS, BUS_ADRALN, (void __user *)addr, esr); |
799 | info.si_errno = 0; | ||
800 | info.si_code = BUS_ADRALN; | ||
801 | info.si_addr = (void __user *)addr; | ||
802 | arm64_notify_die("SP/PC alignment exception", regs, &info, esr); | ||
803 | } | 781 | } |
804 | 782 | ||
805 | int __init early_brk64(unsigned long addr, unsigned int esr, | 783 | int __init early_brk64(unsigned long addr, unsigned int esr, |
@@ -853,14 +831,8 @@ asmlinkage int __exception do_debug_exception(unsigned long addr, | |||
853 | if (!inf->fn(addr, esr, regs)) { | 831 | if (!inf->fn(addr, esr, regs)) { |
854 | rv = 1; | 832 | rv = 1; |
855 | } else { | 833 | } else { |
856 | struct siginfo info; | 834 | arm64_notify_die(inf->name, regs, |
857 | 835 | inf->sig, inf->code, (void __user *)addr, esr); | |
858 | clear_siginfo(&info); | ||
859 | info.si_signo = inf->sig; | ||
860 | info.si_errno = 0; | ||
861 | info.si_code = inf->code; | ||
862 | info.si_addr = (void __user *)addr; | ||
863 | arm64_notify_die(inf->name, regs, &info, esr); | ||
864 | rv = 0; | 836 | rv = 0; |
865 | } | 837 | } |
866 | 838 | ||
diff --git a/arch/ia64/include/uapi/asm/siginfo.h b/arch/ia64/include/uapi/asm/siginfo.h index 52b5af424511..796af1ccaa7e 100644 --- a/arch/ia64/include/uapi/asm/siginfo.h +++ b/arch/ia64/include/uapi/asm/siginfo.h | |||
@@ -9,8 +9,6 @@ | |||
9 | #define _UAPI_ASM_IA64_SIGINFO_H | 9 | #define _UAPI_ASM_IA64_SIGINFO_H |
10 | 10 | ||
11 | 11 | ||
12 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | ||
13 | |||
14 | #include <asm-generic/siginfo.h> | 12 | #include <asm-generic/siginfo.h> |
15 | 13 | ||
16 | #define si_imm _sifields._sigfault._imm /* as per UNIX SysV ABI spec */ | 14 | #define si_imm _sifields._sigfault._imm /* as per UNIX SysV ABI spec */ |
diff --git a/arch/ia64/kernel/brl_emu.c b/arch/ia64/kernel/brl_emu.c index a61f6c6a36f8..c0239bf77a09 100644 --- a/arch/ia64/kernel/brl_emu.c +++ b/arch/ia64/kernel/brl_emu.c | |||
@@ -58,11 +58,9 @@ ia64_emulate_brl (struct pt_regs *regs, unsigned long ar_ec) | |||
58 | unsigned long bundle[2]; | 58 | unsigned long bundle[2]; |
59 | unsigned long opcode, btype, qp, offset, cpl; | 59 | unsigned long opcode, btype, qp, offset, cpl; |
60 | unsigned long next_ip; | 60 | unsigned long next_ip; |
61 | struct siginfo siginfo; | ||
62 | struct illegal_op_return rv; | 61 | struct illegal_op_return rv; |
63 | long tmp_taken, unimplemented_address; | 62 | long tmp_taken, unimplemented_address; |
64 | 63 | ||
65 | clear_siginfo(&siginfo); | ||
66 | rv.fkt = (unsigned long) -1; | 64 | rv.fkt = (unsigned long) -1; |
67 | 65 | ||
68 | /* | 66 | /* |
@@ -198,39 +196,22 @@ ia64_emulate_brl (struct pt_regs *regs, unsigned long ar_ec) | |||
198 | * The target address contains unimplemented bits. | 196 | * The target address contains unimplemented bits. |
199 | */ | 197 | */ |
200 | printk(KERN_DEBUG "Woah! Unimplemented Instruction Address Trap!\n"); | 198 | printk(KERN_DEBUG "Woah! Unimplemented Instruction Address Trap!\n"); |
201 | siginfo.si_signo = SIGILL; | 199 | force_sig_fault(SIGILL, ILL_BADIADDR, (void __user *)NULL, |
202 | siginfo.si_errno = 0; | 200 | 0, 0, 0, current); |
203 | siginfo.si_flags = 0; | ||
204 | siginfo.si_isr = 0; | ||
205 | siginfo.si_imm = 0; | ||
206 | siginfo.si_code = ILL_BADIADDR; | ||
207 | force_sig_info(SIGILL, &siginfo, current); | ||
208 | } else if (ia64_psr(regs)->tb) { | 201 | } else if (ia64_psr(regs)->tb) { |
209 | /* | 202 | /* |
210 | * Branch Tracing is enabled. | 203 | * Branch Tracing is enabled. |
211 | * Force a taken branch signal. | 204 | * Force a taken branch signal. |
212 | */ | 205 | */ |
213 | siginfo.si_signo = SIGTRAP; | 206 | force_sig_fault(SIGTRAP, TRAP_BRANCH, (void __user *)NULL, |
214 | siginfo.si_errno = 0; | 207 | 0, 0, 0, current); |
215 | siginfo.si_code = TRAP_BRANCH; | ||
216 | siginfo.si_flags = 0; | ||
217 | siginfo.si_isr = 0; | ||
218 | siginfo.si_addr = 0; | ||
219 | siginfo.si_imm = 0; | ||
220 | force_sig_info(SIGTRAP, &siginfo, current); | ||
221 | } else if (ia64_psr(regs)->ss) { | 208 | } else if (ia64_psr(regs)->ss) { |
222 | /* | 209 | /* |
223 | * Single Step is enabled. | 210 | * Single Step is enabled. |
224 | * Force a trace signal. | 211 | * Force a trace signal. |
225 | */ | 212 | */ |
226 | siginfo.si_signo = SIGTRAP; | 213 | force_sig_fault(SIGTRAP, TRAP_TRACE, (void __user *)NULL, |
227 | siginfo.si_errno = 0; | 214 | 0, 0, 0, current); |
228 | siginfo.si_code = TRAP_TRACE; | ||
229 | siginfo.si_flags = 0; | ||
230 | siginfo.si_isr = 0; | ||
231 | siginfo.si_addr = 0; | ||
232 | siginfo.si_imm = 0; | ||
233 | force_sig_info(SIGTRAP, &siginfo, current); | ||
234 | } | 215 | } |
235 | return rv; | 216 | return rv; |
236 | } | 217 | } |
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index d1234a5ba4c5..9a960829a01d 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c | |||
@@ -110,7 +110,6 @@ ia64_rt_sigreturn (struct sigscratch *scr) | |||
110 | { | 110 | { |
111 | extern char ia64_strace_leave_kernel, ia64_leave_kernel; | 111 | extern char ia64_strace_leave_kernel, ia64_leave_kernel; |
112 | struct sigcontext __user *sc; | 112 | struct sigcontext __user *sc; |
113 | struct siginfo si; | ||
114 | sigset_t set; | 113 | sigset_t set; |
115 | long retval; | 114 | long retval; |
116 | 115 | ||
@@ -153,14 +152,7 @@ ia64_rt_sigreturn (struct sigscratch *scr) | |||
153 | return retval; | 152 | return retval; |
154 | 153 | ||
155 | give_sigsegv: | 154 | give_sigsegv: |
156 | clear_siginfo(&si); | 155 | force_sig(SIGSEGV, current); |
157 | si.si_signo = SIGSEGV; | ||
158 | si.si_errno = 0; | ||
159 | si.si_code = SI_KERNEL; | ||
160 | si.si_pid = task_pid_vnr(current); | ||
161 | si.si_uid = from_kuid_munged(current_user_ns(), current_uid()); | ||
162 | si.si_addr = sc; | ||
163 | force_sig_info(SIGSEGV, &si, current); | ||
164 | return retval; | 156 | return retval; |
165 | } | 157 | } |
166 | 158 | ||
@@ -232,37 +224,6 @@ rbs_on_sig_stack (unsigned long bsp) | |||
232 | } | 224 | } |
233 | 225 | ||
234 | static long | 226 | static long |
235 | force_sigsegv_info (int sig, void __user *addr) | ||
236 | { | ||
237 | unsigned long flags; | ||
238 | struct siginfo si; | ||
239 | |||
240 | clear_siginfo(&si); | ||
241 | if (sig == SIGSEGV) { | ||
242 | /* | ||
243 | * Acquiring siglock around the sa_handler-update is almost | ||
244 | * certainly overkill, but this isn't a | ||
245 | * performance-critical path and I'd rather play it safe | ||
246 | * here than having to debug a nasty race if and when | ||
247 | * something changes in kernel/signal.c that would make it | ||
248 | * no longer safe to modify sa_handler without holding the | ||
249 | * lock. | ||
250 | */ | ||
251 | spin_lock_irqsave(¤t->sighand->siglock, flags); | ||
252 | current->sighand->action[sig - 1].sa.sa_handler = SIG_DFL; | ||
253 | spin_unlock_irqrestore(¤t->sighand->siglock, flags); | ||
254 | } | ||
255 | si.si_signo = SIGSEGV; | ||
256 | si.si_errno = 0; | ||
257 | si.si_code = SI_KERNEL; | ||
258 | si.si_pid = task_pid_vnr(current); | ||
259 | si.si_uid = from_kuid_munged(current_user_ns(), current_uid()); | ||
260 | si.si_addr = addr; | ||
261 | force_sig_info(SIGSEGV, &si, current); | ||
262 | return 1; | ||
263 | } | ||
264 | |||
265 | static long | ||
266 | setup_frame(struct ksignal *ksig, sigset_t *set, struct sigscratch *scr) | 227 | setup_frame(struct ksignal *ksig, sigset_t *set, struct sigscratch *scr) |
267 | { | 228 | { |
268 | extern char __kernel_sigtramp[]; | 229 | extern char __kernel_sigtramp[]; |
@@ -295,15 +256,18 @@ setup_frame(struct ksignal *ksig, sigset_t *set, struct sigscratch *scr) | |||
295 | * instead so we will die with SIGSEGV. | 256 | * instead so we will die with SIGSEGV. |
296 | */ | 257 | */ |
297 | check_sp = (new_sp - sizeof(*frame)) & -STACK_ALIGN; | 258 | check_sp = (new_sp - sizeof(*frame)) & -STACK_ALIGN; |
298 | if (!likely(on_sig_stack(check_sp))) | 259 | if (!likely(on_sig_stack(check_sp))) { |
299 | return force_sigsegv_info(ksig->sig, (void __user *) | 260 | force_sigsegv(ksig->sig, current); |
300 | check_sp); | 261 | return 1; |
262 | } | ||
301 | } | 263 | } |
302 | } | 264 | } |
303 | frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN); | 265 | frame = (void __user *) ((new_sp - sizeof(*frame)) & -STACK_ALIGN); |
304 | 266 | ||
305 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 267 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) { |
306 | return force_sigsegv_info(ksig->sig, frame); | 268 | force_sigsegv(ksig->sig, current); |
269 | return 1; | ||
270 | } | ||
307 | 271 | ||
308 | err = __put_user(ksig->sig, &frame->arg0); | 272 | err = __put_user(ksig->sig, &frame->arg0); |
309 | err |= __put_user(&frame->info, &frame->arg1); | 273 | err |= __put_user(&frame->info, &frame->arg1); |
@@ -317,8 +281,10 @@ setup_frame(struct ksignal *ksig, sigset_t *set, struct sigscratch *scr) | |||
317 | err |= __save_altstack(&frame->sc.sc_stack, scr->pt.r12); | 281 | err |= __save_altstack(&frame->sc.sc_stack, scr->pt.r12); |
318 | err |= setup_sigcontext(&frame->sc, set, scr); | 282 | err |= setup_sigcontext(&frame->sc, set, scr); |
319 | 283 | ||
320 | if (unlikely(err)) | 284 | if (unlikely(err)) { |
321 | return force_sigsegv_info(ksig->sig, frame); | 285 | force_sigsegv(ksig->sig, current); |
286 | return 1; | ||
287 | } | ||
322 | 288 | ||
323 | scr->pt.r12 = (unsigned long) frame - 16; /* new stack pointer */ | 289 | scr->pt.r12 = (unsigned long) frame - 16; /* new stack pointer */ |
324 | scr->pt.ar_fpsr = FPSR_DEFAULT; /* reset fpsr for signal handler */ | 290 | scr->pt.ar_fpsr = FPSR_DEFAULT; /* reset fpsr for signal handler */ |
diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index c6f4932073a1..85d8616ac4f6 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c | |||
@@ -100,16 +100,8 @@ die_if_kernel (char *str, struct pt_regs *regs, long err) | |||
100 | void | 100 | void |
101 | __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) | 101 | __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) |
102 | { | 102 | { |
103 | siginfo_t siginfo; | ||
104 | int sig, code; | 103 | int sig, code; |
105 | 104 | ||
106 | /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */ | ||
107 | clear_siginfo(&siginfo); | ||
108 | siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); | ||
109 | siginfo.si_imm = break_num; | ||
110 | siginfo.si_flags = 0; /* clear __ISR_VALID */ | ||
111 | siginfo.si_isr = 0; | ||
112 | |||
113 | switch (break_num) { | 105 | switch (break_num) { |
114 | case 0: /* unknown error (used by GCC for __builtin_abort()) */ | 106 | case 0: /* unknown error (used by GCC for __builtin_abort()) */ |
115 | if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP) | 107 | if (notify_die(DIE_BREAK, "break 0", regs, break_num, TRAP_BRKPT, SIGTRAP) |
@@ -182,10 +174,9 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) | |||
182 | sig = SIGTRAP; code = TRAP_BRKPT; | 174 | sig = SIGTRAP; code = TRAP_BRKPT; |
183 | } | 175 | } |
184 | } | 176 | } |
185 | siginfo.si_signo = sig; | 177 | force_sig_fault(sig, code, |
186 | siginfo.si_errno = 0; | 178 | (void __user *) (regs->cr_iip + ia64_psr(regs)->ri), |
187 | siginfo.si_code = code; | 179 | break_num, 0 /* clear __ISR_VALID */, 0, current); |
188 | force_sig_info(sig, &siginfo, current); | ||
189 | } | 180 | } |
190 | 181 | ||
191 | /* | 182 | /* |
@@ -344,30 +335,25 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr) | |||
344 | printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n"); | 335 | printk(KERN_ERR "handle_fpu_swa: fp_emulate() returned -1\n"); |
345 | return -1; | 336 | return -1; |
346 | } else { | 337 | } else { |
347 | struct siginfo siginfo; | ||
348 | |||
349 | /* is next instruction a trap? */ | 338 | /* is next instruction a trap? */ |
339 | int si_code; | ||
340 | |||
350 | if (exception & 2) { | 341 | if (exception & 2) { |
351 | ia64_increment_ip(regs); | 342 | ia64_increment_ip(regs); |
352 | } | 343 | } |
353 | clear_siginfo(&siginfo); | 344 | si_code = FPE_FLTUNK; /* default code */ |
354 | siginfo.si_signo = SIGFPE; | ||
355 | siginfo.si_errno = 0; | ||
356 | siginfo.si_code = FPE_FLTUNK; /* default code */ | ||
357 | siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); | ||
358 | if (isr & 0x11) { | 345 | if (isr & 0x11) { |
359 | siginfo.si_code = FPE_FLTINV; | 346 | si_code = FPE_FLTINV; |
360 | } else if (isr & 0x22) { | 347 | } else if (isr & 0x22) { |
361 | /* denormal operand gets the same si_code as underflow | 348 | /* denormal operand gets the same si_code as underflow |
362 | * see arch/i386/kernel/traps.c:math_error() */ | 349 | * see arch/i386/kernel/traps.c:math_error() */ |
363 | siginfo.si_code = FPE_FLTUND; | 350 | si_code = FPE_FLTUND; |
364 | } else if (isr & 0x44) { | 351 | } else if (isr & 0x44) { |
365 | siginfo.si_code = FPE_FLTDIV; | 352 | si_code = FPE_FLTDIV; |
366 | } | 353 | } |
367 | siginfo.si_isr = isr; | 354 | force_sig_fault(SIGFPE, si_code, |
368 | siginfo.si_flags = __ISR_VALID; | 355 | (void __user *) (regs->cr_iip + ia64_psr(regs)->ri), |
369 | siginfo.si_imm = 0; | 356 | 0, __ISR_VALID, isr, current); |
370 | force_sig_info(SIGFPE, &siginfo, current); | ||
371 | } | 357 | } |
372 | } else { | 358 | } else { |
373 | if (exception == -1) { | 359 | if (exception == -1) { |
@@ -375,24 +361,19 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr) | |||
375 | return -1; | 361 | return -1; |
376 | } else if (exception != 0) { | 362 | } else if (exception != 0) { |
377 | /* raise exception */ | 363 | /* raise exception */ |
378 | struct siginfo siginfo; | 364 | int si_code; |
379 | 365 | ||
380 | clear_siginfo(&siginfo); | 366 | si_code = FPE_FLTUNK; /* default code */ |
381 | siginfo.si_signo = SIGFPE; | ||
382 | siginfo.si_errno = 0; | ||
383 | siginfo.si_code = FPE_FLTUNK; /* default code */ | ||
384 | siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); | ||
385 | if (isr & 0x880) { | 367 | if (isr & 0x880) { |
386 | siginfo.si_code = FPE_FLTOVF; | 368 | si_code = FPE_FLTOVF; |
387 | } else if (isr & 0x1100) { | 369 | } else if (isr & 0x1100) { |
388 | siginfo.si_code = FPE_FLTUND; | 370 | si_code = FPE_FLTUND; |
389 | } else if (isr & 0x2200) { | 371 | } else if (isr & 0x2200) { |
390 | siginfo.si_code = FPE_FLTRES; | 372 | si_code = FPE_FLTRES; |
391 | } | 373 | } |
392 | siginfo.si_isr = isr; | 374 | force_sig_fault(SIGFPE, si_code, |
393 | siginfo.si_flags = __ISR_VALID; | 375 | (void __user *) (regs->cr_iip + ia64_psr(regs)->ri), |
394 | siginfo.si_imm = 0; | 376 | 0, __ISR_VALID, isr, current); |
395 | force_sig_info(SIGFPE, &siginfo, current); | ||
396 | } | 377 | } |
397 | } | 378 | } |
398 | return 0; | 379 | return 0; |
@@ -408,7 +389,6 @@ ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3, | |||
408 | struct pt_regs regs) | 389 | struct pt_regs regs) |
409 | { | 390 | { |
410 | struct illegal_op_return rv; | 391 | struct illegal_op_return rv; |
411 | struct siginfo si; | ||
412 | char buf[128]; | 392 | char buf[128]; |
413 | 393 | ||
414 | #ifdef CONFIG_IA64_BRL_EMU | 394 | #ifdef CONFIG_IA64_BRL_EMU |
@@ -426,11 +406,9 @@ ia64_illegal_op_fault (unsigned long ec, long arg1, long arg2, long arg3, | |||
426 | if (die_if_kernel(buf, ®s, 0)) | 406 | if (die_if_kernel(buf, ®s, 0)) |
427 | return rv; | 407 | return rv; |
428 | 408 | ||
429 | clear_siginfo(&si); | 409 | force_sig_fault(SIGILL, ILL_ILLOPC, |
430 | si.si_signo = SIGILL; | 410 | (void __user *) (regs.cr_iip + ia64_psr(®s)->ri), |
431 | si.si_code = ILL_ILLOPC; | 411 | 0, 0, 0, current); |
432 | si.si_addr = (void __user *) (regs.cr_iip + ia64_psr(®s)->ri); | ||
433 | force_sig_info(SIGILL, &si, current); | ||
434 | return rv; | 412 | return rv; |
435 | } | 413 | } |
436 | 414 | ||
@@ -441,7 +419,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
441 | { | 419 | { |
442 | unsigned long code, error = isr, iip; | 420 | unsigned long code, error = isr, iip; |
443 | char buf[128]; | 421 | char buf[128]; |
444 | int result, sig; | 422 | int result, sig, si_code; |
445 | static const char *reason[] = { | 423 | static const char *reason[] = { |
446 | "IA-64 Illegal Operation fault", | 424 | "IA-64 Illegal Operation fault", |
447 | "IA-64 Privileged Operation fault", | 425 | "IA-64 Privileged Operation fault", |
@@ -490,7 +468,6 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
490 | 468 | ||
491 | case 26: /* NaT Consumption */ | 469 | case 26: /* NaT Consumption */ |
492 | if (user_mode(®s)) { | 470 | if (user_mode(®s)) { |
493 | struct siginfo siginfo; | ||
494 | void __user *addr; | 471 | void __user *addr; |
495 | 472 | ||
496 | if (((isr >> 4) & 0xf) == 2) { | 473 | if (((isr >> 4) & 0xf) == 2) { |
@@ -505,15 +482,8 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
505 | addr = (void __user *) (regs.cr_iip | 482 | addr = (void __user *) (regs.cr_iip |
506 | + ia64_psr(®s)->ri); | 483 | + ia64_psr(®s)->ri); |
507 | } | 484 | } |
508 | clear_siginfo(&siginfo); | 485 | force_sig_fault(sig, code, addr, |
509 | siginfo.si_signo = sig; | 486 | vector, __ISR_VALID, isr, current); |
510 | siginfo.si_code = code; | ||
511 | siginfo.si_errno = 0; | ||
512 | siginfo.si_addr = addr; | ||
513 | siginfo.si_imm = vector; | ||
514 | siginfo.si_flags = __ISR_VALID; | ||
515 | siginfo.si_isr = isr; | ||
516 | force_sig_info(sig, &siginfo, current); | ||
517 | return; | 487 | return; |
518 | } else if (ia64_done_with_exception(®s)) | 488 | } else if (ia64_done_with_exception(®s)) |
519 | return; | 489 | return; |
@@ -522,17 +492,8 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
522 | 492 | ||
523 | case 31: /* Unsupported Data Reference */ | 493 | case 31: /* Unsupported Data Reference */ |
524 | if (user_mode(®s)) { | 494 | if (user_mode(®s)) { |
525 | struct siginfo siginfo; | 495 | force_sig_fault(SIGILL, ILL_ILLOPN, (void __user *) iip, |
526 | 496 | vector, __ISR_VALID, isr, current); | |
527 | clear_siginfo(&siginfo); | ||
528 | siginfo.si_signo = SIGILL; | ||
529 | siginfo.si_code = ILL_ILLOPN; | ||
530 | siginfo.si_errno = 0; | ||
531 | siginfo.si_addr = (void __user *) iip; | ||
532 | siginfo.si_imm = vector; | ||
533 | siginfo.si_flags = __ISR_VALID; | ||
534 | siginfo.si_isr = isr; | ||
535 | force_sig_info(SIGILL, &siginfo, current); | ||
536 | return; | 497 | return; |
537 | } | 498 | } |
538 | sprintf(buf, "Unsupported data reference"); | 499 | sprintf(buf, "Unsupported data reference"); |
@@ -541,10 +502,6 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
541 | case 29: /* Debug */ | 502 | case 29: /* Debug */ |
542 | case 35: /* Taken Branch Trap */ | 503 | case 35: /* Taken Branch Trap */ |
543 | case 36: /* Single Step Trap */ | 504 | case 36: /* Single Step Trap */ |
544 | { | ||
545 | struct siginfo siginfo; | ||
546 | |||
547 | clear_siginfo(&siginfo); | ||
548 | if (fsys_mode(current, ®s)) { | 505 | if (fsys_mode(current, ®s)) { |
549 | extern char __kernel_syscall_via_break[]; | 506 | extern char __kernel_syscall_via_break[]; |
550 | /* | 507 | /* |
@@ -568,7 +525,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
568 | switch (vector) { | 525 | switch (vector) { |
569 | default: | 526 | default: |
570 | case 29: | 527 | case 29: |
571 | siginfo.si_code = TRAP_HWBKPT; | 528 | si_code = TRAP_HWBKPT; |
572 | #ifdef CONFIG_ITANIUM | 529 | #ifdef CONFIG_ITANIUM |
573 | /* | 530 | /* |
574 | * Erratum 10 (IFA may contain incorrect address) now has | 531 | * Erratum 10 (IFA may contain incorrect address) now has |
@@ -578,37 +535,22 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
578 | ifa = regs.cr_iip; | 535 | ifa = regs.cr_iip; |
579 | #endif | 536 | #endif |
580 | break; | 537 | break; |
581 | case 35: siginfo.si_code = TRAP_BRANCH; ifa = 0; break; | 538 | case 35: si_code = TRAP_BRANCH; ifa = 0; break; |
582 | case 36: siginfo.si_code = TRAP_TRACE; ifa = 0; break; | 539 | case 36: si_code = TRAP_TRACE; ifa = 0; break; |
583 | } | 540 | } |
584 | if (notify_die(DIE_FAULT, "ia64_fault", ®s, vector, siginfo.si_code, SIGTRAP) | 541 | if (notify_die(DIE_FAULT, "ia64_fault", ®s, vector, si_code, SIGTRAP) |
585 | == NOTIFY_STOP) | 542 | == NOTIFY_STOP) |
586 | return; | 543 | return; |
587 | siginfo.si_signo = SIGTRAP; | 544 | force_sig_fault(SIGTRAP, si_code, (void __user *) ifa, |
588 | siginfo.si_errno = 0; | 545 | 0, __ISR_VALID, isr, current); |
589 | siginfo.si_addr = (void __user *) ifa; | ||
590 | siginfo.si_imm = 0; | ||
591 | siginfo.si_flags = __ISR_VALID; | ||
592 | siginfo.si_isr = isr; | ||
593 | force_sig_info(SIGTRAP, &siginfo, current); | ||
594 | return; | 546 | return; |
595 | } | ||
596 | 547 | ||
597 | case 32: /* fp fault */ | 548 | case 32: /* fp fault */ |
598 | case 33: /* fp trap */ | 549 | case 33: /* fp trap */ |
599 | result = handle_fpu_swa((vector == 32) ? 1 : 0, ®s, isr); | 550 | result = handle_fpu_swa((vector == 32) ? 1 : 0, ®s, isr); |
600 | if ((result < 0) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) { | 551 | if ((result < 0) || (current->thread.flags & IA64_THREAD_FPEMU_SIGFPE)) { |
601 | struct siginfo siginfo; | 552 | force_sig_fault(SIGFPE, FPE_FLTINV, (void __user *) iip, |
602 | 553 | 0, __ISR_VALID, isr, current); | |
603 | clear_siginfo(&siginfo); | ||
604 | siginfo.si_signo = SIGFPE; | ||
605 | siginfo.si_errno = 0; | ||
606 | siginfo.si_code = FPE_FLTINV; | ||
607 | siginfo.si_addr = (void __user *) iip; | ||
608 | siginfo.si_flags = __ISR_VALID; | ||
609 | siginfo.si_isr = isr; | ||
610 | siginfo.si_imm = 0; | ||
611 | force_sig_info(SIGFPE, &siginfo, current); | ||
612 | } | 554 | } |
613 | return; | 555 | return; |
614 | 556 | ||
@@ -634,17 +576,9 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, | |||
634 | } else { | 576 | } else { |
635 | /* Unimplemented Instr. Address Trap */ | 577 | /* Unimplemented Instr. Address Trap */ |
636 | if (user_mode(®s)) { | 578 | if (user_mode(®s)) { |
637 | struct siginfo siginfo; | 579 | force_sig_fault(SIGILL, ILL_BADIADDR, |
638 | 580 | (void __user *) iip, | |
639 | clear_siginfo(&siginfo); | 581 | 0, 0, 0, current); |
640 | siginfo.si_signo = SIGILL; | ||
641 | siginfo.si_code = ILL_BADIADDR; | ||
642 | siginfo.si_errno = 0; | ||
643 | siginfo.si_flags = 0; | ||
644 | siginfo.si_isr = 0; | ||
645 | siginfo.si_imm = 0; | ||
646 | siginfo.si_addr = (void __user *) iip; | ||
647 | force_sig_info(SIGILL, &siginfo, current); | ||
648 | return; | 582 | return; |
649 | } | 583 | } |
650 | sprintf(buf, "Unimplemented Instruction Address fault"); | 584 | sprintf(buf, "Unimplemented Instruction Address fault"); |
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c index e309f9859acc..a167a3824b35 100644 --- a/arch/ia64/kernel/unaligned.c +++ b/arch/ia64/kernel/unaligned.c | |||
@@ -1298,7 +1298,6 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs) | |||
1298 | mm_segment_t old_fs = get_fs(); | 1298 | mm_segment_t old_fs = get_fs(); |
1299 | unsigned long bundle[2]; | 1299 | unsigned long bundle[2]; |
1300 | unsigned long opcode; | 1300 | unsigned long opcode; |
1301 | struct siginfo si; | ||
1302 | const struct exception_table_entry *eh = NULL; | 1301 | const struct exception_table_entry *eh = NULL; |
1303 | union { | 1302 | union { |
1304 | unsigned long l; | 1303 | unsigned long l; |
@@ -1537,14 +1536,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs) | |||
1537 | /* NOT_REACHED */ | 1536 | /* NOT_REACHED */ |
1538 | } | 1537 | } |
1539 | force_sigbus: | 1538 | force_sigbus: |
1540 | clear_siginfo(&si); | 1539 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *) ifa, |
1541 | si.si_signo = SIGBUS; | 1540 | 0, 0, 0, current); |
1542 | si.si_errno = 0; | ||
1543 | si.si_code = BUS_ADRALN; | ||
1544 | si.si_addr = (void __user *) ifa; | ||
1545 | si.si_flags = 0; | ||
1546 | si.si_isr = 0; | ||
1547 | si.si_imm = 0; | ||
1548 | force_sig_info(SIGBUS, &si, current); | ||
1549 | goto done; | 1541 | goto done; |
1550 | } | 1542 | } |
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index a9d55ad8d67b..5baeb022f474 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c | |||
@@ -248,16 +248,8 @@ retry: | |||
248 | return; | 248 | return; |
249 | } | 249 | } |
250 | if (user_mode(regs)) { | 250 | if (user_mode(regs)) { |
251 | struct siginfo si; | 251 | force_sig_fault(signal, code, (void __user *) address, |
252 | 252 | 0, __ISR_VALID, isr, current); | |
253 | clear_siginfo(&si); | ||
254 | si.si_signo = signal; | ||
255 | si.si_errno = 0; | ||
256 | si.si_code = code; | ||
257 | si.si_addr = (void __user *) address; | ||
258 | si.si_isr = isr; | ||
259 | si.si_flags = __ISR_VALID; | ||
260 | force_sig_info(signal, &si, current); | ||
261 | return; | 253 | return; |
262 | } | 254 | } |
263 | 255 | ||
diff --git a/arch/mips/include/uapi/asm/siginfo.h b/arch/mips/include/uapi/asm/siginfo.h index 262504bd59a5..c34c7eef0a1c 100644 --- a/arch/mips/include/uapi/asm/siginfo.h +++ b/arch/mips/include/uapi/asm/siginfo.h | |||
@@ -14,17 +14,6 @@ | |||
14 | #define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(long) + 2*sizeof(int)) | 14 | #define __ARCH_SIGEV_PREAMBLE_SIZE (sizeof(long) + 2*sizeof(int)) |
15 | #undef __ARCH_SI_TRAPNO /* exception code needs to fill this ... */ | 15 | #undef __ARCH_SI_TRAPNO /* exception code needs to fill this ... */ |
16 | 16 | ||
17 | /* | ||
18 | * Careful to keep union _sifields from shifting ... | ||
19 | */ | ||
20 | #if _MIPS_SZLONG == 32 | ||
21 | #define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int)) | ||
22 | #elif _MIPS_SZLONG == 64 | ||
23 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | ||
24 | #else | ||
25 | #error _MIPS_SZLONG neither 32 nor 64 | ||
26 | #endif | ||
27 | |||
28 | #define __ARCH_HAS_SWAPPED_SIGINFO | 17 | #define __ARCH_HAS_SWAPPED_SIGINFO |
29 | 18 | ||
30 | #include <asm-generic/siginfo.h> | 19 | #include <asm-generic/siginfo.h> |
diff --git a/arch/parisc/include/uapi/asm/Kbuild b/arch/parisc/include/uapi/asm/Kbuild index 286ef5a5904b..adb5c64831c7 100644 --- a/arch/parisc/include/uapi/asm/Kbuild +++ b/arch/parisc/include/uapi/asm/Kbuild | |||
@@ -7,3 +7,4 @@ generic-y += kvm_para.h | |||
7 | generic-y += param.h | 7 | generic-y += param.h |
8 | generic-y += poll.h | 8 | generic-y += poll.h |
9 | generic-y += resource.h | 9 | generic-y += resource.h |
10 | generic-y += siginfo.h | ||
diff --git a/arch/parisc/include/uapi/asm/siginfo.h b/arch/parisc/include/uapi/asm/siginfo.h deleted file mode 100644 index 4a1062e05aaf..000000000000 --- a/arch/parisc/include/uapi/asm/siginfo.h +++ /dev/null | |||
@@ -1,11 +0,0 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | ||
2 | #ifndef _PARISC_SIGINFO_H | ||
3 | #define _PARISC_SIGINFO_H | ||
4 | |||
5 | #if defined(__LP64__) | ||
6 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | ||
7 | #endif | ||
8 | |||
9 | #include <asm-generic/siginfo.h> | ||
10 | |||
11 | #endif | ||
diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h index fd06dbe7d7d3..fed7e6241349 100644 --- a/arch/powerpc/include/asm/bug.h +++ b/arch/powerpc/include/asm/bug.h | |||
@@ -133,7 +133,7 @@ struct pt_regs; | |||
133 | extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long); | 133 | extern int do_page_fault(struct pt_regs *, unsigned long, unsigned long); |
134 | extern void bad_page_fault(struct pt_regs *, unsigned long, int); | 134 | extern void bad_page_fault(struct pt_regs *, unsigned long, int); |
135 | extern void _exception(int, struct pt_regs *, int, unsigned long); | 135 | extern void _exception(int, struct pt_regs *, int, unsigned long); |
136 | extern void _exception_pkey(int, struct pt_regs *, int, unsigned long, int); | 136 | extern void _exception_pkey(struct pt_regs *, unsigned long, int); |
137 | extern void die(const char *, struct pt_regs *, long); | 137 | extern void die(const char *, struct pt_regs *, long); |
138 | extern bool die_will_crash(void); | 138 | extern bool die_will_crash(void); |
139 | extern void panic_flush_kmsg_start(void); | 139 | extern void panic_flush_kmsg_start(void); |
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h index 447cbd1bee99..5b480e1d5909 100644 --- a/arch/powerpc/include/asm/ptrace.h +++ b/arch/powerpc/include/asm/ptrace.h | |||
@@ -149,7 +149,7 @@ do { \ | |||
149 | 149 | ||
150 | #define arch_has_single_step() (1) | 150 | #define arch_has_single_step() (1) |
151 | #define arch_has_block_step() (!cpu_has_feature(CPU_FTR_601)) | 151 | #define arch_has_block_step() (!cpu_has_feature(CPU_FTR_601)) |
152 | #define ARCH_HAS_USER_SINGLE_STEP_INFO | 152 | #define ARCH_HAS_USER_SINGLE_STEP_REPORT |
153 | 153 | ||
154 | /* | 154 | /* |
155 | * kprobe-based event tracer support | 155 | * kprobe-based event tracer support |
diff --git a/arch/powerpc/include/uapi/asm/Kbuild b/arch/powerpc/include/uapi/asm/Kbuild index 1a6ed5919ffd..a658091a19f9 100644 --- a/arch/powerpc/include/uapi/asm/Kbuild +++ b/arch/powerpc/include/uapi/asm/Kbuild | |||
@@ -7,3 +7,4 @@ generic-y += poll.h | |||
7 | generic-y += resource.h | 7 | generic-y += resource.h |
8 | generic-y += sockios.h | 8 | generic-y += sockios.h |
9 | generic-y += statfs.h | 9 | generic-y += statfs.h |
10 | generic-y += siginfo.h | ||
diff --git a/arch/powerpc/include/uapi/asm/siginfo.h b/arch/powerpc/include/uapi/asm/siginfo.h deleted file mode 100644 index 1d51d9b88221..000000000000 --- a/arch/powerpc/include/uapi/asm/siginfo.h +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ | ||
2 | #ifndef _ASM_POWERPC_SIGINFO_H | ||
3 | #define _ASM_POWERPC_SIGINFO_H | ||
4 | |||
5 | /* | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #ifdef __powerpc64__ | ||
13 | # define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | ||
14 | #endif | ||
15 | |||
16 | #include <asm-generic/siginfo.h> | ||
17 | |||
18 | #endif /* _ASM_POWERPC_SIGINFO_H */ | ||
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index bb6ac471a784..5d983d8bac27 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -620,8 +620,6 @@ void do_send_trap(struct pt_regs *regs, unsigned long address, | |||
620 | void do_break (struct pt_regs *regs, unsigned long address, | 620 | void do_break (struct pt_regs *regs, unsigned long address, |
621 | unsigned long error_code) | 621 | unsigned long error_code) |
622 | { | 622 | { |
623 | siginfo_t info; | ||
624 | |||
625 | current->thread.trap_nr = TRAP_HWBKPT; | 623 | current->thread.trap_nr = TRAP_HWBKPT; |
626 | if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code, | 624 | if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code, |
627 | 11, SIGSEGV) == NOTIFY_STOP) | 625 | 11, SIGSEGV) == NOTIFY_STOP) |
@@ -634,12 +632,7 @@ void do_break (struct pt_regs *regs, unsigned long address, | |||
634 | hw_breakpoint_disable(); | 632 | hw_breakpoint_disable(); |
635 | 633 | ||
636 | /* Deliver the signal to userspace */ | 634 | /* Deliver the signal to userspace */ |
637 | clear_siginfo(&info); | 635 | force_sig_fault(SIGTRAP, TRAP_HWBKPT, (void __user *)address, current); |
638 | info.si_signo = SIGTRAP; | ||
639 | info.si_errno = 0; | ||
640 | info.si_code = TRAP_HWBKPT; | ||
641 | info.si_addr = (void __user *)address; | ||
642 | force_sig_info(SIGTRAP, &info, current); | ||
643 | } | 636 | } |
644 | #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ | 637 | #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ |
645 | 638 | ||
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index c85adb858271..ab1bd06d7c44 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c | |||
@@ -307,12 +307,9 @@ void die(const char *str, struct pt_regs *regs, long err) | |||
307 | } | 307 | } |
308 | NOKPROBE_SYMBOL(die); | 308 | NOKPROBE_SYMBOL(die); |
309 | 309 | ||
310 | void user_single_step_siginfo(struct task_struct *tsk, | 310 | void user_single_step_report(struct pt_regs *regs) |
311 | struct pt_regs *regs, siginfo_t *info) | ||
312 | { | 311 | { |
313 | info->si_signo = SIGTRAP; | 312 | force_sig_fault(SIGTRAP, TRAP_TRACE, (void __user *)regs->nip, current); |
314 | info->si_code = TRAP_TRACE; | ||
315 | info->si_addr = (void __user *)regs->nip; | ||
316 | } | 313 | } |
317 | 314 | ||
318 | static void show_signal_msg(int signr, struct pt_regs *regs, int code, | 315 | static void show_signal_msg(int signr, struct pt_regs *regs, int code, |
@@ -341,14 +338,12 @@ static void show_signal_msg(int signr, struct pt_regs *regs, int code, | |||
341 | show_user_instructions(regs); | 338 | show_user_instructions(regs); |
342 | } | 339 | } |
343 | 340 | ||
344 | void _exception_pkey(int signr, struct pt_regs *regs, int code, | 341 | static bool exception_common(int signr, struct pt_regs *regs, int code, |
345 | unsigned long addr, int key) | 342 | unsigned long addr) |
346 | { | 343 | { |
347 | siginfo_t info; | ||
348 | |||
349 | if (!user_mode(regs)) { | 344 | if (!user_mode(regs)) { |
350 | die("Exception in kernel mode", regs, signr); | 345 | die("Exception in kernel mode", regs, signr); |
351 | return; | 346 | return false; |
352 | } | 347 | } |
353 | 348 | ||
354 | show_signal_msg(signr, regs, code, addr); | 349 | show_signal_msg(signr, regs, code, addr); |
@@ -364,18 +359,23 @@ void _exception_pkey(int signr, struct pt_regs *regs, int code, | |||
364 | */ | 359 | */ |
365 | thread_pkey_regs_save(¤t->thread); | 360 | thread_pkey_regs_save(¤t->thread); |
366 | 361 | ||
367 | clear_siginfo(&info); | 362 | return true; |
368 | info.si_signo = signr; | 363 | } |
369 | info.si_code = code; | 364 | |
370 | info.si_addr = (void __user *) addr; | 365 | void _exception_pkey(struct pt_regs *regs, unsigned long addr, int key) |
371 | info.si_pkey = key; | 366 | { |
367 | if (!exception_common(SIGSEGV, regs, SEGV_PKUERR, addr)) | ||
368 | return; | ||
372 | 369 | ||
373 | force_sig_info(signr, &info, current); | 370 | force_sig_pkuerr((void __user *) addr, key); |
374 | } | 371 | } |
375 | 372 | ||
376 | void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) | 373 | void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) |
377 | { | 374 | { |
378 | _exception_pkey(signr, regs, code, addr, 0); | 375 | if (!exception_common(signr, regs, code, addr)) |
376 | return; | ||
377 | |||
378 | force_sig_fault(signr, code, (void __user *)addr, current); | ||
379 | } | 379 | } |
380 | 380 | ||
381 | void system_reset_exception(struct pt_regs *regs) | 381 | void system_reset_exception(struct pt_regs *regs) |
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index d51cf5f4e45e..1697e903bbf2 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c | |||
@@ -103,8 +103,7 @@ static bool store_updates_sp(unsigned int inst) | |||
103 | */ | 103 | */ |
104 | 104 | ||
105 | static int | 105 | static int |
106 | __bad_area_nosemaphore(struct pt_regs *regs, unsigned long address, int si_code, | 106 | __bad_area_nosemaphore(struct pt_regs *regs, unsigned long address, int si_code) |
107 | int pkey) | ||
108 | { | 107 | { |
109 | /* | 108 | /* |
110 | * If we are in kernel mode, bail out with a SEGV, this will | 109 | * If we are in kernel mode, bail out with a SEGV, this will |
@@ -114,18 +113,17 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long address, int si_code, | |||
114 | if (!user_mode(regs)) | 113 | if (!user_mode(regs)) |
115 | return SIGSEGV; | 114 | return SIGSEGV; |
116 | 115 | ||
117 | _exception_pkey(SIGSEGV, regs, si_code, address, pkey); | 116 | _exception(SIGSEGV, regs, si_code, address); |
118 | 117 | ||
119 | return 0; | 118 | return 0; |
120 | } | 119 | } |
121 | 120 | ||
122 | static noinline int bad_area_nosemaphore(struct pt_regs *regs, unsigned long address) | 121 | static noinline int bad_area_nosemaphore(struct pt_regs *regs, unsigned long address) |
123 | { | 122 | { |
124 | return __bad_area_nosemaphore(regs, address, SEGV_MAPERR, 0); | 123 | return __bad_area_nosemaphore(regs, address, SEGV_MAPERR); |
125 | } | 124 | } |
126 | 125 | ||
127 | static int __bad_area(struct pt_regs *regs, unsigned long address, int si_code, | 126 | static int __bad_area(struct pt_regs *regs, unsigned long address, int si_code) |
128 | int pkey) | ||
129 | { | 127 | { |
130 | struct mm_struct *mm = current->mm; | 128 | struct mm_struct *mm = current->mm; |
131 | 129 | ||
@@ -135,54 +133,61 @@ static int __bad_area(struct pt_regs *regs, unsigned long address, int si_code, | |||
135 | */ | 133 | */ |
136 | up_read(&mm->mmap_sem); | 134 | up_read(&mm->mmap_sem); |
137 | 135 | ||
138 | return __bad_area_nosemaphore(regs, address, si_code, pkey); | 136 | return __bad_area_nosemaphore(regs, address, si_code); |
139 | } | 137 | } |
140 | 138 | ||
141 | static noinline int bad_area(struct pt_regs *regs, unsigned long address) | 139 | static noinline int bad_area(struct pt_regs *regs, unsigned long address) |
142 | { | 140 | { |
143 | return __bad_area(regs, address, SEGV_MAPERR, 0); | 141 | return __bad_area(regs, address, SEGV_MAPERR); |
144 | } | 142 | } |
145 | 143 | ||
146 | static int bad_key_fault_exception(struct pt_regs *regs, unsigned long address, | 144 | static int bad_key_fault_exception(struct pt_regs *regs, unsigned long address, |
147 | int pkey) | 145 | int pkey) |
148 | { | 146 | { |
149 | return __bad_area_nosemaphore(regs, address, SEGV_PKUERR, pkey); | 147 | /* |
148 | * If we are in kernel mode, bail out with a SEGV, this will | ||
149 | * be caught by the assembly which will restore the non-volatile | ||
150 | * registers before calling bad_page_fault() | ||
151 | */ | ||
152 | if (!user_mode(regs)) | ||
153 | return SIGSEGV; | ||
154 | |||
155 | _exception_pkey(regs, address, pkey); | ||
156 | |||
157 | return 0; | ||
150 | } | 158 | } |
151 | 159 | ||
152 | static noinline int bad_access(struct pt_regs *regs, unsigned long address) | 160 | static noinline int bad_access(struct pt_regs *regs, unsigned long address) |
153 | { | 161 | { |
154 | return __bad_area(regs, address, SEGV_ACCERR, 0); | 162 | return __bad_area(regs, address, SEGV_ACCERR); |
155 | } | 163 | } |
156 | 164 | ||
157 | static int do_sigbus(struct pt_regs *regs, unsigned long address, | 165 | static int do_sigbus(struct pt_regs *regs, unsigned long address, |
158 | vm_fault_t fault) | 166 | vm_fault_t fault) |
159 | { | 167 | { |
160 | siginfo_t info; | ||
161 | unsigned int lsb = 0; | ||
162 | |||
163 | if (!user_mode(regs)) | 168 | if (!user_mode(regs)) |
164 | return SIGBUS; | 169 | return SIGBUS; |
165 | 170 | ||
166 | current->thread.trap_nr = BUS_ADRERR; | 171 | current->thread.trap_nr = BUS_ADRERR; |
167 | clear_siginfo(&info); | ||
168 | info.si_signo = SIGBUS; | ||
169 | info.si_errno = 0; | ||
170 | info.si_code = BUS_ADRERR; | ||
171 | info.si_addr = (void __user *)address; | ||
172 | #ifdef CONFIG_MEMORY_FAILURE | 172 | #ifdef CONFIG_MEMORY_FAILURE |
173 | if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) { | 173 | if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) { |
174 | unsigned int lsb = 0; /* shutup gcc */ | ||
175 | |||
174 | pr_err("MCE: Killing %s:%d due to hardware memory corruption fault at %lx\n", | 176 | pr_err("MCE: Killing %s:%d due to hardware memory corruption fault at %lx\n", |
175 | current->comm, current->pid, address); | 177 | current->comm, current->pid, address); |
176 | info.si_code = BUS_MCEERR_AR; | 178 | |
179 | if (fault & VM_FAULT_HWPOISON_LARGE) | ||
180 | lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault)); | ||
181 | if (fault & VM_FAULT_HWPOISON) | ||
182 | lsb = PAGE_SHIFT; | ||
183 | |||
184 | force_sig_mceerr(BUS_MCEERR_AR, (void __user *)address, lsb, | ||
185 | current); | ||
186 | return 0; | ||
177 | } | 187 | } |
178 | 188 | ||
179 | if (fault & VM_FAULT_HWPOISON_LARGE) | ||
180 | lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault)); | ||
181 | if (fault & VM_FAULT_HWPOISON) | ||
182 | lsb = PAGE_SHIFT; | ||
183 | #endif | 189 | #endif |
184 | info.si_addr_lsb = lsb; | 190 | force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)address, current); |
185 | force_sig_info(SIGBUS, &info, current); | ||
186 | return 0; | 191 | return 0; |
187 | } | 192 | } |
188 | 193 | ||
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 0c45cdbac4cf..7f12c7b78c0f 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
@@ -50,11 +50,11 @@ struct cbe_spu_info cbe_spu_info[MAX_NUMNODES]; | |||
50 | EXPORT_SYMBOL_GPL(cbe_spu_info); | 50 | EXPORT_SYMBOL_GPL(cbe_spu_info); |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * The spufs fault-handling code needs to call force_sig_info to raise signals | 53 | * The spufs fault-handling code needs to call force_sig_fault to raise signals |
54 | * on DMA errors. Export it here to avoid general kernel-wide access to this | 54 | * on DMA errors. Export it here to avoid general kernel-wide access to this |
55 | * function | 55 | * function |
56 | */ | 56 | */ |
57 | EXPORT_SYMBOL_GPL(force_sig_info); | 57 | EXPORT_SYMBOL_GPL(force_sig_fault); |
58 | 58 | ||
59 | /* | 59 | /* |
60 | * Protects cbe_spu_info and spu->number. | 60 | * Protects cbe_spu_info and spu->number. |
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c index 83cf58daaa79..971ac43b5d60 100644 --- a/arch/powerpc/platforms/cell/spufs/fault.c +++ b/arch/powerpc/platforms/cell/spufs/fault.c | |||
@@ -36,42 +36,32 @@ | |||
36 | static void spufs_handle_event(struct spu_context *ctx, | 36 | static void spufs_handle_event(struct spu_context *ctx, |
37 | unsigned long ea, int type) | 37 | unsigned long ea, int type) |
38 | { | 38 | { |
39 | siginfo_t info; | ||
40 | |||
41 | if (ctx->flags & SPU_CREATE_EVENTS_ENABLED) { | 39 | if (ctx->flags & SPU_CREATE_EVENTS_ENABLED) { |
42 | ctx->event_return |= type; | 40 | ctx->event_return |= type; |
43 | wake_up_all(&ctx->stop_wq); | 41 | wake_up_all(&ctx->stop_wq); |
44 | return; | 42 | return; |
45 | } | 43 | } |
46 | 44 | ||
47 | clear_siginfo(&info); | ||
48 | |||
49 | switch (type) { | 45 | switch (type) { |
50 | case SPE_EVENT_INVALID_DMA: | 46 | case SPE_EVENT_INVALID_DMA: |
51 | info.si_signo = SIGBUS; | 47 | force_sig_fault(SIGBUS, BUS_OBJERR, NULL, current); |
52 | info.si_code = BUS_OBJERR; | ||
53 | break; | 48 | break; |
54 | case SPE_EVENT_SPE_DATA_STORAGE: | 49 | case SPE_EVENT_SPE_DATA_STORAGE: |
55 | info.si_signo = SIGSEGV; | ||
56 | info.si_addr = (void __user *)ea; | ||
57 | info.si_code = SEGV_ACCERR; | ||
58 | ctx->ops->restart_dma(ctx); | 50 | ctx->ops->restart_dma(ctx); |
51 | force_sig_fault(SIGSEGV, SEGV_ACCERR, (void __user *)ea, | ||
52 | current); | ||
59 | break; | 53 | break; |
60 | case SPE_EVENT_DMA_ALIGNMENT: | 54 | case SPE_EVENT_DMA_ALIGNMENT: |
61 | info.si_signo = SIGBUS; | ||
62 | /* DAR isn't set for an alignment fault :( */ | 55 | /* DAR isn't set for an alignment fault :( */ |
63 | info.si_code = BUS_ADRALN; | 56 | force_sig_fault(SIGBUS, BUS_ADRALN, NULL, current); |
64 | break; | 57 | break; |
65 | case SPE_EVENT_SPE_ERROR: | 58 | case SPE_EVENT_SPE_ERROR: |
66 | info.si_signo = SIGILL; | 59 | force_sig_fault( |
67 | info.si_addr = (void __user *)(unsigned long) | 60 | SIGILL, ILL_ILLOPC, |
68 | ctx->ops->npc_read(ctx) - 4; | 61 | (void __user *)(unsigned long) |
69 | info.si_code = ILL_ILLOPC; | 62 | ctx->ops->npc_read(ctx) - 4, current); |
70 | break; | 63 | break; |
71 | } | 64 | } |
72 | |||
73 | if (info.si_signo) | ||
74 | force_sig_info(info.si_signo, &info, current); | ||
75 | } | 65 | } |
76 | 66 | ||
77 | int spufs_handle_class0(struct spu_context *ctx) | 67 | int spufs_handle_class0(struct spu_context *ctx) |
diff --git a/arch/riscv/include/uapi/asm/Kbuild b/arch/riscv/include/uapi/asm/Kbuild index 7e91f4850475..5511b9918131 100644 --- a/arch/riscv/include/uapi/asm/Kbuild +++ b/arch/riscv/include/uapi/asm/Kbuild | |||
@@ -26,3 +26,4 @@ generic-y += swab.h | |||
26 | generic-y += termbits.h | 26 | generic-y += termbits.h |
27 | generic-y += termios.h | 27 | generic-y += termios.h |
28 | generic-y += types.h | 28 | generic-y += types.h |
29 | generic-y += siginfo.h | ||
diff --git a/arch/riscv/include/uapi/asm/siginfo.h b/arch/riscv/include/uapi/asm/siginfo.h deleted file mode 100644 index f96849aac662..000000000000 --- a/arch/riscv/include/uapi/asm/siginfo.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2012 ARM Ltd. | ||
3 | * Copyright (C) 2016 SiFive, Inc. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | #ifndef __ASM_SIGINFO_H | ||
18 | #define __ASM_SIGINFO_H | ||
19 | |||
20 | #define __ARCH_SI_PREAMBLE_SIZE (__SIZEOF_POINTER__ == 4 ? 12 : 16) | ||
21 | |||
22 | #include <asm-generic/siginfo.h> | ||
23 | |||
24 | #endif | ||
diff --git a/arch/s390/include/uapi/asm/Kbuild b/arch/s390/include/uapi/asm/Kbuild index e364873e0d10..dc38a90cf091 100644 --- a/arch/s390/include/uapi/asm/Kbuild +++ b/arch/s390/include/uapi/asm/Kbuild | |||
@@ -18,3 +18,4 @@ generic-y += shmbuf.h | |||
18 | generic-y += sockios.h | 18 | generic-y += sockios.h |
19 | generic-y += swab.h | 19 | generic-y += swab.h |
20 | generic-y += termbits.h | 20 | generic-y += termbits.h |
21 | generic-y += siginfo.h \ No newline at end of file | ||
diff --git a/arch/s390/include/uapi/asm/siginfo.h b/arch/s390/include/uapi/asm/siginfo.h deleted file mode 100644 index 6984820f2f1c..000000000000 --- a/arch/s390/include/uapi/asm/siginfo.h +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | ||
2 | /* | ||
3 | * S390 version | ||
4 | * | ||
5 | * Derived from "include/asm-i386/siginfo.h" | ||
6 | */ | ||
7 | |||
8 | #ifndef _S390_SIGINFO_H | ||
9 | #define _S390_SIGINFO_H | ||
10 | |||
11 | #ifdef __s390x__ | ||
12 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | ||
13 | #endif | ||
14 | |||
15 | #include <asm-generic/siginfo.h> | ||
16 | |||
17 | #endif | ||
diff --git a/arch/sparc/include/uapi/asm/siginfo.h b/arch/sparc/include/uapi/asm/siginfo.h index e7049550ac82..68bdde4c2a2e 100644 --- a/arch/sparc/include/uapi/asm/siginfo.h +++ b/arch/sparc/include/uapi/asm/siginfo.h | |||
@@ -4,7 +4,6 @@ | |||
4 | 4 | ||
5 | #if defined(__sparc__) && defined(__arch64__) | 5 | #if defined(__sparc__) && defined(__arch64__) |
6 | 6 | ||
7 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | ||
8 | #define __ARCH_SI_BAND_T int | 7 | #define __ARCH_SI_BAND_T int |
9 | 8 | ||
10 | #endif /* defined(__sparc__) && defined(__arch64__) */ | 9 | #endif /* defined(__sparc__) && defined(__arch64__) */ |
@@ -17,10 +16,4 @@ | |||
17 | 16 | ||
18 | #define SI_NOINFO 32767 /* no information in siginfo_t */ | 17 | #define SI_NOINFO 32767 /* no information in siginfo_t */ |
19 | 18 | ||
20 | /* | ||
21 | * SIGEMT si_codes | ||
22 | */ | ||
23 | #define EMT_TAGOVF 1 /* tag overflow */ | ||
24 | #define NSIGEMT 1 | ||
25 | |||
26 | #endif /* _UAPI__SPARC_SIGINFO_H */ | 19 | #endif /* _UAPI__SPARC_SIGINFO_H */ |
diff --git a/arch/unicore32/include/asm/bug.h b/arch/unicore32/include/asm/bug.h index 93a56f3e2344..83c7687a0e61 100644 --- a/arch/unicore32/include/asm/bug.h +++ b/arch/unicore32/include/asm/bug.h | |||
@@ -17,6 +17,7 @@ struct siginfo; | |||
17 | 17 | ||
18 | extern void die(const char *msg, struct pt_regs *regs, int err); | 18 | extern void die(const char *msg, struct pt_regs *regs, int err); |
19 | extern void uc32_notify_die(const char *str, struct pt_regs *regs, | 19 | extern void uc32_notify_die(const char *str, struct pt_regs *regs, |
20 | struct siginfo *info, unsigned long err, unsigned long trap); | 20 | int sig, int code, void __user *addr, |
21 | unsigned long err, unsigned long trap); | ||
21 | 22 | ||
22 | #endif /* __UNICORE_BUG_H__ */ | 23 | #endif /* __UNICORE_BUG_H__ */ |
diff --git a/arch/unicore32/kernel/fpu-ucf64.c b/arch/unicore32/kernel/fpu-ucf64.c index 8594b168f25e..fc5dad32a982 100644 --- a/arch/unicore32/kernel/fpu-ucf64.c +++ b/arch/unicore32/kernel/fpu-ucf64.c | |||
@@ -54,14 +54,6 @@ | |||
54 | */ | 54 | */ |
55 | void ucf64_raise_sigfpe(struct pt_regs *regs) | 55 | void ucf64_raise_sigfpe(struct pt_regs *regs) |
56 | { | 56 | { |
57 | siginfo_t info; | ||
58 | |||
59 | clear_siginfo(&info); | ||
60 | |||
61 | info.si_signo = SIGFPE; | ||
62 | info.si_code = FPE_FLTUNK; | ||
63 | info.si_addr = (void __user *)(instruction_pointer(regs) - 4); | ||
64 | |||
65 | /* | 57 | /* |
66 | * This is the same as NWFPE, because it's not clear what | 58 | * This is the same as NWFPE, because it's not clear what |
67 | * this is used for | 59 | * this is used for |
@@ -69,7 +61,9 @@ void ucf64_raise_sigfpe(struct pt_regs *regs) | |||
69 | current->thread.error_code = 0; | 61 | current->thread.error_code = 0; |
70 | current->thread.trap_no = 6; | 62 | current->thread.trap_no = 6; |
71 | 63 | ||
72 | send_sig_info(SIGFPE, &info, current); | 64 | send_sig_fault(SIGFPE, FPE_FLTUNK, |
65 | (void __user *)(instruction_pointer(regs) - 4), | ||
66 | current); | ||
73 | } | 67 | } |
74 | 68 | ||
75 | /* | 69 | /* |
diff --git a/arch/unicore32/kernel/traps.c b/arch/unicore32/kernel/traps.c index c4ac6043ebb0..fb376d83e043 100644 --- a/arch/unicore32/kernel/traps.c +++ b/arch/unicore32/kernel/traps.c | |||
@@ -241,13 +241,14 @@ void die(const char *str, struct pt_regs *regs, int err) | |||
241 | } | 241 | } |
242 | 242 | ||
243 | void uc32_notify_die(const char *str, struct pt_regs *regs, | 243 | void uc32_notify_die(const char *str, struct pt_regs *regs, |
244 | struct siginfo *info, unsigned long err, unsigned long trap) | 244 | int sig, int code, void __user *addr, |
245 | unsigned long err, unsigned long trap) | ||
245 | { | 246 | { |
246 | if (user_mode(regs)) { | 247 | if (user_mode(regs)) { |
247 | current->thread.error_code = err; | 248 | current->thread.error_code = err; |
248 | current->thread.trap_no = trap; | 249 | current->thread.trap_no = trap; |
249 | 250 | ||
250 | force_sig_info(info->si_signo, info, current); | 251 | force_sig_fault(sig, code, addr, current); |
251 | } else | 252 | } else |
252 | die(str, regs, err); | 253 | die(str, regs, err); |
253 | } | 254 | } |
diff --git a/arch/unicore32/mm/fault.c b/arch/unicore32/mm/fault.c index 8f12a5b50a42..b9a3a50644c1 100644 --- a/arch/unicore32/mm/fault.c +++ b/arch/unicore32/mm/fault.c | |||
@@ -120,17 +120,10 @@ static void __do_user_fault(struct task_struct *tsk, unsigned long addr, | |||
120 | unsigned int fsr, unsigned int sig, int code, | 120 | unsigned int fsr, unsigned int sig, int code, |
121 | struct pt_regs *regs) | 121 | struct pt_regs *regs) |
122 | { | 122 | { |
123 | struct siginfo si; | ||
124 | |||
125 | tsk->thread.address = addr; | 123 | tsk->thread.address = addr; |
126 | tsk->thread.error_code = fsr; | 124 | tsk->thread.error_code = fsr; |
127 | tsk->thread.trap_no = 14; | 125 | tsk->thread.trap_no = 14; |
128 | clear_siginfo(&si); | 126 | force_sig_fault(sig, code, (void __user *)addr, tsk); |
129 | si.si_signo = sig; | ||
130 | si.si_errno = 0; | ||
131 | si.si_code = code; | ||
132 | si.si_addr = (void __user *)addr; | ||
133 | force_sig_info(sig, &si, tsk); | ||
134 | } | 127 | } |
135 | 128 | ||
136 | void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | 129 | void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) |
@@ -466,7 +459,6 @@ asmlinkage void do_DataAbort(unsigned long addr, unsigned int fsr, | |||
466 | struct pt_regs *regs) | 459 | struct pt_regs *regs) |
467 | { | 460 | { |
468 | const struct fsr_info *inf = fsr_info + fsr_fs(fsr); | 461 | const struct fsr_info *inf = fsr_info + fsr_fs(fsr); |
469 | struct siginfo info; | ||
470 | 462 | ||
471 | if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs)) | 463 | if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs)) |
472 | return; | 464 | return; |
@@ -474,19 +466,14 @@ asmlinkage void do_DataAbort(unsigned long addr, unsigned int fsr, | |||
474 | printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n", | 466 | printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n", |
475 | inf->name, fsr, addr); | 467 | inf->name, fsr, addr); |
476 | 468 | ||
477 | clear_siginfo(&info); | 469 | uc32_notify_die("", regs, inf->sig, inf->code, (void __user *)addr, |
478 | info.si_signo = inf->sig; | 470 | fsr, 0); |
479 | info.si_errno = 0; | ||
480 | info.si_code = inf->code; | ||
481 | info.si_addr = (void __user *)addr; | ||
482 | uc32_notify_die("", regs, &info, fsr, 0); | ||
483 | } | 471 | } |
484 | 472 | ||
485 | asmlinkage void do_PrefetchAbort(unsigned long addr, | 473 | asmlinkage void do_PrefetchAbort(unsigned long addr, |
486 | unsigned int ifsr, struct pt_regs *regs) | 474 | unsigned int ifsr, struct pt_regs *regs) |
487 | { | 475 | { |
488 | const struct fsr_info *inf = fsr_info + fsr_fs(ifsr); | 476 | const struct fsr_info *inf = fsr_info + fsr_fs(ifsr); |
489 | struct siginfo info; | ||
490 | 477 | ||
491 | if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs)) | 478 | if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs)) |
492 | return; | 479 | return; |
@@ -494,10 +481,6 @@ asmlinkage void do_PrefetchAbort(unsigned long addr, | |||
494 | printk(KERN_ALERT "Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n", | 481 | printk(KERN_ALERT "Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n", |
495 | inf->name, ifsr, addr); | 482 | inf->name, ifsr, addr); |
496 | 483 | ||
497 | clear_siginfo(&info); | 484 | uc32_notify_die("", regs, inf->sig, inf->code, (void __user *)addr, |
498 | info.si_signo = inf->sig; | 485 | ifsr, 0); |
499 | info.si_errno = 0; | ||
500 | info.si_code = inf->code; | ||
501 | info.si_addr = (void __user *)addr; | ||
502 | uc32_notify_die("", regs, &info, ifsr, 0); | ||
503 | } | 486 | } |
diff --git a/arch/x86/entry/vsyscall/vsyscall_64.c b/arch/x86/entry/vsyscall/vsyscall_64.c index 82ed001e8909..85fd85d52ffd 100644 --- a/arch/x86/entry/vsyscall/vsyscall_64.c +++ b/arch/x86/entry/vsyscall/vsyscall_64.c | |||
@@ -100,20 +100,13 @@ static bool write_ok_or_segv(unsigned long ptr, size_t size) | |||
100 | */ | 100 | */ |
101 | 101 | ||
102 | if (!access_ok(VERIFY_WRITE, (void __user *)ptr, size)) { | 102 | if (!access_ok(VERIFY_WRITE, (void __user *)ptr, size)) { |
103 | siginfo_t info; | ||
104 | struct thread_struct *thread = ¤t->thread; | 103 | struct thread_struct *thread = ¤t->thread; |
105 | 104 | ||
106 | thread->error_code = 6; /* user fault, no page, write */ | 105 | thread->error_code = 6; /* user fault, no page, write */ |
107 | thread->cr2 = ptr; | 106 | thread->cr2 = ptr; |
108 | thread->trap_nr = X86_TRAP_PF; | 107 | thread->trap_nr = X86_TRAP_PF; |
109 | 108 | ||
110 | clear_siginfo(&info); | 109 | force_sig_fault(SIGSEGV, SEGV_MAPERR, (void __user *)ptr, current); |
111 | info.si_signo = SIGSEGV; | ||
112 | info.si_errno = 0; | ||
113 | info.si_code = SEGV_MAPERR; | ||
114 | info.si_addr = (void __user *)ptr; | ||
115 | |||
116 | force_sig_info(SIGSEGV, &info, current); | ||
117 | return false; | 110 | return false; |
118 | } else { | 111 | } else { |
119 | return true; | 112 | return true; |
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h index fb97cf7c4137..a0f46bdd9f24 100644 --- a/arch/x86/include/asm/compat.h +++ b/arch/x86/include/asm/compat.h | |||
@@ -240,6 +240,6 @@ static inline bool in_compat_syscall(void) | |||
240 | 240 | ||
241 | struct compat_siginfo; | 241 | struct compat_siginfo; |
242 | int __copy_siginfo_to_user32(struct compat_siginfo __user *to, | 242 | int __copy_siginfo_to_user32(struct compat_siginfo __user *to, |
243 | const siginfo_t *from, bool x32_ABI); | 243 | const kernel_siginfo_t *from, bool x32_ABI); |
244 | 244 | ||
245 | #endif /* _ASM_X86_COMPAT_H */ | 245 | #endif /* _ASM_X86_COMPAT_H */ |
diff --git a/arch/x86/include/asm/mpx.h b/arch/x86/include/asm/mpx.h index 61eb4b63c5ec..d0b1434fb0b6 100644 --- a/arch/x86/include/asm/mpx.h +++ b/arch/x86/include/asm/mpx.h | |||
@@ -57,8 +57,14 @@ | |||
57 | #define MPX_BNDCFG_ADDR_MASK (~((1UL<<MPX_BNDCFG_TAIL)-1)) | 57 | #define MPX_BNDCFG_ADDR_MASK (~((1UL<<MPX_BNDCFG_TAIL)-1)) |
58 | #define MPX_BNDSTA_ERROR_CODE 0x3 | 58 | #define MPX_BNDSTA_ERROR_CODE 0x3 |
59 | 59 | ||
60 | struct mpx_fault_info { | ||
61 | void __user *addr; | ||
62 | void __user *lower; | ||
63 | void __user *upper; | ||
64 | }; | ||
65 | |||
60 | #ifdef CONFIG_X86_INTEL_MPX | 66 | #ifdef CONFIG_X86_INTEL_MPX |
61 | siginfo_t *mpx_generate_siginfo(struct pt_regs *regs); | 67 | int mpx_fault_info(struct mpx_fault_info *info, struct pt_regs *regs); |
62 | int mpx_handle_bd_fault(void); | 68 | int mpx_handle_bd_fault(void); |
63 | static inline int kernel_managing_mpx_tables(struct mm_struct *mm) | 69 | static inline int kernel_managing_mpx_tables(struct mm_struct *mm) |
64 | { | 70 | { |
@@ -78,9 +84,9 @@ void mpx_notify_unmap(struct mm_struct *mm, struct vm_area_struct *vma, | |||
78 | unsigned long mpx_unmapped_area_check(unsigned long addr, unsigned long len, | 84 | unsigned long mpx_unmapped_area_check(unsigned long addr, unsigned long len, |
79 | unsigned long flags); | 85 | unsigned long flags); |
80 | #else | 86 | #else |
81 | static inline siginfo_t *mpx_generate_siginfo(struct pt_regs *regs) | 87 | static inline int mpx_fault_info(struct mpx_fault_info *info, struct pt_regs *regs) |
82 | { | 88 | { |
83 | return NULL; | 89 | return -EINVAL; |
84 | } | 90 | } |
85 | static inline int mpx_handle_bd_fault(void) | 91 | static inline int mpx_handle_bd_fault(void) |
86 | { | 92 | { |
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index f236bcd5485d..143c99499531 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h | |||
@@ -293,7 +293,7 @@ static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, | |||
293 | #define arch_has_block_step() (boot_cpu_data.x86 >= 6) | 293 | #define arch_has_block_step() (boot_cpu_data.x86 >= 6) |
294 | #endif | 294 | #endif |
295 | 295 | ||
296 | #define ARCH_HAS_USER_SINGLE_STEP_INFO | 296 | #define ARCH_HAS_USER_SINGLE_STEP_REPORT |
297 | 297 | ||
298 | /* | 298 | /* |
299 | * When hitting ptrace_stop(), we cannot return using SYSRET because | 299 | * When hitting ptrace_stop(), we cannot return using SYSRET because |
diff --git a/arch/x86/include/asm/trace/mpx.h b/arch/x86/include/asm/trace/mpx.h index 7bd92db09e8d..54133017267c 100644 --- a/arch/x86/include/asm/trace/mpx.h +++ b/arch/x86/include/asm/trace/mpx.h | |||
@@ -11,12 +11,12 @@ | |||
11 | 11 | ||
12 | TRACE_EVENT(mpx_bounds_register_exception, | 12 | TRACE_EVENT(mpx_bounds_register_exception, |
13 | 13 | ||
14 | TP_PROTO(void *addr_referenced, | 14 | TP_PROTO(void __user *addr_referenced, |
15 | const struct mpx_bndreg *bndreg), | 15 | const struct mpx_bndreg *bndreg), |
16 | TP_ARGS(addr_referenced, bndreg), | 16 | TP_ARGS(addr_referenced, bndreg), |
17 | 17 | ||
18 | TP_STRUCT__entry( | 18 | TP_STRUCT__entry( |
19 | __field(void *, addr_referenced) | 19 | __field(void __user *, addr_referenced) |
20 | __field(u64, lower_bound) | 20 | __field(u64, lower_bound) |
21 | __field(u64, upper_bound) | 21 | __field(u64, upper_bound) |
22 | ), | 22 | ), |
diff --git a/arch/x86/include/uapi/asm/siginfo.h b/arch/x86/include/uapi/asm/siginfo.h index b3d157957177..6642d8be40c4 100644 --- a/arch/x86/include/uapi/asm/siginfo.h +++ b/arch/x86/include/uapi/asm/siginfo.h | |||
@@ -7,8 +7,6 @@ | |||
7 | typedef long long __kernel_si_clock_t __attribute__((aligned(4))); | 7 | typedef long long __kernel_si_clock_t __attribute__((aligned(4))); |
8 | # define __ARCH_SI_CLOCK_T __kernel_si_clock_t | 8 | # define __ARCH_SI_CLOCK_T __kernel_si_clock_t |
9 | # define __ARCH_SI_ATTRIBUTES __attribute__((aligned(8))) | 9 | # define __ARCH_SI_ATTRIBUTES __attribute__((aligned(8))) |
10 | # else /* x86-64 */ | ||
11 | # define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | ||
12 | # endif | 10 | # endif |
13 | #endif | 11 | #endif |
14 | 12 | ||
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index d8f49c7384a3..ffae9b9740fd 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -1359,33 +1359,18 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task) | |||
1359 | #endif | 1359 | #endif |
1360 | } | 1360 | } |
1361 | 1361 | ||
1362 | static void fill_sigtrap_info(struct task_struct *tsk, | 1362 | void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, |
1363 | struct pt_regs *regs, | 1363 | int error_code, int si_code) |
1364 | int error_code, int si_code, | ||
1365 | struct siginfo *info) | ||
1366 | { | 1364 | { |
1367 | tsk->thread.trap_nr = X86_TRAP_DB; | 1365 | tsk->thread.trap_nr = X86_TRAP_DB; |
1368 | tsk->thread.error_code = error_code; | 1366 | tsk->thread.error_code = error_code; |
1369 | 1367 | ||
1370 | info->si_signo = SIGTRAP; | 1368 | /* Send us the fake SIGTRAP */ |
1371 | info->si_code = si_code; | 1369 | force_sig_fault(SIGTRAP, si_code, |
1372 | info->si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL; | 1370 | user_mode(regs) ? (void __user *)regs->ip : NULL, tsk); |
1373 | } | ||
1374 | |||
1375 | void user_single_step_siginfo(struct task_struct *tsk, | ||
1376 | struct pt_regs *regs, | ||
1377 | struct siginfo *info) | ||
1378 | { | ||
1379 | fill_sigtrap_info(tsk, regs, 0, TRAP_BRKPT, info); | ||
1380 | } | 1371 | } |
1381 | 1372 | ||
1382 | void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, | 1373 | void user_single_step_report(struct pt_regs *regs) |
1383 | int error_code, int si_code) | ||
1384 | { | 1374 | { |
1385 | struct siginfo info; | 1375 | send_sigtrap(current, regs, 0, TRAP_BRKPT); |
1386 | |||
1387 | clear_siginfo(&info); | ||
1388 | fill_sigtrap_info(tsk, regs, error_code, si_code, &info); | ||
1389 | /* Send us the fake SIGTRAP */ | ||
1390 | force_sig_info(SIGTRAP, &info, tsk); | ||
1391 | } | 1376 | } |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 5bd0a997d81e..8f6dcd88202e 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -189,7 +189,7 @@ int fixup_bug(struct pt_regs *regs, int trapnr) | |||
189 | } | 189 | } |
190 | 190 | ||
191 | static nokprobe_inline int | 191 | static nokprobe_inline int |
192 | do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str, | 192 | do_trap_no_signal(struct task_struct *tsk, int trapnr, const char *str, |
193 | struct pt_regs *regs, long error_code) | 193 | struct pt_regs *regs, long error_code) |
194 | { | 194 | { |
195 | if (v8086_mode(regs)) { | 195 | if (v8086_mode(regs)) { |
@@ -202,10 +202,7 @@ do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str, | |||
202 | error_code, trapnr)) | 202 | error_code, trapnr)) |
203 | return 0; | 203 | return 0; |
204 | } | 204 | } |
205 | return -1; | 205 | } else if (!user_mode(regs)) { |
206 | } | ||
207 | |||
208 | if (!user_mode(regs)) { | ||
209 | if (fixup_exception(regs, trapnr, error_code, 0)) | 206 | if (fixup_exception(regs, trapnr, error_code, 0)) |
210 | return 0; | 207 | return 0; |
211 | 208 | ||
@@ -214,49 +211,6 @@ do_trap_no_signal(struct task_struct *tsk, int trapnr, char *str, | |||
214 | die(str, regs, error_code); | 211 | die(str, regs, error_code); |
215 | } | 212 | } |
216 | 213 | ||
217 | return -1; | ||
218 | } | ||
219 | |||
220 | static siginfo_t *fill_trap_info(struct pt_regs *regs, int signr, int trapnr, | ||
221 | siginfo_t *info) | ||
222 | { | ||
223 | unsigned long siaddr; | ||
224 | int sicode; | ||
225 | |||
226 | switch (trapnr) { | ||
227 | default: | ||
228 | return SEND_SIG_PRIV; | ||
229 | |||
230 | case X86_TRAP_DE: | ||
231 | sicode = FPE_INTDIV; | ||
232 | siaddr = uprobe_get_trap_addr(regs); | ||
233 | break; | ||
234 | case X86_TRAP_UD: | ||
235 | sicode = ILL_ILLOPN; | ||
236 | siaddr = uprobe_get_trap_addr(regs); | ||
237 | break; | ||
238 | case X86_TRAP_AC: | ||
239 | sicode = BUS_ADRALN; | ||
240 | siaddr = 0; | ||
241 | break; | ||
242 | } | ||
243 | |||
244 | info->si_signo = signr; | ||
245 | info->si_errno = 0; | ||
246 | info->si_code = sicode; | ||
247 | info->si_addr = (void __user *)siaddr; | ||
248 | return info; | ||
249 | } | ||
250 | |||
251 | static void | ||
252 | do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, | ||
253 | long error_code, siginfo_t *info) | ||
254 | { | ||
255 | struct task_struct *tsk = current; | ||
256 | |||
257 | |||
258 | if (!do_trap_no_signal(tsk, trapnr, str, regs, error_code)) | ||
259 | return; | ||
260 | /* | 214 | /* |
261 | * We want error_code and trap_nr set for userspace faults and | 215 | * We want error_code and trap_nr set for userspace faults and |
262 | * kernelspace faults which result in die(), but not | 216 | * kernelspace faults which result in die(), but not |
@@ -269,24 +223,45 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, | |||
269 | tsk->thread.error_code = error_code; | 223 | tsk->thread.error_code = error_code; |
270 | tsk->thread.trap_nr = trapnr; | 224 | tsk->thread.trap_nr = trapnr; |
271 | 225 | ||
226 | return -1; | ||
227 | } | ||
228 | |||
229 | static void show_signal(struct task_struct *tsk, int signr, | ||
230 | const char *type, const char *desc, | ||
231 | struct pt_regs *regs, long error_code) | ||
232 | { | ||
272 | if (show_unhandled_signals && unhandled_signal(tsk, signr) && | 233 | if (show_unhandled_signals && unhandled_signal(tsk, signr) && |
273 | printk_ratelimit()) { | 234 | printk_ratelimit()) { |
274 | pr_info("%s[%d] trap %s ip:%lx sp:%lx error:%lx", | 235 | pr_info("%s[%d] %s%s ip:%lx sp:%lx error:%lx", |
275 | tsk->comm, tsk->pid, str, | 236 | tsk->comm, task_pid_nr(tsk), type, desc, |
276 | regs->ip, regs->sp, error_code); | 237 | regs->ip, regs->sp, error_code); |
277 | print_vma_addr(KERN_CONT " in ", regs->ip); | 238 | print_vma_addr(KERN_CONT " in ", regs->ip); |
278 | pr_cont("\n"); | 239 | pr_cont("\n"); |
279 | } | 240 | } |
241 | } | ||
242 | |||
243 | static void | ||
244 | do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, | ||
245 | long error_code, int sicode, void __user *addr) | ||
246 | { | ||
247 | struct task_struct *tsk = current; | ||
248 | |||
249 | |||
250 | if (!do_trap_no_signal(tsk, trapnr, str, regs, error_code)) | ||
251 | return; | ||
252 | |||
253 | show_signal(tsk, signr, "trap ", str, regs, error_code); | ||
280 | 254 | ||
281 | force_sig_info(signr, info ?: SEND_SIG_PRIV, tsk); | 255 | if (!sicode) |
256 | force_sig(signr, tsk); | ||
257 | else | ||
258 | force_sig_fault(signr, sicode, addr, tsk); | ||
282 | } | 259 | } |
283 | NOKPROBE_SYMBOL(do_trap); | 260 | NOKPROBE_SYMBOL(do_trap); |
284 | 261 | ||
285 | static void do_error_trap(struct pt_regs *regs, long error_code, char *str, | 262 | static void do_error_trap(struct pt_regs *regs, long error_code, char *str, |
286 | unsigned long trapnr, int signr) | 263 | unsigned long trapnr, int signr, int sicode, void __user *addr) |
287 | { | 264 | { |
288 | siginfo_t info; | ||
289 | |||
290 | RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); | 265 | RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); |
291 | 266 | ||
292 | /* | 267 | /* |
@@ -299,26 +274,26 @@ static void do_error_trap(struct pt_regs *regs, long error_code, char *str, | |||
299 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) != | 274 | if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) != |
300 | NOTIFY_STOP) { | 275 | NOTIFY_STOP) { |
301 | cond_local_irq_enable(regs); | 276 | cond_local_irq_enable(regs); |
302 | clear_siginfo(&info); | 277 | do_trap(trapnr, signr, str, regs, error_code, sicode, addr); |
303 | do_trap(trapnr, signr, str, regs, error_code, | ||
304 | fill_trap_info(regs, signr, trapnr, &info)); | ||
305 | } | 278 | } |
306 | } | 279 | } |
307 | 280 | ||
308 | #define DO_ERROR(trapnr, signr, str, name) \ | 281 | #define IP ((void __user *)uprobe_get_trap_addr(regs)) |
309 | dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ | 282 | #define DO_ERROR(trapnr, signr, sicode, addr, str, name) \ |
310 | { \ | 283 | dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ |
311 | do_error_trap(regs, error_code, str, trapnr, signr); \ | 284 | { \ |
285 | do_error_trap(regs, error_code, str, trapnr, signr, sicode, addr); \ | ||
312 | } | 286 | } |
313 | 287 | ||
314 | DO_ERROR(X86_TRAP_DE, SIGFPE, "divide error", divide_error) | 288 | DO_ERROR(X86_TRAP_DE, SIGFPE, FPE_INTDIV, IP, "divide error", divide_error) |
315 | DO_ERROR(X86_TRAP_OF, SIGSEGV, "overflow", overflow) | 289 | DO_ERROR(X86_TRAP_OF, SIGSEGV, 0, NULL, "overflow", overflow) |
316 | DO_ERROR(X86_TRAP_UD, SIGILL, "invalid opcode", invalid_op) | 290 | DO_ERROR(X86_TRAP_UD, SIGILL, ILL_ILLOPN, IP, "invalid opcode", invalid_op) |
317 | DO_ERROR(X86_TRAP_OLD_MF, SIGFPE, "coprocessor segment overrun",coprocessor_segment_overrun) | 291 | DO_ERROR(X86_TRAP_OLD_MF, SIGFPE, 0, NULL, "coprocessor segment overrun", coprocessor_segment_overrun) |
318 | DO_ERROR(X86_TRAP_TS, SIGSEGV, "invalid TSS", invalid_TSS) | 292 | DO_ERROR(X86_TRAP_TS, SIGSEGV, 0, NULL, "invalid TSS", invalid_TSS) |
319 | DO_ERROR(X86_TRAP_NP, SIGBUS, "segment not present", segment_not_present) | 293 | DO_ERROR(X86_TRAP_NP, SIGBUS, 0, NULL, "segment not present", segment_not_present) |
320 | DO_ERROR(X86_TRAP_SS, SIGBUS, "stack segment", stack_segment) | 294 | DO_ERROR(X86_TRAP_SS, SIGBUS, 0, NULL, "stack segment", stack_segment) |
321 | DO_ERROR(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check) | 295 | DO_ERROR(X86_TRAP_AC, SIGBUS, BUS_ADRALN, NULL, "alignment check", alignment_check) |
296 | #undef IP | ||
322 | 297 | ||
323 | #ifdef CONFIG_VMAP_STACK | 298 | #ifdef CONFIG_VMAP_STACK |
324 | __visible void __noreturn handle_stack_overflow(const char *message, | 299 | __visible void __noreturn handle_stack_overflow(const char *message, |
@@ -459,7 +434,6 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) | |||
459 | dotraplinkage void do_bounds(struct pt_regs *regs, long error_code) | 434 | dotraplinkage void do_bounds(struct pt_regs *regs, long error_code) |
460 | { | 435 | { |
461 | const struct mpx_bndcsr *bndcsr; | 436 | const struct mpx_bndcsr *bndcsr; |
462 | siginfo_t *info; | ||
463 | 437 | ||
464 | RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); | 438 | RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); |
465 | if (notify_die(DIE_TRAP, "bounds", regs, error_code, | 439 | if (notify_die(DIE_TRAP, "bounds", regs, error_code, |
@@ -497,8 +471,11 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code) | |||
497 | goto exit_trap; | 471 | goto exit_trap; |
498 | break; /* Success, it was handled */ | 472 | break; /* Success, it was handled */ |
499 | case 1: /* Bound violation. */ | 473 | case 1: /* Bound violation. */ |
500 | info = mpx_generate_siginfo(regs); | 474 | { |
501 | if (IS_ERR(info)) { | 475 | struct task_struct *tsk = current; |
476 | struct mpx_fault_info mpx; | ||
477 | |||
478 | if (mpx_fault_info(&mpx, regs)) { | ||
502 | /* | 479 | /* |
503 | * We failed to decode the MPX instruction. Act as if | 480 | * We failed to decode the MPX instruction. Act as if |
504 | * the exception was not caused by MPX. | 481 | * the exception was not caused by MPX. |
@@ -507,14 +484,20 @@ dotraplinkage void do_bounds(struct pt_regs *regs, long error_code) | |||
507 | } | 484 | } |
508 | /* | 485 | /* |
509 | * Success, we decoded the instruction and retrieved | 486 | * Success, we decoded the instruction and retrieved |
510 | * an 'info' containing the address being accessed | 487 | * an 'mpx' containing the address being accessed |
511 | * which caused the exception. This information | 488 | * which caused the exception. This information |
512 | * allows and application to possibly handle the | 489 | * allows and application to possibly handle the |
513 | * #BR exception itself. | 490 | * #BR exception itself. |
514 | */ | 491 | */ |
515 | do_trap(X86_TRAP_BR, SIGSEGV, "bounds", regs, error_code, info); | 492 | if (!do_trap_no_signal(tsk, X86_TRAP_BR, "bounds", regs, |
516 | kfree(info); | 493 | error_code)) |
494 | break; | ||
495 | |||
496 | show_signal(tsk, SIGSEGV, "trap ", "bounds", regs, error_code); | ||
497 | |||
498 | force_sig_bnderr(mpx.addr, mpx.lower, mpx.upper); | ||
517 | break; | 499 | break; |
500 | } | ||
518 | case 0: /* No exception caused by Intel MPX operations. */ | 501 | case 0: /* No exception caused by Intel MPX operations. */ |
519 | goto exit_trap; | 502 | goto exit_trap; |
520 | default: | 503 | default: |
@@ -531,12 +514,13 @@ exit_trap: | |||
531 | * up here if the kernel has MPX turned off at compile | 514 | * up here if the kernel has MPX turned off at compile |
532 | * time.. | 515 | * time.. |
533 | */ | 516 | */ |
534 | do_trap(X86_TRAP_BR, SIGSEGV, "bounds", regs, error_code, NULL); | 517 | do_trap(X86_TRAP_BR, SIGSEGV, "bounds", regs, error_code, 0, NULL); |
535 | } | 518 | } |
536 | 519 | ||
537 | dotraplinkage void | 520 | dotraplinkage void |
538 | do_general_protection(struct pt_regs *regs, long error_code) | 521 | do_general_protection(struct pt_regs *regs, long error_code) |
539 | { | 522 | { |
523 | const char *desc = "general protection fault"; | ||
540 | struct task_struct *tsk; | 524 | struct task_struct *tsk; |
541 | 525 | ||
542 | RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); | 526 | RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); |
@@ -570,25 +554,18 @@ do_general_protection(struct pt_regs *regs, long error_code) | |||
570 | kprobe_fault_handler(regs, X86_TRAP_GP)) | 554 | kprobe_fault_handler(regs, X86_TRAP_GP)) |
571 | return; | 555 | return; |
572 | 556 | ||
573 | if (notify_die(DIE_GPF, "general protection fault", regs, error_code, | 557 | if (notify_die(DIE_GPF, desc, regs, error_code, |
574 | X86_TRAP_GP, SIGSEGV) != NOTIFY_STOP) | 558 | X86_TRAP_GP, SIGSEGV) != NOTIFY_STOP) |
575 | die("general protection fault", regs, error_code); | 559 | die(desc, regs, error_code); |
576 | return; | 560 | return; |
577 | } | 561 | } |
578 | 562 | ||
579 | tsk->thread.error_code = error_code; | 563 | tsk->thread.error_code = error_code; |
580 | tsk->thread.trap_nr = X86_TRAP_GP; | 564 | tsk->thread.trap_nr = X86_TRAP_GP; |
581 | 565 | ||
582 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && | 566 | show_signal(tsk, SIGSEGV, "", desc, regs, error_code); |
583 | printk_ratelimit()) { | ||
584 | pr_info("%s[%d] general protection ip:%lx sp:%lx error:%lx", | ||
585 | tsk->comm, task_pid_nr(tsk), | ||
586 | regs->ip, regs->sp, error_code); | ||
587 | print_vma_addr(KERN_CONT " in ", regs->ip); | ||
588 | pr_cont("\n"); | ||
589 | } | ||
590 | 567 | ||
591 | force_sig_info(SIGSEGV, SEND_SIG_PRIV, tsk); | 568 | force_sig(SIGSEGV, tsk); |
592 | } | 569 | } |
593 | NOKPROBE_SYMBOL(do_general_protection); | 570 | NOKPROBE_SYMBOL(do_general_protection); |
594 | 571 | ||
@@ -631,7 +608,7 @@ dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code) | |||
631 | goto exit; | 608 | goto exit; |
632 | 609 | ||
633 | cond_local_irq_enable(regs); | 610 | cond_local_irq_enable(regs); |
634 | do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, NULL); | 611 | do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, 0, NULL); |
635 | cond_local_irq_disable(regs); | 612 | cond_local_irq_disable(regs); |
636 | 613 | ||
637 | exit: | 614 | exit: |
@@ -845,7 +822,7 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr) | |||
845 | { | 822 | { |
846 | struct task_struct *task = current; | 823 | struct task_struct *task = current; |
847 | struct fpu *fpu = &task->thread.fpu; | 824 | struct fpu *fpu = &task->thread.fpu; |
848 | siginfo_t info; | 825 | int si_code; |
849 | char *str = (trapnr == X86_TRAP_MF) ? "fpu exception" : | 826 | char *str = (trapnr == X86_TRAP_MF) ? "fpu exception" : |
850 | "simd exception"; | 827 | "simd exception"; |
851 | 828 | ||
@@ -871,18 +848,14 @@ static void math_error(struct pt_regs *regs, int error_code, int trapnr) | |||
871 | 848 | ||
872 | task->thread.trap_nr = trapnr; | 849 | task->thread.trap_nr = trapnr; |
873 | task->thread.error_code = error_code; | 850 | task->thread.error_code = error_code; |
874 | clear_siginfo(&info); | ||
875 | info.si_signo = SIGFPE; | ||
876 | info.si_errno = 0; | ||
877 | info.si_addr = (void __user *)uprobe_get_trap_addr(regs); | ||
878 | |||
879 | info.si_code = fpu__exception_code(fpu, trapnr); | ||
880 | 851 | ||
852 | si_code = fpu__exception_code(fpu, trapnr); | ||
881 | /* Retry when we get spurious exceptions: */ | 853 | /* Retry when we get spurious exceptions: */ |
882 | if (!info.si_code) | 854 | if (!si_code) |
883 | return; | 855 | return; |
884 | 856 | ||
885 | force_sig_info(SIGFPE, &info, task); | 857 | force_sig_fault(SIGFPE, si_code, |
858 | (void __user *)uprobe_get_trap_addr(regs), task); | ||
886 | } | 859 | } |
887 | 860 | ||
888 | dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) | 861 | dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) |
@@ -942,20 +915,13 @@ NOKPROBE_SYMBOL(do_device_not_available); | |||
942 | #ifdef CONFIG_X86_32 | 915 | #ifdef CONFIG_X86_32 |
943 | dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) | 916 | dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) |
944 | { | 917 | { |
945 | siginfo_t info; | ||
946 | |||
947 | RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); | 918 | RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU"); |
948 | local_irq_enable(); | 919 | local_irq_enable(); |
949 | 920 | ||
950 | clear_siginfo(&info); | ||
951 | info.si_signo = SIGILL; | ||
952 | info.si_errno = 0; | ||
953 | info.si_code = ILL_BADSTK; | ||
954 | info.si_addr = NULL; | ||
955 | if (notify_die(DIE_TRAP, "iret exception", regs, error_code, | 921 | if (notify_die(DIE_TRAP, "iret exception", regs, error_code, |
956 | X86_TRAP_IRET, SIGILL) != NOTIFY_STOP) { | 922 | X86_TRAP_IRET, SIGILL) != NOTIFY_STOP) { |
957 | do_trap(X86_TRAP_IRET, SIGILL, "iret exception", regs, error_code, | 923 | do_trap(X86_TRAP_IRET, SIGILL, "iret exception", regs, error_code, |
958 | &info); | 924 | ILL_BADSTK, (void __user *)NULL); |
959 | } | 925 | } |
960 | } | 926 | } |
961 | #endif | 927 | #endif |
diff --git a/arch/x86/kernel/umip.c b/arch/x86/kernel/umip.c index ff20b35e98dd..f8f3cfda01ae 100644 --- a/arch/x86/kernel/umip.c +++ b/arch/x86/kernel/umip.c | |||
@@ -271,19 +271,13 @@ static int emulate_umip_insn(struct insn *insn, int umip_inst, | |||
271 | */ | 271 | */ |
272 | static void force_sig_info_umip_fault(void __user *addr, struct pt_regs *regs) | 272 | static void force_sig_info_umip_fault(void __user *addr, struct pt_regs *regs) |
273 | { | 273 | { |
274 | siginfo_t info; | ||
275 | struct task_struct *tsk = current; | 274 | struct task_struct *tsk = current; |
276 | 275 | ||
277 | tsk->thread.cr2 = (unsigned long)addr; | 276 | tsk->thread.cr2 = (unsigned long)addr; |
278 | tsk->thread.error_code = X86_PF_USER | X86_PF_WRITE; | 277 | tsk->thread.error_code = X86_PF_USER | X86_PF_WRITE; |
279 | tsk->thread.trap_nr = X86_TRAP_PF; | 278 | tsk->thread.trap_nr = X86_TRAP_PF; |
280 | 279 | ||
281 | clear_siginfo(&info); | 280 | force_sig_fault(SIGSEGV, SEGV_MAPERR, addr, tsk); |
282 | info.si_signo = SIGSEGV; | ||
283 | info.si_errno = 0; | ||
284 | info.si_code = SEGV_MAPERR; | ||
285 | info.si_addr = addr; | ||
286 | force_sig_info(SIGSEGV, &info, tsk); | ||
287 | 281 | ||
288 | if (!(show_unhandled_signals && unhandled_signal(tsk, SIGSEGV))) | 282 | if (!(show_unhandled_signals && unhandled_signal(tsk, SIGSEGV))) |
289 | return; | 283 | return; |
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index deb576b23b7c..843feb94a950 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c | |||
@@ -1086,7 +1086,7 @@ arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs | |||
1086 | pr_err("return address clobbered: pid=%d, %%sp=%#lx, %%ip=%#lx\n", | 1086 | pr_err("return address clobbered: pid=%d, %%sp=%#lx, %%ip=%#lx\n", |
1087 | current->pid, regs->sp, regs->ip); | 1087 | current->pid, regs->sp, regs->ip); |
1088 | 1088 | ||
1089 | force_sig_info(SIGSEGV, SEND_SIG_FORCED, current); | 1089 | force_sig(SIGSEGV, current); |
1090 | } | 1090 | } |
1091 | 1091 | ||
1092 | return -1; | 1092 | return -1; |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 51b953ad9d4e..e843ec46609d 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -3125,16 +3125,7 @@ static int __direct_map(struct kvm_vcpu *vcpu, int write, int map_writable, | |||
3125 | 3125 | ||
3126 | static void kvm_send_hwpoison_signal(unsigned long address, struct task_struct *tsk) | 3126 | static void kvm_send_hwpoison_signal(unsigned long address, struct task_struct *tsk) |
3127 | { | 3127 | { |
3128 | siginfo_t info; | 3128 | send_sig_mceerr(BUS_MCEERR_AR, (void __user *)address, PAGE_SHIFT, tsk); |
3129 | |||
3130 | clear_siginfo(&info); | ||
3131 | info.si_signo = SIGBUS; | ||
3132 | info.si_errno = 0; | ||
3133 | info.si_code = BUS_MCEERR_AR; | ||
3134 | info.si_addr = (void __user *)address; | ||
3135 | info.si_addr_lsb = PAGE_SHIFT; | ||
3136 | |||
3137 | send_sig_info(SIGBUS, &info, tsk); | ||
3138 | } | 3129 | } |
3139 | 3130 | ||
3140 | static int kvm_handle_bad_page(struct kvm_vcpu *vcpu, gfn_t gfn, kvm_pfn_t pfn) | 3131 | static int kvm_handle_bad_page(struct kvm_vcpu *vcpu, gfn_t gfn, kvm_pfn_t pfn) |
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 2b1519bc5381..b24eb4eb9984 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -157,79 +157,6 @@ is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr) | |||
157 | return prefetch; | 157 | return prefetch; |
158 | } | 158 | } |
159 | 159 | ||
160 | /* | ||
161 | * A protection key fault means that the PKRU value did not allow | ||
162 | * access to some PTE. Userspace can figure out what PKRU was | ||
163 | * from the XSAVE state, and this function fills out a field in | ||
164 | * siginfo so userspace can discover which protection key was set | ||
165 | * on the PTE. | ||
166 | * | ||
167 | * If we get here, we know that the hardware signaled a X86_PF_PK | ||
168 | * fault and that there was a VMA once we got in the fault | ||
169 | * handler. It does *not* guarantee that the VMA we find here | ||
170 | * was the one that we faulted on. | ||
171 | * | ||
172 | * 1. T1 : mprotect_key(foo, PAGE_SIZE, pkey=4); | ||
173 | * 2. T1 : set PKRU to deny access to pkey=4, touches page | ||
174 | * 3. T1 : faults... | ||
175 | * 4. T2: mprotect_key(foo, PAGE_SIZE, pkey=5); | ||
176 | * 5. T1 : enters fault handler, takes mmap_sem, etc... | ||
177 | * 6. T1 : reaches here, sees vma_pkey(vma)=5, when we really | ||
178 | * faulted on a pte with its pkey=4. | ||
179 | */ | ||
180 | static void fill_sig_info_pkey(int si_signo, int si_code, siginfo_t *info, | ||
181 | u32 *pkey) | ||
182 | { | ||
183 | /* This is effectively an #ifdef */ | ||
184 | if (!boot_cpu_has(X86_FEATURE_OSPKE)) | ||
185 | return; | ||
186 | |||
187 | /* Fault not from Protection Keys: nothing to do */ | ||
188 | if ((si_code != SEGV_PKUERR) || (si_signo != SIGSEGV)) | ||
189 | return; | ||
190 | /* | ||
191 | * force_sig_info_fault() is called from a number of | ||
192 | * contexts, some of which have a VMA and some of which | ||
193 | * do not. The X86_PF_PK handing happens after we have a | ||
194 | * valid VMA, so we should never reach this without a | ||
195 | * valid VMA. | ||
196 | */ | ||
197 | if (!pkey) { | ||
198 | WARN_ONCE(1, "PKU fault with no VMA passed in"); | ||
199 | info->si_pkey = 0; | ||
200 | return; | ||
201 | } | ||
202 | /* | ||
203 | * si_pkey should be thought of as a strong hint, but not | ||
204 | * absolutely guranteed to be 100% accurate because of | ||
205 | * the race explained above. | ||
206 | */ | ||
207 | info->si_pkey = *pkey; | ||
208 | } | ||
209 | |||
210 | static void | ||
211 | force_sig_info_fault(int si_signo, int si_code, unsigned long address, | ||
212 | struct task_struct *tsk, u32 *pkey, int fault) | ||
213 | { | ||
214 | unsigned lsb = 0; | ||
215 | siginfo_t info; | ||
216 | |||
217 | clear_siginfo(&info); | ||
218 | info.si_signo = si_signo; | ||
219 | info.si_errno = 0; | ||
220 | info.si_code = si_code; | ||
221 | info.si_addr = (void __user *)address; | ||
222 | if (fault & VM_FAULT_HWPOISON_LARGE) | ||
223 | lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault)); | ||
224 | if (fault & VM_FAULT_HWPOISON) | ||
225 | lsb = PAGE_SHIFT; | ||
226 | info.si_addr_lsb = lsb; | ||
227 | |||
228 | fill_sig_info_pkey(si_signo, si_code, &info, pkey); | ||
229 | |||
230 | force_sig_info(si_signo, &info, tsk); | ||
231 | } | ||
232 | |||
233 | DEFINE_SPINLOCK(pgd_lock); | 160 | DEFINE_SPINLOCK(pgd_lock); |
234 | LIST_HEAD(pgd_list); | 161 | LIST_HEAD(pgd_list); |
235 | 162 | ||
@@ -734,8 +661,8 @@ no_context(struct pt_regs *regs, unsigned long error_code, | |||
734 | tsk->thread.cr2 = address; | 661 | tsk->thread.cr2 = address; |
735 | 662 | ||
736 | /* XXX: hwpoison faults will set the wrong code. */ | 663 | /* XXX: hwpoison faults will set the wrong code. */ |
737 | force_sig_info_fault(signal, si_code, address, | 664 | force_sig_fault(signal, si_code, (void __user *)address, |
738 | tsk, NULL, 0); | 665 | tsk); |
739 | } | 666 | } |
740 | 667 | ||
741 | /* | 668 | /* |
@@ -862,7 +789,7 @@ static bool is_vsyscall_vaddr(unsigned long vaddr) | |||
862 | 789 | ||
863 | static void | 790 | static void |
864 | __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, | 791 | __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, |
865 | unsigned long address, u32 *pkey, int si_code) | 792 | unsigned long address, u32 pkey, int si_code) |
866 | { | 793 | { |
867 | struct task_struct *tsk = current; | 794 | struct task_struct *tsk = current; |
868 | 795 | ||
@@ -898,7 +825,10 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, | |||
898 | tsk->thread.error_code = error_code; | 825 | tsk->thread.error_code = error_code; |
899 | tsk->thread.trap_nr = X86_TRAP_PF; | 826 | tsk->thread.trap_nr = X86_TRAP_PF; |
900 | 827 | ||
901 | force_sig_info_fault(SIGSEGV, si_code, address, tsk, pkey, 0); | 828 | if (si_code == SEGV_PKUERR) |
829 | force_sig_pkuerr((void __user *)address, pkey); | ||
830 | |||
831 | force_sig_fault(SIGSEGV, si_code, (void __user *)address, tsk); | ||
902 | 832 | ||
903 | return; | 833 | return; |
904 | } | 834 | } |
@@ -911,35 +841,29 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, | |||
911 | 841 | ||
912 | static noinline void | 842 | static noinline void |
913 | bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, | 843 | bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, |
914 | unsigned long address, u32 *pkey) | 844 | unsigned long address) |
915 | { | 845 | { |
916 | __bad_area_nosemaphore(regs, error_code, address, pkey, SEGV_MAPERR); | 846 | __bad_area_nosemaphore(regs, error_code, address, 0, SEGV_MAPERR); |
917 | } | 847 | } |
918 | 848 | ||
919 | static void | 849 | static void |
920 | __bad_area(struct pt_regs *regs, unsigned long error_code, | 850 | __bad_area(struct pt_regs *regs, unsigned long error_code, |
921 | unsigned long address, struct vm_area_struct *vma, int si_code) | 851 | unsigned long address, u32 pkey, int si_code) |
922 | { | 852 | { |
923 | struct mm_struct *mm = current->mm; | 853 | struct mm_struct *mm = current->mm; |
924 | u32 pkey; | ||
925 | |||
926 | if (vma) | ||
927 | pkey = vma_pkey(vma); | ||
928 | |||
929 | /* | 854 | /* |
930 | * Something tried to access memory that isn't in our memory map.. | 855 | * Something tried to access memory that isn't in our memory map.. |
931 | * Fix it, but check if it's kernel or user first.. | 856 | * Fix it, but check if it's kernel or user first.. |
932 | */ | 857 | */ |
933 | up_read(&mm->mmap_sem); | 858 | up_read(&mm->mmap_sem); |
934 | 859 | ||
935 | __bad_area_nosemaphore(regs, error_code, address, | 860 | __bad_area_nosemaphore(regs, error_code, address, pkey, si_code); |
936 | (vma) ? &pkey : NULL, si_code); | ||
937 | } | 861 | } |
938 | 862 | ||
939 | static noinline void | 863 | static noinline void |
940 | bad_area(struct pt_regs *regs, unsigned long error_code, unsigned long address) | 864 | bad_area(struct pt_regs *regs, unsigned long error_code, unsigned long address) |
941 | { | 865 | { |
942 | __bad_area(regs, error_code, address, NULL, SEGV_MAPERR); | 866 | __bad_area(regs, error_code, address, 0, SEGV_MAPERR); |
943 | } | 867 | } |
944 | 868 | ||
945 | static inline bool bad_area_access_from_pkeys(unsigned long error_code, | 869 | static inline bool bad_area_access_from_pkeys(unsigned long error_code, |
@@ -968,18 +892,40 @@ bad_area_access_error(struct pt_regs *regs, unsigned long error_code, | |||
968 | * But, doing it this way allows compiler optimizations | 892 | * But, doing it this way allows compiler optimizations |
969 | * if pkeys are compiled out. | 893 | * if pkeys are compiled out. |
970 | */ | 894 | */ |
971 | if (bad_area_access_from_pkeys(error_code, vma)) | 895 | if (bad_area_access_from_pkeys(error_code, vma)) { |
972 | __bad_area(regs, error_code, address, vma, SEGV_PKUERR); | 896 | /* |
973 | else | 897 | * A protection key fault means that the PKRU value did not allow |
974 | __bad_area(regs, error_code, address, vma, SEGV_ACCERR); | 898 | * access to some PTE. Userspace can figure out what PKRU was |
899 | * from the XSAVE state. This function captures the pkey from | ||
900 | * the vma and passes it to userspace so userspace can discover | ||
901 | * which protection key was set on the PTE. | ||
902 | * | ||
903 | * If we get here, we know that the hardware signaled a X86_PF_PK | ||
904 | * fault and that there was a VMA once we got in the fault | ||
905 | * handler. It does *not* guarantee that the VMA we find here | ||
906 | * was the one that we faulted on. | ||
907 | * | ||
908 | * 1. T1 : mprotect_key(foo, PAGE_SIZE, pkey=4); | ||
909 | * 2. T1 : set PKRU to deny access to pkey=4, touches page | ||
910 | * 3. T1 : faults... | ||
911 | * 4. T2: mprotect_key(foo, PAGE_SIZE, pkey=5); | ||
912 | * 5. T1 : enters fault handler, takes mmap_sem, etc... | ||
913 | * 6. T1 : reaches here, sees vma_pkey(vma)=5, when we really | ||
914 | * faulted on a pte with its pkey=4. | ||
915 | */ | ||
916 | u32 pkey = vma_pkey(vma); | ||
917 | |||
918 | __bad_area(regs, error_code, address, pkey, SEGV_PKUERR); | ||
919 | } else { | ||
920 | __bad_area(regs, error_code, address, 0, SEGV_ACCERR); | ||
921 | } | ||
975 | } | 922 | } |
976 | 923 | ||
977 | static void | 924 | static void |
978 | do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, | 925 | do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, |
979 | u32 *pkey, unsigned int fault) | 926 | unsigned int fault) |
980 | { | 927 | { |
981 | struct task_struct *tsk = current; | 928 | struct task_struct *tsk = current; |
982 | int code = BUS_ADRERR; | ||
983 | 929 | ||
984 | /* Kernel mode? Handle exceptions or die: */ | 930 | /* Kernel mode? Handle exceptions or die: */ |
985 | if (!(error_code & X86_PF_USER)) { | 931 | if (!(error_code & X86_PF_USER)) { |
@@ -997,18 +943,25 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, | |||
997 | 943 | ||
998 | #ifdef CONFIG_MEMORY_FAILURE | 944 | #ifdef CONFIG_MEMORY_FAILURE |
999 | if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) { | 945 | if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) { |
1000 | printk(KERN_ERR | 946 | unsigned lsb = 0; |
947 | |||
948 | pr_err( | ||
1001 | "MCE: Killing %s:%d due to hardware memory corruption fault at %lx\n", | 949 | "MCE: Killing %s:%d due to hardware memory corruption fault at %lx\n", |
1002 | tsk->comm, tsk->pid, address); | 950 | tsk->comm, tsk->pid, address); |
1003 | code = BUS_MCEERR_AR; | 951 | if (fault & VM_FAULT_HWPOISON_LARGE) |
952 | lsb = hstate_index_to_shift(VM_FAULT_GET_HINDEX(fault)); | ||
953 | if (fault & VM_FAULT_HWPOISON) | ||
954 | lsb = PAGE_SHIFT; | ||
955 | force_sig_mceerr(BUS_MCEERR_AR, (void __user *)address, lsb, tsk); | ||
956 | return; | ||
1004 | } | 957 | } |
1005 | #endif | 958 | #endif |
1006 | force_sig_info_fault(SIGBUS, code, address, tsk, pkey, fault); | 959 | force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)address, tsk); |
1007 | } | 960 | } |
1008 | 961 | ||
1009 | static noinline void | 962 | static noinline void |
1010 | mm_fault_error(struct pt_regs *regs, unsigned long error_code, | 963 | mm_fault_error(struct pt_regs *regs, unsigned long error_code, |
1011 | unsigned long address, u32 *pkey, vm_fault_t fault) | 964 | unsigned long address, vm_fault_t fault) |
1012 | { | 965 | { |
1013 | if (fatal_signal_pending(current) && !(error_code & X86_PF_USER)) { | 966 | if (fatal_signal_pending(current) && !(error_code & X86_PF_USER)) { |
1014 | no_context(regs, error_code, address, 0, 0); | 967 | no_context(regs, error_code, address, 0, 0); |
@@ -1032,9 +985,9 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code, | |||
1032 | } else { | 985 | } else { |
1033 | if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON| | 986 | if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON| |
1034 | VM_FAULT_HWPOISON_LARGE)) | 987 | VM_FAULT_HWPOISON_LARGE)) |
1035 | do_sigbus(regs, error_code, address, pkey, fault); | 988 | do_sigbus(regs, error_code, address, fault); |
1036 | else if (fault & VM_FAULT_SIGSEGV) | 989 | else if (fault & VM_FAULT_SIGSEGV) |
1037 | bad_area_nosemaphore(regs, error_code, address, pkey); | 990 | bad_area_nosemaphore(regs, error_code, address); |
1038 | else | 991 | else |
1039 | BUG(); | 992 | BUG(); |
1040 | } | 993 | } |
@@ -1267,7 +1220,7 @@ do_kern_addr_fault(struct pt_regs *regs, unsigned long hw_error_code, | |||
1267 | * Don't take the mm semaphore here. If we fixup a prefetch | 1220 | * Don't take the mm semaphore here. If we fixup a prefetch |
1268 | * fault we could otherwise deadlock: | 1221 | * fault we could otherwise deadlock: |
1269 | */ | 1222 | */ |
1270 | bad_area_nosemaphore(regs, hw_error_code, address, NULL); | 1223 | bad_area_nosemaphore(regs, hw_error_code, address); |
1271 | } | 1224 | } |
1272 | NOKPROBE_SYMBOL(do_kern_addr_fault); | 1225 | NOKPROBE_SYMBOL(do_kern_addr_fault); |
1273 | 1226 | ||
@@ -1283,7 +1236,6 @@ void do_user_addr_fault(struct pt_regs *regs, | |||
1283 | struct mm_struct *mm; | 1236 | struct mm_struct *mm; |
1284 | vm_fault_t fault, major = 0; | 1237 | vm_fault_t fault, major = 0; |
1285 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; | 1238 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; |
1286 | u32 pkey; | ||
1287 | 1239 | ||
1288 | tsk = current; | 1240 | tsk = current; |
1289 | mm = tsk->mm; | 1241 | mm = tsk->mm; |
@@ -1304,7 +1256,7 @@ void do_user_addr_fault(struct pt_regs *regs, | |||
1304 | * pages in the user address space. | 1256 | * pages in the user address space. |
1305 | */ | 1257 | */ |
1306 | if (unlikely(smap_violation(hw_error_code, regs))) { | 1258 | if (unlikely(smap_violation(hw_error_code, regs))) { |
1307 | bad_area_nosemaphore(regs, hw_error_code, address, NULL); | 1259 | bad_area_nosemaphore(regs, hw_error_code, address); |
1308 | return; | 1260 | return; |
1309 | } | 1261 | } |
1310 | 1262 | ||
@@ -1313,7 +1265,7 @@ void do_user_addr_fault(struct pt_regs *regs, | |||
1313 | * in a region with pagefaults disabled then we must not take the fault | 1265 | * in a region with pagefaults disabled then we must not take the fault |
1314 | */ | 1266 | */ |
1315 | if (unlikely(faulthandler_disabled() || !mm)) { | 1267 | if (unlikely(faulthandler_disabled() || !mm)) { |
1316 | bad_area_nosemaphore(regs, hw_error_code, address, NULL); | 1268 | bad_area_nosemaphore(regs, hw_error_code, address); |
1317 | return; | 1269 | return; |
1318 | } | 1270 | } |
1319 | 1271 | ||
@@ -1403,7 +1355,7 @@ void do_user_addr_fault(struct pt_regs *regs, | |||
1403 | * Fault from code in kernel from | 1355 | * Fault from code in kernel from |
1404 | * which we do not expect faults. | 1356 | * which we do not expect faults. |
1405 | */ | 1357 | */ |
1406 | bad_area_nosemaphore(regs, sw_error_code, address, NULL); | 1358 | bad_area_nosemaphore(regs, sw_error_code, address); |
1407 | return; | 1359 | return; |
1408 | } | 1360 | } |
1409 | retry: | 1361 | retry: |
@@ -1467,10 +1419,7 @@ good_area: | |||
1467 | * (potentially after handling any pending signal during the return to | 1419 | * (potentially after handling any pending signal during the return to |
1468 | * userland). The return to userland is identified whenever | 1420 | * userland). The return to userland is identified whenever |
1469 | * FAULT_FLAG_USER|FAULT_FLAG_KILLABLE are both set in flags. | 1421 | * FAULT_FLAG_USER|FAULT_FLAG_KILLABLE are both set in flags. |
1470 | * Thus we have to be careful about not touching vma after handling the | ||
1471 | * fault, so we read the pkey beforehand. | ||
1472 | */ | 1422 | */ |
1473 | pkey = vma_pkey(vma); | ||
1474 | fault = handle_mm_fault(vma, address, flags); | 1423 | fault = handle_mm_fault(vma, address, flags); |
1475 | major |= fault & VM_FAULT_MAJOR; | 1424 | major |= fault & VM_FAULT_MAJOR; |
1476 | 1425 | ||
@@ -1499,7 +1448,7 @@ good_area: | |||
1499 | 1448 | ||
1500 | up_read(&mm->mmap_sem); | 1449 | up_read(&mm->mmap_sem); |
1501 | if (unlikely(fault & VM_FAULT_ERROR)) { | 1450 | if (unlikely(fault & VM_FAULT_ERROR)) { |
1502 | mm_fault_error(regs, sw_error_code, address, &pkey, fault); | 1451 | mm_fault_error(regs, sw_error_code, address, fault); |
1503 | return; | 1452 | return; |
1504 | } | 1453 | } |
1505 | 1454 | ||
diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c index e500949bae24..2385538e8065 100644 --- a/arch/x86/mm/mpx.c +++ b/arch/x86/mm/mpx.c | |||
@@ -118,14 +118,11 @@ bad_opcode: | |||
118 | * anything it wants in to the instructions. We can not | 118 | * anything it wants in to the instructions. We can not |
119 | * trust anything about it. They might not be valid | 119 | * trust anything about it. They might not be valid |
120 | * instructions or might encode invalid registers, etc... | 120 | * instructions or might encode invalid registers, etc... |
121 | * | ||
122 | * The caller is expected to kfree() the returned siginfo_t. | ||
123 | */ | 121 | */ |
124 | siginfo_t *mpx_generate_siginfo(struct pt_regs *regs) | 122 | int mpx_fault_info(struct mpx_fault_info *info, struct pt_regs *regs) |
125 | { | 123 | { |
126 | const struct mpx_bndreg_state *bndregs; | 124 | const struct mpx_bndreg_state *bndregs; |
127 | const struct mpx_bndreg *bndreg; | 125 | const struct mpx_bndreg *bndreg; |
128 | siginfo_t *info = NULL; | ||
129 | struct insn insn; | 126 | struct insn insn; |
130 | uint8_t bndregno; | 127 | uint8_t bndregno; |
131 | int err; | 128 | int err; |
@@ -153,11 +150,6 @@ siginfo_t *mpx_generate_siginfo(struct pt_regs *regs) | |||
153 | /* now go select the individual register in the set of 4 */ | 150 | /* now go select the individual register in the set of 4 */ |
154 | bndreg = &bndregs->bndreg[bndregno]; | 151 | bndreg = &bndregs->bndreg[bndregno]; |
155 | 152 | ||
156 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
157 | if (!info) { | ||
158 | err = -ENOMEM; | ||
159 | goto err_out; | ||
160 | } | ||
161 | /* | 153 | /* |
162 | * The registers are always 64-bit, but the upper 32 | 154 | * The registers are always 64-bit, but the upper 32 |
163 | * bits are ignored in 32-bit mode. Also, note that the | 155 | * bits are ignored in 32-bit mode. Also, note that the |
@@ -168,27 +160,23 @@ siginfo_t *mpx_generate_siginfo(struct pt_regs *regs) | |||
168 | * complains when casting from integers to different-size | 160 | * complains when casting from integers to different-size |
169 | * pointers. | 161 | * pointers. |
170 | */ | 162 | */ |
171 | info->si_lower = (void __user *)(unsigned long)bndreg->lower_bound; | 163 | info->lower = (void __user *)(unsigned long)bndreg->lower_bound; |
172 | info->si_upper = (void __user *)(unsigned long)~bndreg->upper_bound; | 164 | info->upper = (void __user *)(unsigned long)~bndreg->upper_bound; |
173 | info->si_addr_lsb = 0; | 165 | info->addr = insn_get_addr_ref(&insn, regs); |
174 | info->si_signo = SIGSEGV; | 166 | |
175 | info->si_errno = 0; | ||
176 | info->si_code = SEGV_BNDERR; | ||
177 | info->si_addr = insn_get_addr_ref(&insn, regs); | ||
178 | /* | 167 | /* |
179 | * We were not able to extract an address from the instruction, | 168 | * We were not able to extract an address from the instruction, |
180 | * probably because there was something invalid in it. | 169 | * probably because there was something invalid in it. |
181 | */ | 170 | */ |
182 | if (info->si_addr == (void __user *)-1) { | 171 | if (info->addr == (void __user *)-1) { |
183 | err = -EINVAL; | 172 | err = -EINVAL; |
184 | goto err_out; | 173 | goto err_out; |
185 | } | 174 | } |
186 | trace_mpx_bounds_register_exception(info->si_addr, bndreg); | 175 | trace_mpx_bounds_register_exception(info->addr, bndreg); |
187 | return info; | 176 | return 0; |
188 | err_out: | 177 | err_out: |
189 | /* info might be NULL, but kfree() handles that */ | 178 | /* info might be NULL, but kfree() handles that */ |
190 | kfree(info); | 179 | return err; |
191 | return ERR_PTR(err); | ||
192 | } | 180 | } |
193 | 181 | ||
194 | static __user void *mpx_get_bounds_dir(void) | 182 | static __user void *mpx_get_bounds_dir(void) |
diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h index 120738d6e58b..77ed3967c5b0 100644 --- a/drivers/misc/genwqe/card_base.h +++ b/drivers/misc/genwqe/card_base.h | |||
@@ -408,7 +408,7 @@ struct genwqe_file { | |||
408 | struct file *filp; | 408 | struct file *filp; |
409 | 409 | ||
410 | struct fasync_struct *async_queue; | 410 | struct fasync_struct *async_queue; |
411 | struct task_struct *owner; | 411 | struct pid *opener; |
412 | struct list_head list; /* entry in list of open files */ | 412 | struct list_head list; /* entry in list of open files */ |
413 | 413 | ||
414 | spinlock_t map_lock; /* lock for dma_mappings */ | 414 | spinlock_t map_lock; /* lock for dma_mappings */ |
diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c index f453ab82f0d7..8c1b63a4337b 100644 --- a/drivers/misc/genwqe/card_dev.c +++ b/drivers/misc/genwqe/card_dev.c | |||
@@ -52,7 +52,7 @@ static void genwqe_add_file(struct genwqe_dev *cd, struct genwqe_file *cfile) | |||
52 | { | 52 | { |
53 | unsigned long flags; | 53 | unsigned long flags; |
54 | 54 | ||
55 | cfile->owner = current; | 55 | cfile->opener = get_pid(task_tgid(current)); |
56 | spin_lock_irqsave(&cd->file_lock, flags); | 56 | spin_lock_irqsave(&cd->file_lock, flags); |
57 | list_add(&cfile->list, &cd->file_list); | 57 | list_add(&cfile->list, &cd->file_list); |
58 | spin_unlock_irqrestore(&cd->file_lock, flags); | 58 | spin_unlock_irqrestore(&cd->file_lock, flags); |
@@ -65,6 +65,7 @@ static int genwqe_del_file(struct genwqe_dev *cd, struct genwqe_file *cfile) | |||
65 | spin_lock_irqsave(&cd->file_lock, flags); | 65 | spin_lock_irqsave(&cd->file_lock, flags); |
66 | list_del(&cfile->list); | 66 | list_del(&cfile->list); |
67 | spin_unlock_irqrestore(&cd->file_lock, flags); | 67 | spin_unlock_irqrestore(&cd->file_lock, flags); |
68 | put_pid(cfile->opener); | ||
68 | 69 | ||
69 | return 0; | 70 | return 0; |
70 | } | 71 | } |
@@ -275,7 +276,7 @@ static int genwqe_kill_fasync(struct genwqe_dev *cd, int sig) | |||
275 | return files; | 276 | return files; |
276 | } | 277 | } |
277 | 278 | ||
278 | static int genwqe_force_sig(struct genwqe_dev *cd, int sig) | 279 | static int genwqe_terminate(struct genwqe_dev *cd) |
279 | { | 280 | { |
280 | unsigned int files = 0; | 281 | unsigned int files = 0; |
281 | unsigned long flags; | 282 | unsigned long flags; |
@@ -283,7 +284,7 @@ static int genwqe_force_sig(struct genwqe_dev *cd, int sig) | |||
283 | 284 | ||
284 | spin_lock_irqsave(&cd->file_lock, flags); | 285 | spin_lock_irqsave(&cd->file_lock, flags); |
285 | list_for_each_entry(cfile, &cd->file_list, list) { | 286 | list_for_each_entry(cfile, &cd->file_list, list) { |
286 | force_sig(sig, cfile->owner); | 287 | kill_pid(cfile->opener, SIGKILL, 1); |
287 | files++; | 288 | files++; |
288 | } | 289 | } |
289 | spin_unlock_irqrestore(&cd->file_lock, flags); | 290 | spin_unlock_irqrestore(&cd->file_lock, flags); |
@@ -1352,7 +1353,7 @@ static int genwqe_inform_and_stop_processes(struct genwqe_dev *cd) | |||
1352 | dev_warn(&pci_dev->dev, | 1353 | dev_warn(&pci_dev->dev, |
1353 | "[%s] send SIGKILL and wait ...\n", __func__); | 1354 | "[%s] send SIGKILL and wait ...\n", __func__); |
1354 | 1355 | ||
1355 | rc = genwqe_force_sig(cd, SIGKILL); /* force terminate */ | 1356 | rc = genwqe_terminate(cd); |
1356 | if (rc) { | 1357 | if (rc) { |
1357 | /* Give kill_timout more seconds to end processes */ | 1358 | /* Give kill_timout more seconds to end processes */ |
1358 | for (i = 0; (i < GENWQE_KILL_TIMEOUT) && | 1359 | for (i = 0; (i < GENWQE_KILL_TIMEOUT) && |
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 06ed20dd01ba..ad1ee5d01b53 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c | |||
@@ -348,7 +348,7 @@ static void send_sig_all(int sig) | |||
348 | if (is_global_init(p)) | 348 | if (is_global_init(p)) |
349 | continue; | 349 | continue; |
350 | 350 | ||
351 | do_send_sig_info(sig, SEND_SIG_FORCED, p, PIDTYPE_MAX); | 351 | do_send_sig_info(sig, SEND_SIG_PRIV, p, PIDTYPE_MAX); |
352 | } | 352 | } |
353 | read_unlock(&tasklist_lock); | 353 | read_unlock(&tasklist_lock); |
354 | } | 354 | } |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 5e5da9acaf0a..816d8ba971a2 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -2743,7 +2743,7 @@ void __do_SAK(struct tty_struct *tty) | |||
2743 | do_each_pid_task(session, PIDTYPE_SID, p) { | 2743 | do_each_pid_task(session, PIDTYPE_SID, p) { |
2744 | tty_notice(tty, "SAK: killed process %d (%s): by session\n", | 2744 | tty_notice(tty, "SAK: killed process %d (%s): by session\n", |
2745 | task_pid_nr(p), p->comm); | 2745 | task_pid_nr(p), p->comm); |
2746 | send_sig(SIGKILL, p, 1); | 2746 | group_send_sig_info(SIGKILL, SEND_SIG_PRIV, p, PIDTYPE_SID); |
2747 | } while_each_pid_task(session, PIDTYPE_SID, p); | 2747 | } while_each_pid_task(session, PIDTYPE_SID, p); |
2748 | 2748 | ||
2749 | /* Now kill any processes that happen to have the tty open */ | 2749 | /* Now kill any processes that happen to have the tty open */ |
@@ -2751,7 +2751,7 @@ void __do_SAK(struct tty_struct *tty) | |||
2751 | if (p->signal->tty == tty) { | 2751 | if (p->signal->tty == tty) { |
2752 | tty_notice(tty, "SAK: killed process %d (%s): by controlling tty\n", | 2752 | tty_notice(tty, "SAK: killed process %d (%s): by controlling tty\n", |
2753 | task_pid_nr(p), p->comm); | 2753 | task_pid_nr(p), p->comm); |
2754 | send_sig(SIGKILL, p, 1); | 2754 | group_send_sig_info(SIGKILL, SEND_SIG_PRIV, p, PIDTYPE_SID); |
2755 | continue; | 2755 | continue; |
2756 | } | 2756 | } |
2757 | task_lock(p); | 2757 | task_lock(p); |
@@ -2759,7 +2759,7 @@ void __do_SAK(struct tty_struct *tty) | |||
2759 | if (i != 0) { | 2759 | if (i != 0) { |
2760 | tty_notice(tty, "SAK: killed process %d (%s): by fd#%d\n", | 2760 | tty_notice(tty, "SAK: killed process %d (%s): by fd#%d\n", |
2761 | task_pid_nr(p), p->comm, i - 1); | 2761 | task_pid_nr(p), p->comm, i - 1); |
2762 | force_sig(SIGKILL, p); | 2762 | group_send_sig_info(SIGKILL, SEND_SIG_PRIV, p, PIDTYPE_SID); |
2763 | } | 2763 | } |
2764 | task_unlock(p); | 2764 | task_unlock(p); |
2765 | } while_each_thread(g, p); | 2765 | } while_each_thread(g, p); |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index ffccd40ea67d..a75bc0b8a50f 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -582,7 +582,7 @@ static void async_completed(struct urb *urb) | |||
582 | { | 582 | { |
583 | struct async *as = urb->context; | 583 | struct async *as = urb->context; |
584 | struct usb_dev_state *ps = as->ps; | 584 | struct usb_dev_state *ps = as->ps; |
585 | struct siginfo sinfo; | 585 | struct kernel_siginfo sinfo; |
586 | struct pid *pid = NULL; | 586 | struct pid *pid = NULL; |
587 | const struct cred *cred = NULL; | 587 | const struct cred *cred = NULL; |
588 | unsigned long flags; | 588 | unsigned long flags; |
@@ -2617,7 +2617,7 @@ const struct file_operations usbdev_file_operations = { | |||
2617 | static void usbdev_remove(struct usb_device *udev) | 2617 | static void usbdev_remove(struct usb_device *udev) |
2618 | { | 2618 | { |
2619 | struct usb_dev_state *ps; | 2619 | struct usb_dev_state *ps; |
2620 | struct siginfo sinfo; | 2620 | struct kernel_siginfo sinfo; |
2621 | 2621 | ||
2622 | while (!list_empty(&udev->filelist)) { | 2622 | while (!list_empty(&udev->filelist)) { |
2623 | ps = list_entry(udev->filelist.next, struct usb_dev_state, list); | 2623 | ps = list_entry(udev->filelist.next, struct usb_dev_state, list); |
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index 1074cb82ec17..043f97ad8f22 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c | |||
@@ -405,7 +405,7 @@ static void raise_exception(struct fsg_common *common, enum fsg_state new_state) | |||
405 | common->exception_req_tag = common->ep0_req_tag; | 405 | common->exception_req_tag = common->ep0_req_tag; |
406 | common->state = new_state; | 406 | common->state = new_state; |
407 | if (common->thread_task) | 407 | if (common->thread_task) |
408 | send_sig_info(SIGUSR1, SEND_SIG_FORCED, | 408 | send_sig_info(SIGUSR1, SEND_SIG_PRIV, |
409 | common->thread_task); | 409 | common->thread_task); |
410 | } | 410 | } |
411 | spin_unlock_irqrestore(&common->lock, flags); | 411 | spin_unlock_irqrestore(&common->lock, flags); |
@@ -2313,7 +2313,7 @@ static void handle_exception(struct fsg_common *common) | |||
2313 | * into a high-priority EXIT exception. | 2313 | * into a high-priority EXIT exception. |
2314 | */ | 2314 | */ |
2315 | for (;;) { | 2315 | for (;;) { |
2316 | int sig = kernel_dequeue_signal(NULL); | 2316 | int sig = kernel_dequeue_signal(); |
2317 | if (!sig) | 2317 | if (!sig) |
2318 | break; | 2318 | break; |
2319 | if (sig != SIGUSR1) { | 2319 | if (sig != SIGUSR1) { |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index efae2fb0930a..54207327f98f 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -1580,7 +1580,7 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm) | |||
1580 | } | 1580 | } |
1581 | 1581 | ||
1582 | static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata, | 1582 | static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata, |
1583 | const siginfo_t *siginfo) | 1583 | const kernel_siginfo_t *siginfo) |
1584 | { | 1584 | { |
1585 | mm_segment_t old_fs = get_fs(); | 1585 | mm_segment_t old_fs = get_fs(); |
1586 | set_fs(KERNEL_DS); | 1586 | set_fs(KERNEL_DS); |
@@ -1782,7 +1782,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, | |||
1782 | 1782 | ||
1783 | static int fill_note_info(struct elfhdr *elf, int phdrs, | 1783 | static int fill_note_info(struct elfhdr *elf, int phdrs, |
1784 | struct elf_note_info *info, | 1784 | struct elf_note_info *info, |
1785 | const siginfo_t *siginfo, struct pt_regs *regs) | 1785 | const kernel_siginfo_t *siginfo, struct pt_regs *regs) |
1786 | { | 1786 | { |
1787 | struct task_struct *dump_task = current; | 1787 | struct task_struct *dump_task = current; |
1788 | const struct user_regset_view *view = task_user_regset_view(dump_task); | 1788 | const struct user_regset_view *view = task_user_regset_view(dump_task); |
@@ -2031,7 +2031,7 @@ static int elf_note_info_init(struct elf_note_info *info) | |||
2031 | 2031 | ||
2032 | static int fill_note_info(struct elfhdr *elf, int phdrs, | 2032 | static int fill_note_info(struct elfhdr *elf, int phdrs, |
2033 | struct elf_note_info *info, | 2033 | struct elf_note_info *info, |
2034 | const siginfo_t *siginfo, struct pt_regs *regs) | 2034 | const kernel_siginfo_t *siginfo, struct pt_regs *regs) |
2035 | { | 2035 | { |
2036 | struct list_head *t; | 2036 | struct list_head *t; |
2037 | struct core_thread *ct; | 2037 | struct core_thread *ct; |
diff --git a/fs/coredump.c b/fs/coredump.c index 1e2c87acac9b..e42e17e55bfd 100644 --- a/fs/coredump.c +++ b/fs/coredump.c | |||
@@ -536,7 +536,7 @@ static int umh_pipe_setup(struct subprocess_info *info, struct cred *new) | |||
536 | return err; | 536 | return err; |
537 | } | 537 | } |
538 | 538 | ||
539 | void do_coredump(const siginfo_t *siginfo) | 539 | void do_coredump(const kernel_siginfo_t *siginfo) |
540 | { | 540 | { |
541 | struct core_state core_state; | 541 | struct core_state core_state; |
542 | struct core_name cn; | 542 | struct core_name cn; |
diff --git a/fs/fcntl.c b/fs/fcntl.c index 4137d96534a6..083185174c6d 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -735,7 +735,7 @@ static void send_sigio_to_task(struct task_struct *p, | |||
735 | return; | 735 | return; |
736 | 736 | ||
737 | switch (signum) { | 737 | switch (signum) { |
738 | siginfo_t si; | 738 | kernel_siginfo_t si; |
739 | default: | 739 | default: |
740 | /* Queue a rt signal with the appropriate fd as its | 740 | /* Queue a rt signal with the appropriate fd as its |
741 | value. We use SI_SIGIO as the source, not | 741 | value. We use SI_SIGIO as the source, not |
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c index 453a6a1fff34..2b4d5013dc5d 100644 --- a/fs/jffs2/background.c +++ b/fs/jffs2/background.c | |||
@@ -125,7 +125,7 @@ static int jffs2_garbage_collect_thread(void *_c) | |||
125 | if (try_to_freeze()) | 125 | if (try_to_freeze()) |
126 | goto again; | 126 | goto again; |
127 | 127 | ||
128 | signr = kernel_dequeue_signal(NULL); | 128 | signr = kernel_dequeue_signal(); |
129 | 129 | ||
130 | switch(signr) { | 130 | switch(signr) { |
131 | case SIGSTOP: | 131 | case SIGSTOP: |
diff --git a/fs/signalfd.c b/fs/signalfd.c index 4fcd1498acf5..757afc7c5895 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c | |||
@@ -79,7 +79,7 @@ static __poll_t signalfd_poll(struct file *file, poll_table *wait) | |||
79 | * Copied from copy_siginfo_to_user() in kernel/signal.c | 79 | * Copied from copy_siginfo_to_user() in kernel/signal.c |
80 | */ | 80 | */ |
81 | static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo, | 81 | static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo, |
82 | siginfo_t const *kinfo) | 82 | kernel_siginfo_t const *kinfo) |
83 | { | 83 | { |
84 | struct signalfd_siginfo new; | 84 | struct signalfd_siginfo new; |
85 | 85 | ||
@@ -163,7 +163,7 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo, | |||
163 | return sizeof(*uinfo); | 163 | return sizeof(*uinfo); |
164 | } | 164 | } |
165 | 165 | ||
166 | static ssize_t signalfd_dequeue(struct signalfd_ctx *ctx, siginfo_t *info, | 166 | static ssize_t signalfd_dequeue(struct signalfd_ctx *ctx, kernel_siginfo_t *info, |
167 | int nonblock) | 167 | int nonblock) |
168 | { | 168 | { |
169 | ssize_t ret; | 169 | ssize_t ret; |
@@ -215,7 +215,7 @@ static ssize_t signalfd_read(struct file *file, char __user *buf, size_t count, | |||
215 | struct signalfd_siginfo __user *siginfo; | 215 | struct signalfd_siginfo __user *siginfo; |
216 | int nonblock = file->f_flags & O_NONBLOCK; | 216 | int nonblock = file->f_flags & O_NONBLOCK; |
217 | ssize_t ret, total = 0; | 217 | ssize_t ret, total = 0; |
218 | siginfo_t info; | 218 | kernel_siginfo_t info; |
219 | 219 | ||
220 | count /= sizeof(struct signalfd_siginfo); | 220 | count /= sizeof(struct signalfd_siginfo); |
221 | if (!count) | 221 | if (!count) |
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index c05f24fac4f6..e9f5fe69df31 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h | |||
@@ -78,7 +78,7 @@ struct linux_binprm { | |||
78 | 78 | ||
79 | /* Function parameter for binfmt->coredump */ | 79 | /* Function parameter for binfmt->coredump */ |
80 | struct coredump_params { | 80 | struct coredump_params { |
81 | const siginfo_t *siginfo; | 81 | const kernel_siginfo_t *siginfo; |
82 | struct pt_regs *regs; | 82 | struct pt_regs *regs; |
83 | struct file *file; | 83 | struct file *file; |
84 | unsigned long limit; | 84 | unsigned long limit; |
diff --git a/include/linux/compat.h b/include/linux/compat.h index de0c13bdcd2c..e75b926bc5df 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
@@ -455,8 +455,8 @@ long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask, | |||
455 | unsigned long bitmap_size); | 455 | unsigned long bitmap_size); |
456 | long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask, | 456 | long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask, |
457 | unsigned long bitmap_size); | 457 | unsigned long bitmap_size); |
458 | int copy_siginfo_from_user32(siginfo_t *to, const struct compat_siginfo __user *from); | 458 | int copy_siginfo_from_user32(kernel_siginfo_t *to, const struct compat_siginfo __user *from); |
459 | int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *from); | 459 | int copy_siginfo_to_user32(struct compat_siginfo __user *to, const kernel_siginfo_t *from); |
460 | int get_compat_sigevent(struct sigevent *event, | 460 | int get_compat_sigevent(struct sigevent *event, |
461 | const struct compat_sigevent __user *u_event); | 461 | const struct compat_sigevent __user *u_event); |
462 | 462 | ||
diff --git a/include/linux/coredump.h b/include/linux/coredump.h index 207aed96a5b7..abf4b4e65dbb 100644 --- a/include/linux/coredump.h +++ b/include/linux/coredump.h | |||
@@ -17,9 +17,9 @@ extern int dump_emit(struct coredump_params *cprm, const void *addr, int nr); | |||
17 | extern int dump_align(struct coredump_params *cprm, int align); | 17 | extern int dump_align(struct coredump_params *cprm, int align); |
18 | extern void dump_truncate(struct coredump_params *cprm); | 18 | extern void dump_truncate(struct coredump_params *cprm); |
19 | #ifdef CONFIG_COREDUMP | 19 | #ifdef CONFIG_COREDUMP |
20 | extern void do_coredump(const siginfo_t *siginfo); | 20 | extern void do_coredump(const kernel_siginfo_t *siginfo); |
21 | #else | 21 | #else |
22 | static inline void do_coredump(const siginfo_t *siginfo) {} | 22 | static inline void do_coredump(const kernel_siginfo_t *siginfo) {} |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | #endif /* _LINUX_COREDUMP_H */ | 25 | #endif /* _LINUX_COREDUMP_H */ |
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 97a020c616ad..bb40f6d34163 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h | |||
@@ -672,7 +672,7 @@ | |||
672 | * Return 0 if permission is granted. | 672 | * Return 0 if permission is granted. |
673 | * @task_kill: | 673 | * @task_kill: |
674 | * Check permission before sending signal @sig to @p. @info can be NULL, | 674 | * Check permission before sending signal @sig to @p. @info can be NULL, |
675 | * the constant 1, or a pointer to a siginfo structure. If @info is 1 or | 675 | * the constant 1, or a pointer to a kernel_siginfo structure. If @info is 1 or |
676 | * SI_FROMKERNEL(info) is true, then the signal should be viewed as coming | 676 | * SI_FROMKERNEL(info) is true, then the signal should be viewed as coming |
677 | * from the kernel and should typically be permitted. | 677 | * from the kernel and should typically be permitted. |
678 | * SIGIO signals are handled separately by the send_sigiotask hook in | 678 | * SIGIO signals are handled separately by the send_sigiotask hook in |
@@ -1606,7 +1606,7 @@ union security_list_options { | |||
1606 | int (*task_setscheduler)(struct task_struct *p); | 1606 | int (*task_setscheduler)(struct task_struct *p); |
1607 | int (*task_getscheduler)(struct task_struct *p); | 1607 | int (*task_getscheduler)(struct task_struct *p); |
1608 | int (*task_movememory)(struct task_struct *p); | 1608 | int (*task_movememory)(struct task_struct *p); |
1609 | int (*task_kill)(struct task_struct *p, struct siginfo *info, | 1609 | int (*task_kill)(struct task_struct *p, struct kernel_siginfo *info, |
1610 | int sig, const struct cred *cred); | 1610 | int sig, const struct cred *cred); |
1611 | int (*task_prctl)(int option, unsigned long arg2, unsigned long arg3, | 1611 | int (*task_prctl)(int option, unsigned long arg2, unsigned long arg3, |
1612 | unsigned long arg4, unsigned long arg5); | 1612 | unsigned long arg4, unsigned long arg5); |
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index ee7e987ea1b4..e96581ca7c9d 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h | |||
@@ -126,5 +126,5 @@ void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx, | |||
126 | 126 | ||
127 | void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new); | 127 | void update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new); |
128 | 128 | ||
129 | void posixtimer_rearm(struct siginfo *info); | 129 | void posixtimer_rearm(struct kernel_siginfo *info); |
130 | #endif | 130 | #endif |
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index e5e5ef513df3..6c2ffed907f5 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h | |||
@@ -353,14 +353,19 @@ static inline void user_enable_block_step(struct task_struct *task) | |||
353 | extern void user_enable_block_step(struct task_struct *); | 353 | extern void user_enable_block_step(struct task_struct *); |
354 | #endif /* arch_has_block_step */ | 354 | #endif /* arch_has_block_step */ |
355 | 355 | ||
356 | #ifdef ARCH_HAS_USER_SINGLE_STEP_INFO | 356 | #ifdef ARCH_HAS_USER_SINGLE_STEP_REPORT |
357 | extern void user_single_step_siginfo(struct task_struct *tsk, | 357 | extern void user_single_step_report(struct pt_regs *regs); |
358 | struct pt_regs *regs, siginfo_t *info); | ||
359 | #else | 358 | #else |
360 | static inline void user_single_step_siginfo(struct task_struct *tsk, | 359 | static inline void user_single_step_report(struct pt_regs *regs) |
361 | struct pt_regs *regs, siginfo_t *info) | ||
362 | { | 360 | { |
363 | info->si_signo = SIGTRAP; | 361 | kernel_siginfo_t info; |
362 | clear_siginfo(&info); | ||
363 | info.si_signo = SIGTRAP; | ||
364 | info.si_errno = 0; | ||
365 | info.si_code = SI_USER; | ||
366 | info.si_pid = 0; | ||
367 | info.si_uid = 0; | ||
368 | force_sig_info(info.si_signo, &info, current); | ||
364 | } | 369 | } |
365 | #endif | 370 | #endif |
366 | 371 | ||
diff --git a/include/linux/sched.h b/include/linux/sched.h index 58e2af8d064b..adfb3f9a7597 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -962,7 +962,7 @@ struct task_struct { | |||
962 | 962 | ||
963 | /* Ptrace state: */ | 963 | /* Ptrace state: */ |
964 | unsigned long ptrace_message; | 964 | unsigned long ptrace_message; |
965 | siginfo_t *last_siginfo; | 965 | kernel_siginfo_t *last_siginfo; |
966 | 966 | ||
967 | struct task_io_accounting ioac; | 967 | struct task_io_accounting ioac; |
968 | #ifdef CONFIG_TASK_XACCT | 968 | #ifdef CONFIG_TASK_XACCT |
diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index 1be35729c2c5..13789d10a50e 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h | |||
@@ -270,16 +270,16 @@ static inline int signal_group_exit(const struct signal_struct *sig) | |||
270 | extern void flush_signals(struct task_struct *); | 270 | extern void flush_signals(struct task_struct *); |
271 | extern void ignore_signals(struct task_struct *); | 271 | extern void ignore_signals(struct task_struct *); |
272 | extern void flush_signal_handlers(struct task_struct *, int force_default); | 272 | extern void flush_signal_handlers(struct task_struct *, int force_default); |
273 | extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info); | 273 | extern int dequeue_signal(struct task_struct *tsk, sigset_t *mask, kernel_siginfo_t *info); |
274 | 274 | ||
275 | static inline int kernel_dequeue_signal(siginfo_t *info) | 275 | static inline int kernel_dequeue_signal(void) |
276 | { | 276 | { |
277 | struct task_struct *tsk = current; | 277 | struct task_struct *tsk = current; |
278 | siginfo_t __info; | 278 | kernel_siginfo_t __info; |
279 | int ret; | 279 | int ret; |
280 | 280 | ||
281 | spin_lock_irq(&tsk->sighand->siglock); | 281 | spin_lock_irq(&tsk->sighand->siglock); |
282 | ret = dequeue_signal(tsk, &tsk->blocked, info ?: &__info); | 282 | ret = dequeue_signal(tsk, &tsk->blocked, &__info); |
283 | spin_unlock_irq(&tsk->sighand->siglock); | 283 | spin_unlock_irq(&tsk->sighand->siglock); |
284 | 284 | ||
285 | return ret; | 285 | return ret; |
@@ -322,12 +322,12 @@ int force_sig_pkuerr(void __user *addr, u32 pkey); | |||
322 | 322 | ||
323 | int force_sig_ptrace_errno_trap(int errno, void __user *addr); | 323 | int force_sig_ptrace_errno_trap(int errno, void __user *addr); |
324 | 324 | ||
325 | extern int send_sig_info(int, struct siginfo *, struct task_struct *); | 325 | extern int send_sig_info(int, struct kernel_siginfo *, struct task_struct *); |
326 | extern void force_sigsegv(int sig, struct task_struct *p); | 326 | extern void force_sigsegv(int sig, struct task_struct *p); |
327 | extern int force_sig_info(int, struct siginfo *, struct task_struct *); | 327 | extern int force_sig_info(int, struct kernel_siginfo *, struct task_struct *); |
328 | extern int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp); | 328 | extern int __kill_pgrp_info(int sig, struct kernel_siginfo *info, struct pid *pgrp); |
329 | extern int kill_pid_info(int sig, struct siginfo *info, struct pid *pid); | 329 | extern int kill_pid_info(int sig, struct kernel_siginfo *info, struct pid *pid); |
330 | extern int kill_pid_info_as_cred(int, struct siginfo *, struct pid *, | 330 | extern int kill_pid_info_as_cred(int, struct kernel_siginfo *, struct pid *, |
331 | const struct cred *); | 331 | const struct cred *); |
332 | extern int kill_pgrp(struct pid *pid, int sig, int priv); | 332 | extern int kill_pgrp(struct pid *pid, int sig, int priv); |
333 | extern int kill_pid(struct pid *pid, int sig, int priv); | 333 | extern int kill_pid(struct pid *pid, int sig, int priv); |
@@ -475,9 +475,8 @@ static inline int kill_cad_pid(int sig, int priv) | |||
475 | } | 475 | } |
476 | 476 | ||
477 | /* These can be the second arg to send_sig_info/send_group_sig_info. */ | 477 | /* These can be the second arg to send_sig_info/send_group_sig_info. */ |
478 | #define SEND_SIG_NOINFO ((struct siginfo *) 0) | 478 | #define SEND_SIG_NOINFO ((struct kernel_siginfo *) 0) |
479 | #define SEND_SIG_PRIV ((struct siginfo *) 1) | 479 | #define SEND_SIG_PRIV ((struct kernel_siginfo *) 1) |
480 | #define SEND_SIG_FORCED ((struct siginfo *) 2) | ||
481 | 480 | ||
482 | /* | 481 | /* |
483 | * True if we are on the alternate signal stack. | 482 | * True if we are on the alternate signal stack. |
diff --git a/include/linux/security.h b/include/linux/security.h index 75f4156c84d7..d170a5b031f3 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -35,7 +35,7 @@ | |||
35 | struct linux_binprm; | 35 | struct linux_binprm; |
36 | struct cred; | 36 | struct cred; |
37 | struct rlimit; | 37 | struct rlimit; |
38 | struct siginfo; | 38 | struct kernel_siginfo; |
39 | struct sembuf; | 39 | struct sembuf; |
40 | struct kern_ipc_perm; | 40 | struct kern_ipc_perm; |
41 | struct audit_context; | 41 | struct audit_context; |
@@ -361,7 +361,7 @@ int security_task_setrlimit(struct task_struct *p, unsigned int resource, | |||
361 | int security_task_setscheduler(struct task_struct *p); | 361 | int security_task_setscheduler(struct task_struct *p); |
362 | int security_task_getscheduler(struct task_struct *p); | 362 | int security_task_getscheduler(struct task_struct *p); |
363 | int security_task_movememory(struct task_struct *p); | 363 | int security_task_movememory(struct task_struct *p); |
364 | int security_task_kill(struct task_struct *p, struct siginfo *info, | 364 | int security_task_kill(struct task_struct *p, struct kernel_siginfo *info, |
365 | int sig, const struct cred *cred); | 365 | int sig, const struct cred *cred); |
366 | int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, | 366 | int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, |
367 | unsigned long arg4, unsigned long arg5); | 367 | unsigned long arg4, unsigned long arg5); |
@@ -1020,7 +1020,7 @@ static inline int security_task_movememory(struct task_struct *p) | |||
1020 | } | 1020 | } |
1021 | 1021 | ||
1022 | static inline int security_task_kill(struct task_struct *p, | 1022 | static inline int security_task_kill(struct task_struct *p, |
1023 | struct siginfo *info, int sig, | 1023 | struct kernel_siginfo *info, int sig, |
1024 | const struct cred *cred) | 1024 | const struct cred *cred) |
1025 | { | 1025 | { |
1026 | return 0; | 1026 | return 0; |
diff --git a/include/linux/signal.h b/include/linux/signal.h index 3d4cd5db30a9..200ed96a05af 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h | |||
@@ -11,17 +11,21 @@ struct task_struct; | |||
11 | /* for sysctl */ | 11 | /* for sysctl */ |
12 | extern int print_fatal_signals; | 12 | extern int print_fatal_signals; |
13 | 13 | ||
14 | static inline void copy_siginfo(struct siginfo *to, const struct siginfo *from) | 14 | static inline void copy_siginfo(kernel_siginfo_t *to, |
15 | const kernel_siginfo_t *from) | ||
15 | { | 16 | { |
16 | memcpy(to, from, sizeof(*to)); | 17 | memcpy(to, from, sizeof(*to)); |
17 | } | 18 | } |
18 | 19 | ||
19 | static inline void clear_siginfo(struct siginfo *info) | 20 | static inline void clear_siginfo(kernel_siginfo_t *info) |
20 | { | 21 | { |
21 | memset(info, 0, sizeof(*info)); | 22 | memset(info, 0, sizeof(*info)); |
22 | } | 23 | } |
23 | 24 | ||
24 | int copy_siginfo_to_user(struct siginfo __user *to, const struct siginfo *from); | 25 | #define SI_EXPANSION_SIZE (sizeof(struct siginfo) - sizeof(struct kernel_siginfo)) |
26 | |||
27 | int copy_siginfo_to_user(siginfo_t __user *to, const kernel_siginfo_t *from); | ||
28 | int copy_siginfo_from_user(kernel_siginfo_t *to, const siginfo_t __user *from); | ||
25 | 29 | ||
26 | enum siginfo_layout { | 30 | enum siginfo_layout { |
27 | SIL_KILL, | 31 | SIL_KILL, |
@@ -36,7 +40,7 @@ enum siginfo_layout { | |||
36 | SIL_SYS, | 40 | SIL_SYS, |
37 | }; | 41 | }; |
38 | 42 | ||
39 | enum siginfo_layout siginfo_layout(int sig, int si_code); | 43 | enum siginfo_layout siginfo_layout(unsigned sig, int si_code); |
40 | 44 | ||
41 | /* | 45 | /* |
42 | * Define some primitives to manipulate sigset_t. | 46 | * Define some primitives to manipulate sigset_t. |
@@ -257,11 +261,11 @@ struct pt_regs; | |||
257 | enum pid_type; | 261 | enum pid_type; |
258 | 262 | ||
259 | extern int next_signal(struct sigpending *pending, sigset_t *mask); | 263 | extern int next_signal(struct sigpending *pending, sigset_t *mask); |
260 | extern int do_send_sig_info(int sig, struct siginfo *info, | 264 | extern int do_send_sig_info(int sig, struct kernel_siginfo *info, |
261 | struct task_struct *p, enum pid_type type); | 265 | struct task_struct *p, enum pid_type type); |
262 | extern int group_send_sig_info(int sig, struct siginfo *info, | 266 | extern int group_send_sig_info(int sig, struct kernel_siginfo *info, |
263 | struct task_struct *p, enum pid_type type); | 267 | struct task_struct *p, enum pid_type type); |
264 | extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); | 268 | extern int __group_send_sig_info(int, struct kernel_siginfo *, struct task_struct *); |
265 | extern int sigprocmask(int, sigset_t *, sigset_t *); | 269 | extern int sigprocmask(int, sigset_t *, sigset_t *); |
266 | extern void set_current_blocked(sigset_t *); | 270 | extern void set_current_blocked(sigset_t *); |
267 | extern void __set_current_blocked(const sigset_t *); | 271 | extern void __set_current_blocked(const sigset_t *); |
diff --git a/include/linux/signal_types.h b/include/linux/signal_types.h index 222ae696000b..f8a90ae9c6ec 100644 --- a/include/linux/signal_types.h +++ b/include/linux/signal_types.h | |||
@@ -9,6 +9,10 @@ | |||
9 | #include <linux/list.h> | 9 | #include <linux/list.h> |
10 | #include <uapi/linux/signal.h> | 10 | #include <uapi/linux/signal.h> |
11 | 11 | ||
12 | typedef struct kernel_siginfo { | ||
13 | __SIGINFO; | ||
14 | } kernel_siginfo_t; | ||
15 | |||
12 | /* | 16 | /* |
13 | * Real Time signals may be queued. | 17 | * Real Time signals may be queued. |
14 | */ | 18 | */ |
@@ -16,7 +20,7 @@ | |||
16 | struct sigqueue { | 20 | struct sigqueue { |
17 | struct list_head list; | 21 | struct list_head list; |
18 | int flags; | 22 | int flags; |
19 | siginfo_t info; | 23 | kernel_siginfo_t info; |
20 | struct user_struct *user; | 24 | struct user_struct *user; |
21 | }; | 25 | }; |
22 | 26 | ||
@@ -60,7 +64,7 @@ struct old_sigaction { | |||
60 | 64 | ||
61 | struct ksignal { | 65 | struct ksignal { |
62 | struct k_sigaction ka; | 66 | struct k_sigaction ka; |
63 | siginfo_t info; | 67 | kernel_siginfo_t info; |
64 | int sig; | 68 | int sig; |
65 | }; | 69 | }; |
66 | 70 | ||
diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 05589a3e37f4..40b0b4c1bf7b 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h | |||
@@ -123,15 +123,10 @@ static inline __must_check int tracehook_report_syscall_entry( | |||
123 | */ | 123 | */ |
124 | static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step) | 124 | static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step) |
125 | { | 125 | { |
126 | if (step) { | 126 | if (step) |
127 | siginfo_t info; | 127 | user_single_step_report(regs); |
128 | clear_siginfo(&info); | 128 | else |
129 | user_single_step_siginfo(current, regs, &info); | 129 | ptrace_report_syscall(regs); |
130 | force_sig_info(SIGTRAP, &info, current); | ||
131 | return; | ||
132 | } | ||
133 | |||
134 | ptrace_report_syscall(regs); | ||
135 | } | 130 | } |
136 | 131 | ||
137 | /** | 132 | /** |
diff --git a/include/trace/events/signal.h b/include/trace/events/signal.h index 86582923d51c..1db7e4b07c01 100644 --- a/include/trace/events/signal.h +++ b/include/trace/events/signal.h | |||
@@ -11,8 +11,7 @@ | |||
11 | 11 | ||
12 | #define TP_STORE_SIGINFO(__entry, info) \ | 12 | #define TP_STORE_SIGINFO(__entry, info) \ |
13 | do { \ | 13 | do { \ |
14 | if (info == SEND_SIG_NOINFO || \ | 14 | if (info == SEND_SIG_NOINFO) { \ |
15 | info == SEND_SIG_FORCED) { \ | ||
16 | __entry->errno = 0; \ | 15 | __entry->errno = 0; \ |
17 | __entry->code = SI_USER; \ | 16 | __entry->code = SI_USER; \ |
18 | } else if (info == SEND_SIG_PRIV) { \ | 17 | } else if (info == SEND_SIG_PRIV) { \ |
@@ -50,7 +49,7 @@ enum { | |||
50 | */ | 49 | */ |
51 | TRACE_EVENT(signal_generate, | 50 | TRACE_EVENT(signal_generate, |
52 | 51 | ||
53 | TP_PROTO(int sig, struct siginfo *info, struct task_struct *task, | 52 | TP_PROTO(int sig, struct kernel_siginfo *info, struct task_struct *task, |
54 | int group, int result), | 53 | int group, int result), |
55 | 54 | ||
56 | TP_ARGS(sig, info, task, group, result), | 55 | TP_ARGS(sig, info, task, group, result), |
@@ -96,7 +95,7 @@ TRACE_EVENT(signal_generate, | |||
96 | */ | 95 | */ |
97 | TRACE_EVENT(signal_deliver, | 96 | TRACE_EVENT(signal_deliver, |
98 | 97 | ||
99 | TP_PROTO(int sig, struct siginfo *info, struct k_sigaction *ka), | 98 | TP_PROTO(int sig, struct kernel_siginfo *info, struct k_sigaction *ka), |
100 | 99 | ||
101 | TP_ARGS(sig, info, ka), | 100 | TP_ARGS(sig, info, ka), |
102 | 101 | ||
diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h index 80e2a7227205..cb3d6c267181 100644 --- a/include/uapi/asm-generic/siginfo.h +++ b/include/uapi/asm-generic/siginfo.h | |||
@@ -10,18 +10,7 @@ typedef union sigval { | |||
10 | void __user *sival_ptr; | 10 | void __user *sival_ptr; |
11 | } sigval_t; | 11 | } sigval_t; |
12 | 12 | ||
13 | /* | ||
14 | * This is the size (including padding) of the part of the | ||
15 | * struct siginfo that is before the union. | ||
16 | */ | ||
17 | #ifndef __ARCH_SI_PREAMBLE_SIZE | ||
18 | #define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int)) | ||
19 | #endif | ||
20 | |||
21 | #define SI_MAX_SIZE 128 | 13 | #define SI_MAX_SIZE 128 |
22 | #ifndef SI_PAD_SIZE | ||
23 | #define SI_PAD_SIZE ((SI_MAX_SIZE - __ARCH_SI_PREAMBLE_SIZE) / sizeof(int)) | ||
24 | #endif | ||
25 | 14 | ||
26 | /* | 15 | /* |
27 | * The default "si_band" type is "long", as specified by POSIX. | 16 | * The default "si_band" type is "long", as specified by POSIX. |
@@ -40,96 +29,108 @@ typedef union sigval { | |||
40 | #define __ARCH_SI_ATTRIBUTES | 29 | #define __ARCH_SI_ATTRIBUTES |
41 | #endif | 30 | #endif |
42 | 31 | ||
43 | typedef struct siginfo { | 32 | union __sifields { |
44 | int si_signo; | 33 | /* kill() */ |
45 | #ifndef __ARCH_HAS_SWAPPED_SIGINFO | 34 | struct { |
46 | int si_errno; | 35 | __kernel_pid_t _pid; /* sender's pid */ |
47 | int si_code; | 36 | __kernel_uid32_t _uid; /* sender's uid */ |
48 | #else | 37 | } _kill; |
49 | int si_code; | 38 | |
50 | int si_errno; | 39 | /* POSIX.1b timers */ |
51 | #endif | 40 | struct { |
52 | 41 | __kernel_timer_t _tid; /* timer id */ | |
53 | union { | 42 | int _overrun; /* overrun count */ |
54 | int _pad[SI_PAD_SIZE]; | 43 | sigval_t _sigval; /* same as below */ |
55 | 44 | int _sys_private; /* not to be passed to user */ | |
56 | /* kill() */ | 45 | } _timer; |
57 | struct { | 46 | |
58 | __kernel_pid_t _pid; /* sender's pid */ | 47 | /* POSIX.1b signals */ |
59 | __kernel_uid32_t _uid; /* sender's uid */ | 48 | struct { |
60 | } _kill; | 49 | __kernel_pid_t _pid; /* sender's pid */ |
61 | 50 | __kernel_uid32_t _uid; /* sender's uid */ | |
62 | /* POSIX.1b timers */ | 51 | sigval_t _sigval; |
63 | struct { | 52 | } _rt; |
64 | __kernel_timer_t _tid; /* timer id */ | 53 | |
65 | int _overrun; /* overrun count */ | 54 | /* SIGCHLD */ |
66 | sigval_t _sigval; /* same as below */ | 55 | struct { |
67 | int _sys_private; /* not to be passed to user */ | 56 | __kernel_pid_t _pid; /* which child */ |
68 | } _timer; | 57 | __kernel_uid32_t _uid; /* sender's uid */ |
69 | 58 | int _status; /* exit code */ | |
70 | /* POSIX.1b signals */ | 59 | __ARCH_SI_CLOCK_T _utime; |
71 | struct { | 60 | __ARCH_SI_CLOCK_T _stime; |
72 | __kernel_pid_t _pid; /* sender's pid */ | 61 | } _sigchld; |
73 | __kernel_uid32_t _uid; /* sender's uid */ | 62 | |
74 | sigval_t _sigval; | 63 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */ |
75 | } _rt; | 64 | struct { |
76 | 65 | void __user *_addr; /* faulting insn/memory ref. */ | |
77 | /* SIGCHLD */ | ||
78 | struct { | ||
79 | __kernel_pid_t _pid; /* which child */ | ||
80 | __kernel_uid32_t _uid; /* sender's uid */ | ||
81 | int _status; /* exit code */ | ||
82 | __ARCH_SI_CLOCK_T _utime; | ||
83 | __ARCH_SI_CLOCK_T _stime; | ||
84 | } _sigchld; | ||
85 | |||
86 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */ | ||
87 | struct { | ||
88 | void __user *_addr; /* faulting insn/memory ref. */ | ||
89 | #ifdef __ARCH_SI_TRAPNO | 66 | #ifdef __ARCH_SI_TRAPNO |
90 | int _trapno; /* TRAP # which caused the signal */ | 67 | int _trapno; /* TRAP # which caused the signal */ |
91 | #endif | 68 | #endif |
92 | #ifdef __ia64__ | 69 | #ifdef __ia64__ |
93 | int _imm; /* immediate value for "break" */ | 70 | int _imm; /* immediate value for "break" */ |
94 | unsigned int _flags; /* see ia64 si_flags */ | 71 | unsigned int _flags; /* see ia64 si_flags */ |
95 | unsigned long _isr; /* isr */ | 72 | unsigned long _isr; /* isr */ |
96 | #endif | 73 | #endif |
97 | 74 | ||
98 | #define __ADDR_BND_PKEY_PAD (__alignof__(void *) < sizeof(short) ? \ | 75 | #define __ADDR_BND_PKEY_PAD (__alignof__(void *) < sizeof(short) ? \ |
99 | sizeof(short) : __alignof__(void *)) | 76 | sizeof(short) : __alignof__(void *)) |
100 | union { | 77 | union { |
101 | /* | 78 | /* |
102 | * used when si_code=BUS_MCEERR_AR or | 79 | * used when si_code=BUS_MCEERR_AR or |
103 | * used when si_code=BUS_MCEERR_AO | 80 | * used when si_code=BUS_MCEERR_AO |
104 | */ | 81 | */ |
105 | short _addr_lsb; /* LSB of the reported address */ | 82 | short _addr_lsb; /* LSB of the reported address */ |
106 | /* used when si_code=SEGV_BNDERR */ | 83 | /* used when si_code=SEGV_BNDERR */ |
107 | struct { | 84 | struct { |
108 | char _dummy_bnd[__ADDR_BND_PKEY_PAD]; | 85 | char _dummy_bnd[__ADDR_BND_PKEY_PAD]; |
109 | void __user *_lower; | 86 | void __user *_lower; |
110 | void __user *_upper; | 87 | void __user *_upper; |
111 | } _addr_bnd; | 88 | } _addr_bnd; |
112 | /* used when si_code=SEGV_PKUERR */ | 89 | /* used when si_code=SEGV_PKUERR */ |
113 | struct { | 90 | struct { |
114 | char _dummy_pkey[__ADDR_BND_PKEY_PAD]; | 91 | char _dummy_pkey[__ADDR_BND_PKEY_PAD]; |
115 | __u32 _pkey; | 92 | __u32 _pkey; |
116 | } _addr_pkey; | 93 | } _addr_pkey; |
117 | }; | 94 | }; |
118 | } _sigfault; | 95 | } _sigfault; |
119 | 96 | ||
120 | /* SIGPOLL */ | 97 | /* SIGPOLL */ |
121 | struct { | 98 | struct { |
122 | __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | 99 | __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */ |
123 | int _fd; | 100 | int _fd; |
124 | } _sigpoll; | 101 | } _sigpoll; |
102 | |||
103 | /* SIGSYS */ | ||
104 | struct { | ||
105 | void __user *_call_addr; /* calling user insn */ | ||
106 | int _syscall; /* triggering system call number */ | ||
107 | unsigned int _arch; /* AUDIT_ARCH_* of syscall */ | ||
108 | } _sigsys; | ||
109 | }; | ||
125 | 110 | ||
126 | /* SIGSYS */ | 111 | #ifndef __ARCH_HAS_SWAPPED_SIGINFO |
127 | struct { | 112 | #define __SIGINFO \ |
128 | void __user *_call_addr; /* calling user insn */ | 113 | struct { \ |
129 | int _syscall; /* triggering system call number */ | 114 | int si_signo; \ |
130 | unsigned int _arch; /* AUDIT_ARCH_* of syscall */ | 115 | int si_errno; \ |
131 | } _sigsys; | 116 | int si_code; \ |
132 | } _sifields; | 117 | union __sifields _sifields; \ |
118 | } | ||
119 | #else | ||
120 | #define __SIGINFO \ | ||
121 | struct { \ | ||
122 | int si_signo; \ | ||
123 | int si_code; \ | ||
124 | int si_errno; \ | ||
125 | union __sifields _sifields; \ | ||
126 | } | ||
127 | #endif /* __ARCH_HAS_SWAPPED_SIGINFO */ | ||
128 | |||
129 | typedef struct siginfo { | ||
130 | union { | ||
131 | __SIGINFO; | ||
132 | int _si_pad[SI_MAX_SIZE/sizeof(int)]; | ||
133 | }; | ||
133 | } __ARCH_SI_ATTRIBUTES siginfo_t; | 134 | } __ARCH_SI_ATTRIBUTES siginfo_t; |
134 | 135 | ||
135 | /* | 136 | /* |
@@ -286,6 +287,12 @@ typedef struct siginfo { | |||
286 | #define NSIGSYS 1 | 287 | #define NSIGSYS 1 |
287 | 288 | ||
288 | /* | 289 | /* |
290 | * SIGEMT si_codes | ||
291 | */ | ||
292 | #define EMT_TAGOVF 1 /* tag overflow */ | ||
293 | #define NSIGEMT 1 | ||
294 | |||
295 | /* | ||
289 | * sigevent definitions | 296 | * sigevent definitions |
290 | * | 297 | * |
291 | * It seems likely that SIGEV_THREAD will have to be handled from | 298 | * It seems likely that SIGEV_THREAD will have to be handled from |
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index c0d58f390c3b..cc41de3b8deb 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -655,7 +655,7 @@ static void __do_notify(struct mqueue_inode_info *info) | |||
655 | * synchronously. */ | 655 | * synchronously. */ |
656 | if (info->notify_owner && | 656 | if (info->notify_owner && |
657 | info->attr.mq_curmsgs == 1) { | 657 | info->attr.mq_curmsgs == 1) { |
658 | struct siginfo sig_i; | 658 | struct kernel_siginfo sig_i; |
659 | switch (info->notify.sigev_notify) { | 659 | switch (info->notify.sigev_notify) { |
660 | case SIGEV_NONE: | 660 | case SIGEV_NONE: |
661 | break; | 661 | break; |
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 3207a4d26849..2bf792d22087 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
@@ -1858,7 +1858,7 @@ static void handle_trampoline(struct pt_regs *regs) | |||
1858 | 1858 | ||
1859 | sigill: | 1859 | sigill: |
1860 | uprobe_warn(current, "handle uretprobe, sending SIGILL."); | 1860 | uprobe_warn(current, "handle uretprobe, sending SIGILL."); |
1861 | force_sig_info(SIGILL, SEND_SIG_FORCED, current); | 1861 | force_sig(SIGILL, current); |
1862 | 1862 | ||
1863 | } | 1863 | } |
1864 | 1864 | ||
@@ -1966,7 +1966,7 @@ static void handle_singlestep(struct uprobe_task *utask, struct pt_regs *regs) | |||
1966 | 1966 | ||
1967 | if (unlikely(err)) { | 1967 | if (unlikely(err)) { |
1968 | uprobe_warn(current, "execute the probed insn, sending SIGILL."); | 1968 | uprobe_warn(current, "execute the probed insn, sending SIGILL."); |
1969 | force_sig_info(SIGILL, SEND_SIG_FORCED, current); | 1969 | force_sig(SIGILL, current); |
1970 | } | 1970 | } |
1971 | } | 1971 | } |
1972 | 1972 | ||
diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 2a2ac53d8b8b..aa6e72fb7c08 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c | |||
@@ -216,7 +216,7 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns) | |||
216 | idr_for_each_entry_continue(&pid_ns->idr, pid, nr) { | 216 | idr_for_each_entry_continue(&pid_ns->idr, pid, nr) { |
217 | task = pid_task(pid, PIDTYPE_PID); | 217 | task = pid_task(pid, PIDTYPE_PID); |
218 | if (task && !__fatal_signal_pending(task)) | 218 | if (task && !__fatal_signal_pending(task)) |
219 | send_sig_info(SIGKILL, SEND_SIG_FORCED, task); | 219 | group_send_sig_info(SIGKILL, SEND_SIG_PRIV, task, PIDTYPE_MAX); |
220 | } | 220 | } |
221 | read_unlock(&tasklist_lock); | 221 | read_unlock(&tasklist_lock); |
222 | rcu_read_unlock(); | 222 | rcu_read_unlock(); |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 99cfddde6a55..80b34dffdfb9 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -406,7 +406,7 @@ static int ptrace_attach(struct task_struct *task, long request, | |||
406 | 406 | ||
407 | /* SEIZE doesn't trap tracee on attach */ | 407 | /* SEIZE doesn't trap tracee on attach */ |
408 | if (!seize) | 408 | if (!seize) |
409 | send_sig_info(SIGSTOP, SEND_SIG_FORCED, task); | 409 | send_sig_info(SIGSTOP, SEND_SIG_PRIV, task); |
410 | 410 | ||
411 | spin_lock(&task->sighand->siglock); | 411 | spin_lock(&task->sighand->siglock); |
412 | 412 | ||
@@ -573,7 +573,7 @@ void exit_ptrace(struct task_struct *tracer, struct list_head *dead) | |||
573 | 573 | ||
574 | list_for_each_entry_safe(p, n, &tracer->ptraced, ptrace_entry) { | 574 | list_for_each_entry_safe(p, n, &tracer->ptraced, ptrace_entry) { |
575 | if (unlikely(p->ptrace & PT_EXITKILL)) | 575 | if (unlikely(p->ptrace & PT_EXITKILL)) |
576 | send_sig_info(SIGKILL, SEND_SIG_FORCED, p); | 576 | send_sig_info(SIGKILL, SEND_SIG_PRIV, p); |
577 | 577 | ||
578 | if (__ptrace_detach(tracer, p)) | 578 | if (__ptrace_detach(tracer, p)) |
579 | list_add(&p->ptrace_entry, dead); | 579 | list_add(&p->ptrace_entry, dead); |
@@ -661,7 +661,7 @@ static int ptrace_setoptions(struct task_struct *child, unsigned long data) | |||
661 | return 0; | 661 | return 0; |
662 | } | 662 | } |
663 | 663 | ||
664 | static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info) | 664 | static int ptrace_getsiginfo(struct task_struct *child, kernel_siginfo_t *info) |
665 | { | 665 | { |
666 | unsigned long flags; | 666 | unsigned long flags; |
667 | int error = -ESRCH; | 667 | int error = -ESRCH; |
@@ -677,7 +677,7 @@ static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info) | |||
677 | return error; | 677 | return error; |
678 | } | 678 | } |
679 | 679 | ||
680 | static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info) | 680 | static int ptrace_setsiginfo(struct task_struct *child, const kernel_siginfo_t *info) |
681 | { | 681 | { |
682 | unsigned long flags; | 682 | unsigned long flags; |
683 | int error = -ESRCH; | 683 | int error = -ESRCH; |
@@ -719,7 +719,7 @@ static int ptrace_peek_siginfo(struct task_struct *child, | |||
719 | pending = &child->pending; | 719 | pending = &child->pending; |
720 | 720 | ||
721 | for (i = 0; i < arg.nr; ) { | 721 | for (i = 0; i < arg.nr; ) { |
722 | siginfo_t info; | 722 | kernel_siginfo_t info; |
723 | s32 off = arg.off + i; | 723 | s32 off = arg.off + i; |
724 | 724 | ||
725 | spin_lock_irq(&child->sighand->siglock); | 725 | spin_lock_irq(&child->sighand->siglock); |
@@ -895,7 +895,7 @@ int ptrace_request(struct task_struct *child, long request, | |||
895 | { | 895 | { |
896 | bool seized = child->ptrace & PT_SEIZED; | 896 | bool seized = child->ptrace & PT_SEIZED; |
897 | int ret = -EIO; | 897 | int ret = -EIO; |
898 | siginfo_t siginfo, *si; | 898 | kernel_siginfo_t siginfo, *si; |
899 | void __user *datavp = (void __user *) data; | 899 | void __user *datavp = (void __user *) data; |
900 | unsigned long __user *datalp = datavp; | 900 | unsigned long __user *datalp = datavp; |
901 | unsigned long flags; | 901 | unsigned long flags; |
@@ -929,9 +929,8 @@ int ptrace_request(struct task_struct *child, long request, | |||
929 | break; | 929 | break; |
930 | 930 | ||
931 | case PTRACE_SETSIGINFO: | 931 | case PTRACE_SETSIGINFO: |
932 | if (copy_from_user(&siginfo, datavp, sizeof siginfo)) | 932 | ret = copy_siginfo_from_user(&siginfo, datavp); |
933 | ret = -EFAULT; | 933 | if (!ret) |
934 | else | ||
935 | ret = ptrace_setsiginfo(child, &siginfo); | 934 | ret = ptrace_setsiginfo(child, &siginfo); |
936 | break; | 935 | break; |
937 | 936 | ||
@@ -1191,7 +1190,7 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request, | |||
1191 | { | 1190 | { |
1192 | compat_ulong_t __user *datap = compat_ptr(data); | 1191 | compat_ulong_t __user *datap = compat_ptr(data); |
1193 | compat_ulong_t word; | 1192 | compat_ulong_t word; |
1194 | siginfo_t siginfo; | 1193 | kernel_siginfo_t siginfo; |
1195 | int ret; | 1194 | int ret; |
1196 | 1195 | ||
1197 | switch (request) { | 1196 | switch (request) { |
@@ -1225,10 +1224,9 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request, | |||
1225 | break; | 1224 | break; |
1226 | 1225 | ||
1227 | case PTRACE_SETSIGINFO: | 1226 | case PTRACE_SETSIGINFO: |
1228 | if (copy_siginfo_from_user32( | 1227 | ret = copy_siginfo_from_user32( |
1229 | &siginfo, (struct compat_siginfo __user *) datap)) | 1228 | &siginfo, (struct compat_siginfo __user *) datap); |
1230 | ret = -EFAULT; | 1229 | if (!ret) |
1231 | else | ||
1232 | ret = ptrace_setsiginfo(child, &siginfo); | 1230 | ret = ptrace_setsiginfo(child, &siginfo); |
1233 | break; | 1231 | break; |
1234 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK | 1232 | #ifdef CONFIG_HAVE_ARCH_TRACEHOOK |
diff --git a/kernel/seccomp.c b/kernel/seccomp.c index fd023ac24e10..4d7809cdd27d 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c | |||
@@ -522,7 +522,7 @@ void put_seccomp_filter(struct task_struct *tsk) | |||
522 | __put_seccomp_filter(tsk->seccomp.filter); | 522 | __put_seccomp_filter(tsk->seccomp.filter); |
523 | } | 523 | } |
524 | 524 | ||
525 | static void seccomp_init_siginfo(siginfo_t *info, int syscall, int reason) | 525 | static void seccomp_init_siginfo(kernel_siginfo_t *info, int syscall, int reason) |
526 | { | 526 | { |
527 | clear_siginfo(info); | 527 | clear_siginfo(info); |
528 | info->si_signo = SIGSYS; | 528 | info->si_signo = SIGSYS; |
@@ -542,7 +542,7 @@ static void seccomp_init_siginfo(siginfo_t *info, int syscall, int reason) | |||
542 | */ | 542 | */ |
543 | static void seccomp_send_sigsys(int syscall, int reason) | 543 | static void seccomp_send_sigsys(int syscall, int reason) |
544 | { | 544 | { |
545 | struct siginfo info; | 545 | struct kernel_siginfo info; |
546 | seccomp_init_siginfo(&info, syscall, reason); | 546 | seccomp_init_siginfo(&info, syscall, reason); |
547 | force_sig_info(SIGSYS, &info, current); | 547 | force_sig_info(SIGSYS, &info, current); |
548 | } | 548 | } |
@@ -747,7 +747,7 @@ static int __seccomp_filter(int this_syscall, const struct seccomp_data *sd, | |||
747 | /* Dump core only if this is the last remaining thread. */ | 747 | /* Dump core only if this is the last remaining thread. */ |
748 | if (action == SECCOMP_RET_KILL_PROCESS || | 748 | if (action == SECCOMP_RET_KILL_PROCESS || |
749 | get_nr_threads(current) == 1) { | 749 | get_nr_threads(current) == 1) { |
750 | siginfo_t info; | 750 | kernel_siginfo_t info; |
751 | 751 | ||
752 | /* Show the original registers in the dump. */ | 752 | /* Show the original registers in the dump. */ |
753 | syscall_rollback(current, task_pt_regs(current)); | 753 | syscall_rollback(current, task_pt_regs(current)); |
diff --git a/kernel/signal.c b/kernel/signal.c index e4aad0e90882..dbd2e4db24cf 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -78,6 +78,10 @@ static bool sig_task_ignored(struct task_struct *t, int sig, bool force) | |||
78 | 78 | ||
79 | handler = sig_handler(t, sig); | 79 | handler = sig_handler(t, sig); |
80 | 80 | ||
81 | /* SIGKILL and SIGSTOP may not be sent to the global init */ | ||
82 | if (unlikely(is_global_init(t) && sig_kernel_only(sig))) | ||
83 | return true; | ||
84 | |||
81 | if (unlikely(t->signal->flags & SIGNAL_UNKILLABLE) && | 85 | if (unlikely(t->signal->flags & SIGNAL_UNKILLABLE) && |
82 | handler == SIG_DFL && !(force && sig_kernel_only(sig))) | 86 | handler == SIG_DFL && !(force && sig_kernel_only(sig))) |
83 | return true; | 87 | return true; |
@@ -172,6 +176,7 @@ void recalc_sigpending(void) | |||
172 | clear_thread_flag(TIF_SIGPENDING); | 176 | clear_thread_flag(TIF_SIGPENDING); |
173 | 177 | ||
174 | } | 178 | } |
179 | EXPORT_SYMBOL(recalc_sigpending); | ||
175 | 180 | ||
176 | void calculate_sigpending(void) | 181 | void calculate_sigpending(void) |
177 | { | 182 | { |
@@ -462,6 +467,7 @@ void flush_signals(struct task_struct *t) | |||
462 | flush_sigqueue(&t->signal->shared_pending); | 467 | flush_sigqueue(&t->signal->shared_pending); |
463 | spin_unlock_irqrestore(&t->sighand->siglock, flags); | 468 | spin_unlock_irqrestore(&t->sighand->siglock, flags); |
464 | } | 469 | } |
470 | EXPORT_SYMBOL(flush_signals); | ||
465 | 471 | ||
466 | #ifdef CONFIG_POSIX_TIMERS | 472 | #ifdef CONFIG_POSIX_TIMERS |
467 | static void __flush_itimer_signals(struct sigpending *pending) | 473 | static void __flush_itimer_signals(struct sigpending *pending) |
@@ -543,7 +549,7 @@ bool unhandled_signal(struct task_struct *tsk, int sig) | |||
543 | return !tsk->ptrace; | 549 | return !tsk->ptrace; |
544 | } | 550 | } |
545 | 551 | ||
546 | static void collect_signal(int sig, struct sigpending *list, siginfo_t *info, | 552 | static void collect_signal(int sig, struct sigpending *list, kernel_siginfo_t *info, |
547 | bool *resched_timer) | 553 | bool *resched_timer) |
548 | { | 554 | { |
549 | struct sigqueue *q, *first = NULL; | 555 | struct sigqueue *q, *first = NULL; |
@@ -589,7 +595,7 @@ still_pending: | |||
589 | } | 595 | } |
590 | 596 | ||
591 | static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, | 597 | static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, |
592 | siginfo_t *info, bool *resched_timer) | 598 | kernel_siginfo_t *info, bool *resched_timer) |
593 | { | 599 | { |
594 | int sig = next_signal(pending, mask); | 600 | int sig = next_signal(pending, mask); |
595 | 601 | ||
@@ -604,7 +610,7 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, | |||
604 | * | 610 | * |
605 | * All callers have to hold the siglock. | 611 | * All callers have to hold the siglock. |
606 | */ | 612 | */ |
607 | int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) | 613 | int dequeue_signal(struct task_struct *tsk, sigset_t *mask, kernel_siginfo_t *info) |
608 | { | 614 | { |
609 | bool resched_timer = false; | 615 | bool resched_timer = false; |
610 | int signr; | 616 | int signr; |
@@ -680,6 +686,7 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) | |||
680 | #endif | 686 | #endif |
681 | return signr; | 687 | return signr; |
682 | } | 688 | } |
689 | EXPORT_SYMBOL_GPL(dequeue_signal); | ||
683 | 690 | ||
684 | /* | 691 | /* |
685 | * Tell a process that it has a new active signal.. | 692 | * Tell a process that it has a new active signal.. |
@@ -730,12 +737,12 @@ static void flush_sigqueue_mask(sigset_t *mask, struct sigpending *s) | |||
730 | } | 737 | } |
731 | } | 738 | } |
732 | 739 | ||
733 | static inline int is_si_special(const struct siginfo *info) | 740 | static inline int is_si_special(const struct kernel_siginfo *info) |
734 | { | 741 | { |
735 | return info <= SEND_SIG_FORCED; | 742 | return info <= SEND_SIG_PRIV; |
736 | } | 743 | } |
737 | 744 | ||
738 | static inline bool si_fromuser(const struct siginfo *info) | 745 | static inline bool si_fromuser(const struct kernel_siginfo *info) |
739 | { | 746 | { |
740 | return info == SEND_SIG_NOINFO || | 747 | return info == SEND_SIG_NOINFO || |
741 | (!is_si_special(info) && SI_FROMUSER(info)); | 748 | (!is_si_special(info) && SI_FROMUSER(info)); |
@@ -760,7 +767,7 @@ static bool kill_ok_by_cred(struct task_struct *t) | |||
760 | * Bad permissions for sending the signal | 767 | * Bad permissions for sending the signal |
761 | * - the caller must hold the RCU read lock | 768 | * - the caller must hold the RCU read lock |
762 | */ | 769 | */ |
763 | static int check_kill_permission(int sig, struct siginfo *info, | 770 | static int check_kill_permission(int sig, struct kernel_siginfo *info, |
764 | struct task_struct *t) | 771 | struct task_struct *t) |
765 | { | 772 | { |
766 | struct pid *sid; | 773 | struct pid *sid; |
@@ -1003,7 +1010,7 @@ static inline bool legacy_queue(struct sigpending *signals, int sig) | |||
1003 | } | 1010 | } |
1004 | 1011 | ||
1005 | #ifdef CONFIG_USER_NS | 1012 | #ifdef CONFIG_USER_NS |
1006 | static inline void userns_fixup_signal_uid(struct siginfo *info, struct task_struct *t) | 1013 | static inline void userns_fixup_signal_uid(struct kernel_siginfo *info, struct task_struct *t) |
1007 | { | 1014 | { |
1008 | if (current_user_ns() == task_cred_xxx(t, user_ns)) | 1015 | if (current_user_ns() == task_cred_xxx(t, user_ns)) |
1009 | return; | 1016 | return; |
@@ -1017,13 +1024,13 @@ static inline void userns_fixup_signal_uid(struct siginfo *info, struct task_str | |||
1017 | rcu_read_unlock(); | 1024 | rcu_read_unlock(); |
1018 | } | 1025 | } |
1019 | #else | 1026 | #else |
1020 | static inline void userns_fixup_signal_uid(struct siginfo *info, struct task_struct *t) | 1027 | static inline void userns_fixup_signal_uid(struct kernel_siginfo *info, struct task_struct *t) |
1021 | { | 1028 | { |
1022 | return; | 1029 | return; |
1023 | } | 1030 | } |
1024 | #endif | 1031 | #endif |
1025 | 1032 | ||
1026 | static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, | 1033 | static int __send_signal(int sig, struct kernel_siginfo *info, struct task_struct *t, |
1027 | enum pid_type type, int from_ancestor_ns) | 1034 | enum pid_type type, int from_ancestor_ns) |
1028 | { | 1035 | { |
1029 | struct sigpending *pending; | 1036 | struct sigpending *pending; |
@@ -1035,7 +1042,7 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
1035 | 1042 | ||
1036 | result = TRACE_SIGNAL_IGNORED; | 1043 | result = TRACE_SIGNAL_IGNORED; |
1037 | if (!prepare_signal(sig, t, | 1044 | if (!prepare_signal(sig, t, |
1038 | from_ancestor_ns || (info == SEND_SIG_FORCED))) | 1045 | from_ancestor_ns || (info == SEND_SIG_PRIV))) |
1039 | goto ret; | 1046 | goto ret; |
1040 | 1047 | ||
1041 | pending = (type != PIDTYPE_PID) ? &t->signal->shared_pending : &t->pending; | 1048 | pending = (type != PIDTYPE_PID) ? &t->signal->shared_pending : &t->pending; |
@@ -1050,10 +1057,10 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
1050 | 1057 | ||
1051 | result = TRACE_SIGNAL_DELIVERED; | 1058 | result = TRACE_SIGNAL_DELIVERED; |
1052 | /* | 1059 | /* |
1053 | * fast-pathed signals for kernel-internal things like SIGSTOP | 1060 | * Skip useless siginfo allocation for SIGKILL SIGSTOP, |
1054 | * or SIGKILL. | 1061 | * and kernel threads. |
1055 | */ | 1062 | */ |
1056 | if (info == SEND_SIG_FORCED) | 1063 | if (sig_kernel_only(sig) || (t->flags & PF_KTHREAD)) |
1057 | goto out_set; | 1064 | goto out_set; |
1058 | 1065 | ||
1059 | /* | 1066 | /* |
@@ -1143,7 +1150,7 @@ ret: | |||
1143 | return ret; | 1150 | return ret; |
1144 | } | 1151 | } |
1145 | 1152 | ||
1146 | static int send_signal(int sig, struct siginfo *info, struct task_struct *t, | 1153 | static int send_signal(int sig, struct kernel_siginfo *info, struct task_struct *t, |
1147 | enum pid_type type) | 1154 | enum pid_type type) |
1148 | { | 1155 | { |
1149 | int from_ancestor_ns = 0; | 1156 | int from_ancestor_ns = 0; |
@@ -1190,18 +1197,12 @@ static int __init setup_print_fatal_signals(char *str) | |||
1190 | __setup("print-fatal-signals=", setup_print_fatal_signals); | 1197 | __setup("print-fatal-signals=", setup_print_fatal_signals); |
1191 | 1198 | ||
1192 | int | 1199 | int |
1193 | __group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p) | 1200 | __group_send_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *p) |
1194 | { | 1201 | { |
1195 | return send_signal(sig, info, p, PIDTYPE_TGID); | 1202 | return send_signal(sig, info, p, PIDTYPE_TGID); |
1196 | } | 1203 | } |
1197 | 1204 | ||
1198 | static int | 1205 | int do_send_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *p, |
1199 | specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) | ||
1200 | { | ||
1201 | return send_signal(sig, info, t, PIDTYPE_PID); | ||
1202 | } | ||
1203 | |||
1204 | int do_send_sig_info(int sig, struct siginfo *info, struct task_struct *p, | ||
1205 | enum pid_type type) | 1206 | enum pid_type type) |
1206 | { | 1207 | { |
1207 | unsigned long flags; | 1208 | unsigned long flags; |
@@ -1227,7 +1228,7 @@ int do_send_sig_info(int sig, struct siginfo *info, struct task_struct *p, | |||
1227 | * that is why we also clear SIGNAL_UNKILLABLE. | 1228 | * that is why we also clear SIGNAL_UNKILLABLE. |
1228 | */ | 1229 | */ |
1229 | int | 1230 | int |
1230 | force_sig_info(int sig, struct siginfo *info, struct task_struct *t) | 1231 | force_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *t) |
1231 | { | 1232 | { |
1232 | unsigned long int flags; | 1233 | unsigned long int flags; |
1233 | int ret, blocked, ignored; | 1234 | int ret, blocked, ignored; |
@@ -1250,7 +1251,7 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t) | |||
1250 | */ | 1251 | */ |
1251 | if (action->sa.sa_handler == SIG_DFL && !t->ptrace) | 1252 | if (action->sa.sa_handler == SIG_DFL && !t->ptrace) |
1252 | t->signal->flags &= ~SIGNAL_UNKILLABLE; | 1253 | t->signal->flags &= ~SIGNAL_UNKILLABLE; |
1253 | ret = specific_send_sig_info(sig, info, t); | 1254 | ret = send_signal(sig, info, t, PIDTYPE_PID); |
1254 | spin_unlock_irqrestore(&t->sighand->siglock, flags); | 1255 | spin_unlock_irqrestore(&t->sighand->siglock, flags); |
1255 | 1256 | ||
1256 | return ret; | 1257 | return ret; |
@@ -1315,8 +1316,8 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, | |||
1315 | /* | 1316 | /* |
1316 | * send signal info to all the members of a group | 1317 | * send signal info to all the members of a group |
1317 | */ | 1318 | */ |
1318 | int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p, | 1319 | int group_send_sig_info(int sig, struct kernel_siginfo *info, |
1319 | enum pid_type type) | 1320 | struct task_struct *p, enum pid_type type) |
1320 | { | 1321 | { |
1321 | int ret; | 1322 | int ret; |
1322 | 1323 | ||
@@ -1335,7 +1336,7 @@ int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p, | |||
1335 | * control characters do (^C, ^Z etc) | 1336 | * control characters do (^C, ^Z etc) |
1336 | * - the caller must hold at least a readlock on tasklist_lock | 1337 | * - the caller must hold at least a readlock on tasklist_lock |
1337 | */ | 1338 | */ |
1338 | int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp) | 1339 | int __kill_pgrp_info(int sig, struct kernel_siginfo *info, struct pid *pgrp) |
1339 | { | 1340 | { |
1340 | struct task_struct *p = NULL; | 1341 | struct task_struct *p = NULL; |
1341 | int retval, success; | 1342 | int retval, success; |
@@ -1350,7 +1351,7 @@ int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp) | |||
1350 | return success ? 0 : retval; | 1351 | return success ? 0 : retval; |
1351 | } | 1352 | } |
1352 | 1353 | ||
1353 | int kill_pid_info(int sig, struct siginfo *info, struct pid *pid) | 1354 | int kill_pid_info(int sig, struct kernel_siginfo *info, struct pid *pid) |
1354 | { | 1355 | { |
1355 | int error = -ESRCH; | 1356 | int error = -ESRCH; |
1356 | struct task_struct *p; | 1357 | struct task_struct *p; |
@@ -1372,7 +1373,7 @@ int kill_pid_info(int sig, struct siginfo *info, struct pid *pid) | |||
1372 | } | 1373 | } |
1373 | } | 1374 | } |
1374 | 1375 | ||
1375 | static int kill_proc_info(int sig, struct siginfo *info, pid_t pid) | 1376 | static int kill_proc_info(int sig, struct kernel_siginfo *info, pid_t pid) |
1376 | { | 1377 | { |
1377 | int error; | 1378 | int error; |
1378 | rcu_read_lock(); | 1379 | rcu_read_lock(); |
@@ -1393,7 +1394,7 @@ static inline bool kill_as_cred_perm(const struct cred *cred, | |||
1393 | } | 1394 | } |
1394 | 1395 | ||
1395 | /* like kill_pid_info(), but doesn't use uid/euid of "current" */ | 1396 | /* like kill_pid_info(), but doesn't use uid/euid of "current" */ |
1396 | int kill_pid_info_as_cred(int sig, struct siginfo *info, struct pid *pid, | 1397 | int kill_pid_info_as_cred(int sig, struct kernel_siginfo *info, struct pid *pid, |
1397 | const struct cred *cred) | 1398 | const struct cred *cred) |
1398 | { | 1399 | { |
1399 | int ret = -EINVAL; | 1400 | int ret = -EINVAL; |
@@ -1437,7 +1438,7 @@ EXPORT_SYMBOL_GPL(kill_pid_info_as_cred); | |||
1437 | * is probably wrong. Should make it like BSD or SYSV. | 1438 | * is probably wrong. Should make it like BSD or SYSV. |
1438 | */ | 1439 | */ |
1439 | 1440 | ||
1440 | static int kill_something_info(int sig, struct siginfo *info, pid_t pid) | 1441 | static int kill_something_info(int sig, struct kernel_siginfo *info, pid_t pid) |
1441 | { | 1442 | { |
1442 | int ret; | 1443 | int ret; |
1443 | 1444 | ||
@@ -1481,7 +1482,7 @@ static int kill_something_info(int sig, struct siginfo *info, pid_t pid) | |||
1481 | * These are for backward compatibility with the rest of the kernel source. | 1482 | * These are for backward compatibility with the rest of the kernel source. |
1482 | */ | 1483 | */ |
1483 | 1484 | ||
1484 | int send_sig_info(int sig, struct siginfo *info, struct task_struct *p) | 1485 | int send_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *p) |
1485 | { | 1486 | { |
1486 | /* | 1487 | /* |
1487 | * Make sure legacy kernel users don't send in bad values | 1488 | * Make sure legacy kernel users don't send in bad values |
@@ -1492,6 +1493,7 @@ int send_sig_info(int sig, struct siginfo *info, struct task_struct *p) | |||
1492 | 1493 | ||
1493 | return do_send_sig_info(sig, info, p, PIDTYPE_PID); | 1494 | return do_send_sig_info(sig, info, p, PIDTYPE_PID); |
1494 | } | 1495 | } |
1496 | EXPORT_SYMBOL(send_sig_info); | ||
1495 | 1497 | ||
1496 | #define __si_special(priv) \ | 1498 | #define __si_special(priv) \ |
1497 | ((priv) ? SEND_SIG_PRIV : SEND_SIG_NOINFO) | 1499 | ((priv) ? SEND_SIG_PRIV : SEND_SIG_NOINFO) |
@@ -1501,11 +1503,13 @@ send_sig(int sig, struct task_struct *p, int priv) | |||
1501 | { | 1503 | { |
1502 | return send_sig_info(sig, __si_special(priv), p); | 1504 | return send_sig_info(sig, __si_special(priv), p); |
1503 | } | 1505 | } |
1506 | EXPORT_SYMBOL(send_sig); | ||
1504 | 1507 | ||
1505 | void force_sig(int sig, struct task_struct *p) | 1508 | void force_sig(int sig, struct task_struct *p) |
1506 | { | 1509 | { |
1507 | force_sig_info(sig, SEND_SIG_PRIV, p); | 1510 | force_sig_info(sig, SEND_SIG_PRIV, p); |
1508 | } | 1511 | } |
1512 | EXPORT_SYMBOL(force_sig); | ||
1509 | 1513 | ||
1510 | /* | 1514 | /* |
1511 | * When things go south during signal handling, we | 1515 | * When things go south during signal handling, we |
@@ -1529,7 +1533,7 @@ int force_sig_fault(int sig, int code, void __user *addr | |||
1529 | ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr) | 1533 | ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr) |
1530 | , struct task_struct *t) | 1534 | , struct task_struct *t) |
1531 | { | 1535 | { |
1532 | struct siginfo info; | 1536 | struct kernel_siginfo info; |
1533 | 1537 | ||
1534 | clear_siginfo(&info); | 1538 | clear_siginfo(&info); |
1535 | info.si_signo = sig; | 1539 | info.si_signo = sig; |
@@ -1552,7 +1556,7 @@ int send_sig_fault(int sig, int code, void __user *addr | |||
1552 | ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr) | 1556 | ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr) |
1553 | , struct task_struct *t) | 1557 | , struct task_struct *t) |
1554 | { | 1558 | { |
1555 | struct siginfo info; | 1559 | struct kernel_siginfo info; |
1556 | 1560 | ||
1557 | clear_siginfo(&info); | 1561 | clear_siginfo(&info); |
1558 | info.si_signo = sig; | 1562 | info.si_signo = sig; |
@@ -1572,7 +1576,7 @@ int send_sig_fault(int sig, int code, void __user *addr | |||
1572 | 1576 | ||
1573 | int force_sig_mceerr(int code, void __user *addr, short lsb, struct task_struct *t) | 1577 | int force_sig_mceerr(int code, void __user *addr, short lsb, struct task_struct *t) |
1574 | { | 1578 | { |
1575 | struct siginfo info; | 1579 | struct kernel_siginfo info; |
1576 | 1580 | ||
1577 | WARN_ON((code != BUS_MCEERR_AO) && (code != BUS_MCEERR_AR)); | 1581 | WARN_ON((code != BUS_MCEERR_AO) && (code != BUS_MCEERR_AR)); |
1578 | clear_siginfo(&info); | 1582 | clear_siginfo(&info); |
@@ -1586,7 +1590,7 @@ int force_sig_mceerr(int code, void __user *addr, short lsb, struct task_struct | |||
1586 | 1590 | ||
1587 | int send_sig_mceerr(int code, void __user *addr, short lsb, struct task_struct *t) | 1591 | int send_sig_mceerr(int code, void __user *addr, short lsb, struct task_struct *t) |
1588 | { | 1592 | { |
1589 | struct siginfo info; | 1593 | struct kernel_siginfo info; |
1590 | 1594 | ||
1591 | WARN_ON((code != BUS_MCEERR_AO) && (code != BUS_MCEERR_AR)); | 1595 | WARN_ON((code != BUS_MCEERR_AO) && (code != BUS_MCEERR_AR)); |
1592 | clear_siginfo(&info); | 1596 | clear_siginfo(&info); |
@@ -1601,7 +1605,7 @@ EXPORT_SYMBOL(send_sig_mceerr); | |||
1601 | 1605 | ||
1602 | int force_sig_bnderr(void __user *addr, void __user *lower, void __user *upper) | 1606 | int force_sig_bnderr(void __user *addr, void __user *lower, void __user *upper) |
1603 | { | 1607 | { |
1604 | struct siginfo info; | 1608 | struct kernel_siginfo info; |
1605 | 1609 | ||
1606 | clear_siginfo(&info); | 1610 | clear_siginfo(&info); |
1607 | info.si_signo = SIGSEGV; | 1611 | info.si_signo = SIGSEGV; |
@@ -1616,7 +1620,7 @@ int force_sig_bnderr(void __user *addr, void __user *lower, void __user *upper) | |||
1616 | #ifdef SEGV_PKUERR | 1620 | #ifdef SEGV_PKUERR |
1617 | int force_sig_pkuerr(void __user *addr, u32 pkey) | 1621 | int force_sig_pkuerr(void __user *addr, u32 pkey) |
1618 | { | 1622 | { |
1619 | struct siginfo info; | 1623 | struct kernel_siginfo info; |
1620 | 1624 | ||
1621 | clear_siginfo(&info); | 1625 | clear_siginfo(&info); |
1622 | info.si_signo = SIGSEGV; | 1626 | info.si_signo = SIGSEGV; |
@@ -1633,7 +1637,7 @@ int force_sig_pkuerr(void __user *addr, u32 pkey) | |||
1633 | */ | 1637 | */ |
1634 | int force_sig_ptrace_errno_trap(int errno, void __user *addr) | 1638 | int force_sig_ptrace_errno_trap(int errno, void __user *addr) |
1635 | { | 1639 | { |
1636 | struct siginfo info; | 1640 | struct kernel_siginfo info; |
1637 | 1641 | ||
1638 | clear_siginfo(&info); | 1642 | clear_siginfo(&info); |
1639 | info.si_signo = SIGTRAP; | 1643 | info.si_signo = SIGTRAP; |
@@ -1762,7 +1766,7 @@ ret: | |||
1762 | */ | 1766 | */ |
1763 | bool do_notify_parent(struct task_struct *tsk, int sig) | 1767 | bool do_notify_parent(struct task_struct *tsk, int sig) |
1764 | { | 1768 | { |
1765 | struct siginfo info; | 1769 | struct kernel_siginfo info; |
1766 | unsigned long flags; | 1770 | unsigned long flags; |
1767 | struct sighand_struct *psig; | 1771 | struct sighand_struct *psig; |
1768 | bool autoreap = false; | 1772 | bool autoreap = false; |
@@ -1867,7 +1871,7 @@ bool do_notify_parent(struct task_struct *tsk, int sig) | |||
1867 | static void do_notify_parent_cldstop(struct task_struct *tsk, | 1871 | static void do_notify_parent_cldstop(struct task_struct *tsk, |
1868 | bool for_ptracer, int why) | 1872 | bool for_ptracer, int why) |
1869 | { | 1873 | { |
1870 | struct siginfo info; | 1874 | struct kernel_siginfo info; |
1871 | unsigned long flags; | 1875 | unsigned long flags; |
1872 | struct task_struct *parent; | 1876 | struct task_struct *parent; |
1873 | struct sighand_struct *sighand; | 1877 | struct sighand_struct *sighand; |
@@ -1967,7 +1971,7 @@ static bool sigkill_pending(struct task_struct *tsk) | |||
1967 | * If we actually decide not to stop at all because the tracer | 1971 | * If we actually decide not to stop at all because the tracer |
1968 | * is gone, we keep current->exit_code unless clear_code. | 1972 | * is gone, we keep current->exit_code unless clear_code. |
1969 | */ | 1973 | */ |
1970 | static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) | 1974 | static void ptrace_stop(int exit_code, int why, int clear_code, kernel_siginfo_t *info) |
1971 | __releases(¤t->sighand->siglock) | 1975 | __releases(¤t->sighand->siglock) |
1972 | __acquires(¤t->sighand->siglock) | 1976 | __acquires(¤t->sighand->siglock) |
1973 | { | 1977 | { |
@@ -2104,7 +2108,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, siginfo_t *info) | |||
2104 | 2108 | ||
2105 | static void ptrace_do_notify(int signr, int exit_code, int why) | 2109 | static void ptrace_do_notify(int signr, int exit_code, int why) |
2106 | { | 2110 | { |
2107 | siginfo_t info; | 2111 | kernel_siginfo_t info; |
2108 | 2112 | ||
2109 | clear_siginfo(&info); | 2113 | clear_siginfo(&info); |
2110 | info.si_signo = signr; | 2114 | info.si_signo = signr; |
@@ -2285,7 +2289,7 @@ static void do_jobctl_trap(void) | |||
2285 | } | 2289 | } |
2286 | } | 2290 | } |
2287 | 2291 | ||
2288 | static int ptrace_signal(int signr, siginfo_t *info) | 2292 | static int ptrace_signal(int signr, kernel_siginfo_t *info) |
2289 | { | 2293 | { |
2290 | /* | 2294 | /* |
2291 | * We do not check sig_kernel_stop(signr) but set this marker | 2295 | * We do not check sig_kernel_stop(signr) but set this marker |
@@ -2326,7 +2330,7 @@ static int ptrace_signal(int signr, siginfo_t *info) | |||
2326 | 2330 | ||
2327 | /* If the (new) signal is now blocked, requeue it. */ | 2331 | /* If the (new) signal is now blocked, requeue it. */ |
2328 | if (sigismember(¤t->blocked, signr)) { | 2332 | if (sigismember(¤t->blocked, signr)) { |
2329 | specific_send_sig_info(signr, info, current); | 2333 | send_signal(signr, info, current, PIDTYPE_PID); |
2330 | signr = 0; | 2334 | signr = 0; |
2331 | } | 2335 | } |
2332 | 2336 | ||
@@ -2636,14 +2640,6 @@ out: | |||
2636 | } | 2640 | } |
2637 | } | 2641 | } |
2638 | 2642 | ||
2639 | EXPORT_SYMBOL(recalc_sigpending); | ||
2640 | EXPORT_SYMBOL_GPL(dequeue_signal); | ||
2641 | EXPORT_SYMBOL(flush_signals); | ||
2642 | EXPORT_SYMBOL(force_sig); | ||
2643 | EXPORT_SYMBOL(send_sig); | ||
2644 | EXPORT_SYMBOL(send_sig_info); | ||
2645 | EXPORT_SYMBOL(sigprocmask); | ||
2646 | |||
2647 | /* | 2643 | /* |
2648 | * System call entry points. | 2644 | * System call entry points. |
2649 | */ | 2645 | */ |
@@ -2737,6 +2733,7 @@ int sigprocmask(int how, sigset_t *set, sigset_t *oldset) | |||
2737 | __set_current_blocked(&newset); | 2733 | __set_current_blocked(&newset); |
2738 | return 0; | 2734 | return 0; |
2739 | } | 2735 | } |
2736 | EXPORT_SYMBOL(sigprocmask); | ||
2740 | 2737 | ||
2741 | /** | 2738 | /** |
2742 | * sys_rt_sigprocmask - change the list of currently blocked signals | 2739 | * sys_rt_sigprocmask - change the list of currently blocked signals |
@@ -2847,27 +2844,48 @@ COMPAT_SYSCALL_DEFINE2(rt_sigpending, compat_sigset_t __user *, uset, | |||
2847 | } | 2844 | } |
2848 | #endif | 2845 | #endif |
2849 | 2846 | ||
2850 | enum siginfo_layout siginfo_layout(int sig, int si_code) | 2847 | static const struct { |
2848 | unsigned char limit, layout; | ||
2849 | } sig_sicodes[] = { | ||
2850 | [SIGILL] = { NSIGILL, SIL_FAULT }, | ||
2851 | [SIGFPE] = { NSIGFPE, SIL_FAULT }, | ||
2852 | [SIGSEGV] = { NSIGSEGV, SIL_FAULT }, | ||
2853 | [SIGBUS] = { NSIGBUS, SIL_FAULT }, | ||
2854 | [SIGTRAP] = { NSIGTRAP, SIL_FAULT }, | ||
2855 | #if defined(SIGEMT) | ||
2856 | [SIGEMT] = { NSIGEMT, SIL_FAULT }, | ||
2857 | #endif | ||
2858 | [SIGCHLD] = { NSIGCHLD, SIL_CHLD }, | ||
2859 | [SIGPOLL] = { NSIGPOLL, SIL_POLL }, | ||
2860 | [SIGSYS] = { NSIGSYS, SIL_SYS }, | ||
2861 | }; | ||
2862 | |||
2863 | static bool known_siginfo_layout(unsigned sig, int si_code) | ||
2864 | { | ||
2865 | if (si_code == SI_KERNEL) | ||
2866 | return true; | ||
2867 | else if ((si_code > SI_USER)) { | ||
2868 | if (sig_specific_sicodes(sig)) { | ||
2869 | if (si_code <= sig_sicodes[sig].limit) | ||
2870 | return true; | ||
2871 | } | ||
2872 | else if (si_code <= NSIGPOLL) | ||
2873 | return true; | ||
2874 | } | ||
2875 | else if (si_code >= SI_DETHREAD) | ||
2876 | return true; | ||
2877 | else if (si_code == SI_ASYNCNL) | ||
2878 | return true; | ||
2879 | return false; | ||
2880 | } | ||
2881 | |||
2882 | enum siginfo_layout siginfo_layout(unsigned sig, int si_code) | ||
2851 | { | 2883 | { |
2852 | enum siginfo_layout layout = SIL_KILL; | 2884 | enum siginfo_layout layout = SIL_KILL; |
2853 | if ((si_code > SI_USER) && (si_code < SI_KERNEL)) { | 2885 | if ((si_code > SI_USER) && (si_code < SI_KERNEL)) { |
2854 | static const struct { | 2886 | if ((sig < ARRAY_SIZE(sig_sicodes)) && |
2855 | unsigned char limit, layout; | 2887 | (si_code <= sig_sicodes[sig].limit)) { |
2856 | } filter[] = { | 2888 | layout = sig_sicodes[sig].layout; |
2857 | [SIGILL] = { NSIGILL, SIL_FAULT }, | ||
2858 | [SIGFPE] = { NSIGFPE, SIL_FAULT }, | ||
2859 | [SIGSEGV] = { NSIGSEGV, SIL_FAULT }, | ||
2860 | [SIGBUS] = { NSIGBUS, SIL_FAULT }, | ||
2861 | [SIGTRAP] = { NSIGTRAP, SIL_FAULT }, | ||
2862 | #if defined(SIGEMT) && defined(NSIGEMT) | ||
2863 | [SIGEMT] = { NSIGEMT, SIL_FAULT }, | ||
2864 | #endif | ||
2865 | [SIGCHLD] = { NSIGCHLD, SIL_CHLD }, | ||
2866 | [SIGPOLL] = { NSIGPOLL, SIL_POLL }, | ||
2867 | [SIGSYS] = { NSIGSYS, SIL_SYS }, | ||
2868 | }; | ||
2869 | if ((sig < ARRAY_SIZE(filter)) && (si_code <= filter[sig].limit)) { | ||
2870 | layout = filter[sig].layout; | ||
2871 | /* Handle the exceptions */ | 2889 | /* Handle the exceptions */ |
2872 | if ((sig == SIGBUS) && | 2890 | if ((sig == SIGBUS) && |
2873 | (si_code >= BUS_MCEERR_AR) && (si_code <= BUS_MCEERR_AO)) | 2891 | (si_code >= BUS_MCEERR_AR) && (si_code <= BUS_MCEERR_AO)) |
@@ -2892,22 +2910,69 @@ enum siginfo_layout siginfo_layout(int sig, int si_code) | |||
2892 | return layout; | 2910 | return layout; |
2893 | } | 2911 | } |
2894 | 2912 | ||
2895 | int copy_siginfo_to_user(siginfo_t __user *to, const siginfo_t *from) | 2913 | static inline char __user *si_expansion(const siginfo_t __user *info) |
2914 | { | ||
2915 | return ((char __user *)info) + sizeof(struct kernel_siginfo); | ||
2916 | } | ||
2917 | |||
2918 | int copy_siginfo_to_user(siginfo_t __user *to, const kernel_siginfo_t *from) | ||
2896 | { | 2919 | { |
2897 | if (copy_to_user(to, from , sizeof(struct siginfo))) | 2920 | char __user *expansion = si_expansion(to); |
2921 | if (copy_to_user(to, from , sizeof(struct kernel_siginfo))) | ||
2922 | return -EFAULT; | ||
2923 | if (clear_user(expansion, SI_EXPANSION_SIZE)) | ||
2898 | return -EFAULT; | 2924 | return -EFAULT; |
2899 | return 0; | 2925 | return 0; |
2900 | } | 2926 | } |
2901 | 2927 | ||
2928 | static int post_copy_siginfo_from_user(kernel_siginfo_t *info, | ||
2929 | const siginfo_t __user *from) | ||
2930 | { | ||
2931 | if (unlikely(!known_siginfo_layout(info->si_signo, info->si_code))) { | ||
2932 | char __user *expansion = si_expansion(from); | ||
2933 | char buf[SI_EXPANSION_SIZE]; | ||
2934 | int i; | ||
2935 | /* | ||
2936 | * An unknown si_code might need more than | ||
2937 | * sizeof(struct kernel_siginfo) bytes. Verify all of the | ||
2938 | * extra bytes are 0. This guarantees copy_siginfo_to_user | ||
2939 | * will return this data to userspace exactly. | ||
2940 | */ | ||
2941 | if (copy_from_user(&buf, expansion, SI_EXPANSION_SIZE)) | ||
2942 | return -EFAULT; | ||
2943 | for (i = 0; i < SI_EXPANSION_SIZE; i++) { | ||
2944 | if (buf[i] != 0) | ||
2945 | return -E2BIG; | ||
2946 | } | ||
2947 | } | ||
2948 | return 0; | ||
2949 | } | ||
2950 | |||
2951 | static int __copy_siginfo_from_user(int signo, kernel_siginfo_t *to, | ||
2952 | const siginfo_t __user *from) | ||
2953 | { | ||
2954 | if (copy_from_user(to, from, sizeof(struct kernel_siginfo))) | ||
2955 | return -EFAULT; | ||
2956 | to->si_signo = signo; | ||
2957 | return post_copy_siginfo_from_user(to, from); | ||
2958 | } | ||
2959 | |||
2960 | int copy_siginfo_from_user(kernel_siginfo_t *to, const siginfo_t __user *from) | ||
2961 | { | ||
2962 | if (copy_from_user(to, from, sizeof(struct kernel_siginfo))) | ||
2963 | return -EFAULT; | ||
2964 | return post_copy_siginfo_from_user(to, from); | ||
2965 | } | ||
2966 | |||
2902 | #ifdef CONFIG_COMPAT | 2967 | #ifdef CONFIG_COMPAT |
2903 | int copy_siginfo_to_user32(struct compat_siginfo __user *to, | 2968 | int copy_siginfo_to_user32(struct compat_siginfo __user *to, |
2904 | const struct siginfo *from) | 2969 | const struct kernel_siginfo *from) |
2905 | #if defined(CONFIG_X86_X32_ABI) || defined(CONFIG_IA32_EMULATION) | 2970 | #if defined(CONFIG_X86_X32_ABI) || defined(CONFIG_IA32_EMULATION) |
2906 | { | 2971 | { |
2907 | return __copy_siginfo_to_user32(to, from, in_x32_syscall()); | 2972 | return __copy_siginfo_to_user32(to, from, in_x32_syscall()); |
2908 | } | 2973 | } |
2909 | int __copy_siginfo_to_user32(struct compat_siginfo __user *to, | 2974 | int __copy_siginfo_to_user32(struct compat_siginfo __user *to, |
2910 | const struct siginfo *from, bool x32_ABI) | 2975 | const struct kernel_siginfo *from, bool x32_ABI) |
2911 | #endif | 2976 | #endif |
2912 | { | 2977 | { |
2913 | struct compat_siginfo new; | 2978 | struct compat_siginfo new; |
@@ -2991,88 +3056,106 @@ int __copy_siginfo_to_user32(struct compat_siginfo __user *to, | |||
2991 | return 0; | 3056 | return 0; |
2992 | } | 3057 | } |
2993 | 3058 | ||
2994 | int copy_siginfo_from_user32(struct siginfo *to, | 3059 | static int post_copy_siginfo_from_user32(kernel_siginfo_t *to, |
2995 | const struct compat_siginfo __user *ufrom) | 3060 | const struct compat_siginfo *from) |
2996 | { | 3061 | { |
2997 | struct compat_siginfo from; | ||
2998 | |||
2999 | if (copy_from_user(&from, ufrom, sizeof(struct compat_siginfo))) | ||
3000 | return -EFAULT; | ||
3001 | |||
3002 | clear_siginfo(to); | 3062 | clear_siginfo(to); |
3003 | to->si_signo = from.si_signo; | 3063 | to->si_signo = from->si_signo; |
3004 | to->si_errno = from.si_errno; | 3064 | to->si_errno = from->si_errno; |
3005 | to->si_code = from.si_code; | 3065 | to->si_code = from->si_code; |
3006 | switch(siginfo_layout(from.si_signo, from.si_code)) { | 3066 | switch(siginfo_layout(from->si_signo, from->si_code)) { |
3007 | case SIL_KILL: | 3067 | case SIL_KILL: |
3008 | to->si_pid = from.si_pid; | 3068 | to->si_pid = from->si_pid; |
3009 | to->si_uid = from.si_uid; | 3069 | to->si_uid = from->si_uid; |
3010 | break; | 3070 | break; |
3011 | case SIL_TIMER: | 3071 | case SIL_TIMER: |
3012 | to->si_tid = from.si_tid; | 3072 | to->si_tid = from->si_tid; |
3013 | to->si_overrun = from.si_overrun; | 3073 | to->si_overrun = from->si_overrun; |
3014 | to->si_int = from.si_int; | 3074 | to->si_int = from->si_int; |
3015 | break; | 3075 | break; |
3016 | case SIL_POLL: | 3076 | case SIL_POLL: |
3017 | to->si_band = from.si_band; | 3077 | to->si_band = from->si_band; |
3018 | to->si_fd = from.si_fd; | 3078 | to->si_fd = from->si_fd; |
3019 | break; | 3079 | break; |
3020 | case SIL_FAULT: | 3080 | case SIL_FAULT: |
3021 | to->si_addr = compat_ptr(from.si_addr); | 3081 | to->si_addr = compat_ptr(from->si_addr); |
3022 | #ifdef __ARCH_SI_TRAPNO | 3082 | #ifdef __ARCH_SI_TRAPNO |
3023 | to->si_trapno = from.si_trapno; | 3083 | to->si_trapno = from->si_trapno; |
3024 | #endif | 3084 | #endif |
3025 | break; | 3085 | break; |
3026 | case SIL_FAULT_MCEERR: | 3086 | case SIL_FAULT_MCEERR: |
3027 | to->si_addr = compat_ptr(from.si_addr); | 3087 | to->si_addr = compat_ptr(from->si_addr); |
3028 | #ifdef __ARCH_SI_TRAPNO | 3088 | #ifdef __ARCH_SI_TRAPNO |
3029 | to->si_trapno = from.si_trapno; | 3089 | to->si_trapno = from->si_trapno; |
3030 | #endif | 3090 | #endif |
3031 | to->si_addr_lsb = from.si_addr_lsb; | 3091 | to->si_addr_lsb = from->si_addr_lsb; |
3032 | break; | 3092 | break; |
3033 | case SIL_FAULT_BNDERR: | 3093 | case SIL_FAULT_BNDERR: |
3034 | to->si_addr = compat_ptr(from.si_addr); | 3094 | to->si_addr = compat_ptr(from->si_addr); |
3035 | #ifdef __ARCH_SI_TRAPNO | 3095 | #ifdef __ARCH_SI_TRAPNO |
3036 | to->si_trapno = from.si_trapno; | 3096 | to->si_trapno = from->si_trapno; |
3037 | #endif | 3097 | #endif |
3038 | to->si_lower = compat_ptr(from.si_lower); | 3098 | to->si_lower = compat_ptr(from->si_lower); |
3039 | to->si_upper = compat_ptr(from.si_upper); | 3099 | to->si_upper = compat_ptr(from->si_upper); |
3040 | break; | 3100 | break; |
3041 | case SIL_FAULT_PKUERR: | 3101 | case SIL_FAULT_PKUERR: |
3042 | to->si_addr = compat_ptr(from.si_addr); | 3102 | to->si_addr = compat_ptr(from->si_addr); |
3043 | #ifdef __ARCH_SI_TRAPNO | 3103 | #ifdef __ARCH_SI_TRAPNO |
3044 | to->si_trapno = from.si_trapno; | 3104 | to->si_trapno = from->si_trapno; |
3045 | #endif | 3105 | #endif |
3046 | to->si_pkey = from.si_pkey; | 3106 | to->si_pkey = from->si_pkey; |
3047 | break; | 3107 | break; |
3048 | case SIL_CHLD: | 3108 | case SIL_CHLD: |
3049 | to->si_pid = from.si_pid; | 3109 | to->si_pid = from->si_pid; |
3050 | to->si_uid = from.si_uid; | 3110 | to->si_uid = from->si_uid; |
3051 | to->si_status = from.si_status; | 3111 | to->si_status = from->si_status; |
3052 | #ifdef CONFIG_X86_X32_ABI | 3112 | #ifdef CONFIG_X86_X32_ABI |
3053 | if (in_x32_syscall()) { | 3113 | if (in_x32_syscall()) { |
3054 | to->si_utime = from._sifields._sigchld_x32._utime; | 3114 | to->si_utime = from->_sifields._sigchld_x32._utime; |
3055 | to->si_stime = from._sifields._sigchld_x32._stime; | 3115 | to->si_stime = from->_sifields._sigchld_x32._stime; |
3056 | } else | 3116 | } else |
3057 | #endif | 3117 | #endif |
3058 | { | 3118 | { |
3059 | to->si_utime = from.si_utime; | 3119 | to->si_utime = from->si_utime; |
3060 | to->si_stime = from.si_stime; | 3120 | to->si_stime = from->si_stime; |
3061 | } | 3121 | } |
3062 | break; | 3122 | break; |
3063 | case SIL_RT: | 3123 | case SIL_RT: |
3064 | to->si_pid = from.si_pid; | 3124 | to->si_pid = from->si_pid; |
3065 | to->si_uid = from.si_uid; | 3125 | to->si_uid = from->si_uid; |
3066 | to->si_int = from.si_int; | 3126 | to->si_int = from->si_int; |
3067 | break; | 3127 | break; |
3068 | case SIL_SYS: | 3128 | case SIL_SYS: |
3069 | to->si_call_addr = compat_ptr(from.si_call_addr); | 3129 | to->si_call_addr = compat_ptr(from->si_call_addr); |
3070 | to->si_syscall = from.si_syscall; | 3130 | to->si_syscall = from->si_syscall; |
3071 | to->si_arch = from.si_arch; | 3131 | to->si_arch = from->si_arch; |
3072 | break; | 3132 | break; |
3073 | } | 3133 | } |
3074 | return 0; | 3134 | return 0; |
3075 | } | 3135 | } |
3136 | |||
3137 | static int __copy_siginfo_from_user32(int signo, struct kernel_siginfo *to, | ||
3138 | const struct compat_siginfo __user *ufrom) | ||
3139 | { | ||
3140 | struct compat_siginfo from; | ||
3141 | |||
3142 | if (copy_from_user(&from, ufrom, sizeof(struct compat_siginfo))) | ||
3143 | return -EFAULT; | ||
3144 | |||
3145 | from.si_signo = signo; | ||
3146 | return post_copy_siginfo_from_user32(to, &from); | ||
3147 | } | ||
3148 | |||
3149 | int copy_siginfo_from_user32(struct kernel_siginfo *to, | ||
3150 | const struct compat_siginfo __user *ufrom) | ||
3151 | { | ||
3152 | struct compat_siginfo from; | ||
3153 | |||
3154 | if (copy_from_user(&from, ufrom, sizeof(struct compat_siginfo))) | ||
3155 | return -EFAULT; | ||
3156 | |||
3157 | return post_copy_siginfo_from_user32(to, &from); | ||
3158 | } | ||
3076 | #endif /* CONFIG_COMPAT */ | 3159 | #endif /* CONFIG_COMPAT */ |
3077 | 3160 | ||
3078 | /** | 3161 | /** |
@@ -3081,7 +3164,7 @@ int copy_siginfo_from_user32(struct siginfo *to, | |||
3081 | * @info: if non-null, the signal's siginfo is returned here | 3164 | * @info: if non-null, the signal's siginfo is returned here |
3082 | * @ts: upper bound on process time suspension | 3165 | * @ts: upper bound on process time suspension |
3083 | */ | 3166 | */ |
3084 | static int do_sigtimedwait(const sigset_t *which, siginfo_t *info, | 3167 | static int do_sigtimedwait(const sigset_t *which, kernel_siginfo_t *info, |
3085 | const struct timespec *ts) | 3168 | const struct timespec *ts) |
3086 | { | 3169 | { |
3087 | ktime_t *to = NULL, timeout = KTIME_MAX; | 3170 | ktime_t *to = NULL, timeout = KTIME_MAX; |
@@ -3145,7 +3228,7 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese, | |||
3145 | { | 3228 | { |
3146 | sigset_t these; | 3229 | sigset_t these; |
3147 | struct timespec ts; | 3230 | struct timespec ts; |
3148 | siginfo_t info; | 3231 | kernel_siginfo_t info; |
3149 | int ret; | 3232 | int ret; |
3150 | 3233 | ||
3151 | /* XXX: Don't preclude handling different sized sigset_t's. */ | 3234 | /* XXX: Don't preclude handling different sized sigset_t's. */ |
@@ -3177,7 +3260,7 @@ COMPAT_SYSCALL_DEFINE4(rt_sigtimedwait, compat_sigset_t __user *, uthese, | |||
3177 | { | 3260 | { |
3178 | sigset_t s; | 3261 | sigset_t s; |
3179 | struct timespec t; | 3262 | struct timespec t; |
3180 | siginfo_t info; | 3263 | kernel_siginfo_t info; |
3181 | long ret; | 3264 | long ret; |
3182 | 3265 | ||
3183 | if (sigsetsize != sizeof(sigset_t)) | 3266 | if (sigsetsize != sizeof(sigset_t)) |
@@ -3209,7 +3292,7 @@ COMPAT_SYSCALL_DEFINE4(rt_sigtimedwait, compat_sigset_t __user *, uthese, | |||
3209 | */ | 3292 | */ |
3210 | SYSCALL_DEFINE2(kill, pid_t, pid, int, sig) | 3293 | SYSCALL_DEFINE2(kill, pid_t, pid, int, sig) |
3211 | { | 3294 | { |
3212 | struct siginfo info; | 3295 | struct kernel_siginfo info; |
3213 | 3296 | ||
3214 | clear_siginfo(&info); | 3297 | clear_siginfo(&info); |
3215 | info.si_signo = sig; | 3298 | info.si_signo = sig; |
@@ -3222,7 +3305,7 @@ SYSCALL_DEFINE2(kill, pid_t, pid, int, sig) | |||
3222 | } | 3305 | } |
3223 | 3306 | ||
3224 | static int | 3307 | static int |
3225 | do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info) | 3308 | do_send_specific(pid_t tgid, pid_t pid, int sig, struct kernel_siginfo *info) |
3226 | { | 3309 | { |
3227 | struct task_struct *p; | 3310 | struct task_struct *p; |
3228 | int error = -ESRCH; | 3311 | int error = -ESRCH; |
@@ -3253,7 +3336,7 @@ do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info) | |||
3253 | 3336 | ||
3254 | static int do_tkill(pid_t tgid, pid_t pid, int sig) | 3337 | static int do_tkill(pid_t tgid, pid_t pid, int sig) |
3255 | { | 3338 | { |
3256 | struct siginfo info; | 3339 | struct kernel_siginfo info; |
3257 | 3340 | ||
3258 | clear_siginfo(&info); | 3341 | clear_siginfo(&info); |
3259 | info.si_signo = sig; | 3342 | info.si_signo = sig; |
@@ -3300,7 +3383,7 @@ SYSCALL_DEFINE2(tkill, pid_t, pid, int, sig) | |||
3300 | return do_tkill(0, pid, sig); | 3383 | return do_tkill(0, pid, sig); |
3301 | } | 3384 | } |
3302 | 3385 | ||
3303 | static int do_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t *info) | 3386 | static int do_rt_sigqueueinfo(pid_t pid, int sig, kernel_siginfo_t *info) |
3304 | { | 3387 | { |
3305 | /* Not even root can pretend to send signals from the kernel. | 3388 | /* Not even root can pretend to send signals from the kernel. |
3306 | * Nor can they impersonate a kill()/tgkill(), which adds source info. | 3389 | * Nor can they impersonate a kill()/tgkill(), which adds source info. |
@@ -3309,8 +3392,6 @@ static int do_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t *info) | |||
3309 | (task_pid_vnr(current) != pid)) | 3392 | (task_pid_vnr(current) != pid)) |
3310 | return -EPERM; | 3393 | return -EPERM; |
3311 | 3394 | ||
3312 | info->si_signo = sig; | ||
3313 | |||
3314 | /* POSIX.1b doesn't mention process groups. */ | 3395 | /* POSIX.1b doesn't mention process groups. */ |
3315 | return kill_proc_info(sig, info, pid); | 3396 | return kill_proc_info(sig, info, pid); |
3316 | } | 3397 | } |
@@ -3324,9 +3405,10 @@ static int do_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t *info) | |||
3324 | SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig, | 3405 | SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig, |
3325 | siginfo_t __user *, uinfo) | 3406 | siginfo_t __user *, uinfo) |
3326 | { | 3407 | { |
3327 | siginfo_t info; | 3408 | kernel_siginfo_t info; |
3328 | if (copy_from_user(&info, uinfo, sizeof(siginfo_t))) | 3409 | int ret = __copy_siginfo_from_user(sig, &info, uinfo); |
3329 | return -EFAULT; | 3410 | if (unlikely(ret)) |
3411 | return ret; | ||
3330 | return do_rt_sigqueueinfo(pid, sig, &info); | 3412 | return do_rt_sigqueueinfo(pid, sig, &info); |
3331 | } | 3413 | } |
3332 | 3414 | ||
@@ -3336,15 +3418,15 @@ COMPAT_SYSCALL_DEFINE3(rt_sigqueueinfo, | |||
3336 | int, sig, | 3418 | int, sig, |
3337 | struct compat_siginfo __user *, uinfo) | 3419 | struct compat_siginfo __user *, uinfo) |
3338 | { | 3420 | { |
3339 | siginfo_t info; | 3421 | kernel_siginfo_t info; |
3340 | int ret = copy_siginfo_from_user32(&info, uinfo); | 3422 | int ret = __copy_siginfo_from_user32(sig, &info, uinfo); |
3341 | if (unlikely(ret)) | 3423 | if (unlikely(ret)) |
3342 | return ret; | 3424 | return ret; |
3343 | return do_rt_sigqueueinfo(pid, sig, &info); | 3425 | return do_rt_sigqueueinfo(pid, sig, &info); |
3344 | } | 3426 | } |
3345 | #endif | 3427 | #endif |
3346 | 3428 | ||
3347 | static int do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info) | 3429 | static int do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, kernel_siginfo_t *info) |
3348 | { | 3430 | { |
3349 | /* This is only valid for single tasks */ | 3431 | /* This is only valid for single tasks */ |
3350 | if (pid <= 0 || tgid <= 0) | 3432 | if (pid <= 0 || tgid <= 0) |
@@ -3357,19 +3439,16 @@ static int do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info) | |||
3357 | (task_pid_vnr(current) != pid)) | 3439 | (task_pid_vnr(current) != pid)) |
3358 | return -EPERM; | 3440 | return -EPERM; |
3359 | 3441 | ||
3360 | info->si_signo = sig; | ||
3361 | |||
3362 | return do_send_specific(tgid, pid, sig, info); | 3442 | return do_send_specific(tgid, pid, sig, info); |
3363 | } | 3443 | } |
3364 | 3444 | ||
3365 | SYSCALL_DEFINE4(rt_tgsigqueueinfo, pid_t, tgid, pid_t, pid, int, sig, | 3445 | SYSCALL_DEFINE4(rt_tgsigqueueinfo, pid_t, tgid, pid_t, pid, int, sig, |
3366 | siginfo_t __user *, uinfo) | 3446 | siginfo_t __user *, uinfo) |
3367 | { | 3447 | { |
3368 | siginfo_t info; | 3448 | kernel_siginfo_t info; |
3369 | 3449 | int ret = __copy_siginfo_from_user(sig, &info, uinfo); | |
3370 | if (copy_from_user(&info, uinfo, sizeof(siginfo_t))) | 3450 | if (unlikely(ret)) |
3371 | return -EFAULT; | 3451 | return ret; |
3372 | |||
3373 | return do_rt_tgsigqueueinfo(tgid, pid, sig, &info); | 3452 | return do_rt_tgsigqueueinfo(tgid, pid, sig, &info); |
3374 | } | 3453 | } |
3375 | 3454 | ||
@@ -3380,10 +3459,10 @@ COMPAT_SYSCALL_DEFINE4(rt_tgsigqueueinfo, | |||
3380 | int, sig, | 3459 | int, sig, |
3381 | struct compat_siginfo __user *, uinfo) | 3460 | struct compat_siginfo __user *, uinfo) |
3382 | { | 3461 | { |
3383 | siginfo_t info; | 3462 | kernel_siginfo_t info; |
3384 | 3463 | int ret = __copy_siginfo_from_user32(sig, &info, uinfo); | |
3385 | if (copy_siginfo_from_user32(&info, uinfo)) | 3464 | if (unlikely(ret)) |
3386 | return -EFAULT; | 3465 | return ret; |
3387 | return do_rt_tgsigqueueinfo(tgid, pid, sig, &info); | 3466 | return do_rt_tgsigqueueinfo(tgid, pid, sig, &info); |
3388 | } | 3467 | } |
3389 | #endif | 3468 | #endif |
@@ -3966,13 +4045,57 @@ __weak const char *arch_vma_name(struct vm_area_struct *vma) | |||
3966 | return NULL; | 4045 | return NULL; |
3967 | } | 4046 | } |
3968 | 4047 | ||
3969 | void __init signals_init(void) | 4048 | static inline void siginfo_buildtime_checks(void) |
3970 | { | 4049 | { |
3971 | /* If this check fails, the __ARCH_SI_PREAMBLE_SIZE value is wrong! */ | ||
3972 | BUILD_BUG_ON(__ARCH_SI_PREAMBLE_SIZE | ||
3973 | != offsetof(struct siginfo, _sifields._pad)); | ||
3974 | BUILD_BUG_ON(sizeof(struct siginfo) != SI_MAX_SIZE); | 4050 | BUILD_BUG_ON(sizeof(struct siginfo) != SI_MAX_SIZE); |
3975 | 4051 | ||
4052 | /* Verify the offsets in the two siginfos match */ | ||
4053 | #define CHECK_OFFSET(field) \ | ||
4054 | BUILD_BUG_ON(offsetof(siginfo_t, field) != offsetof(kernel_siginfo_t, field)) | ||
4055 | |||
4056 | /* kill */ | ||
4057 | CHECK_OFFSET(si_pid); | ||
4058 | CHECK_OFFSET(si_uid); | ||
4059 | |||
4060 | /* timer */ | ||
4061 | CHECK_OFFSET(si_tid); | ||
4062 | CHECK_OFFSET(si_overrun); | ||
4063 | CHECK_OFFSET(si_value); | ||
4064 | |||
4065 | /* rt */ | ||
4066 | CHECK_OFFSET(si_pid); | ||
4067 | CHECK_OFFSET(si_uid); | ||
4068 | CHECK_OFFSET(si_value); | ||
4069 | |||
4070 | /* sigchld */ | ||
4071 | CHECK_OFFSET(si_pid); | ||
4072 | CHECK_OFFSET(si_uid); | ||
4073 | CHECK_OFFSET(si_status); | ||
4074 | CHECK_OFFSET(si_utime); | ||
4075 | CHECK_OFFSET(si_stime); | ||
4076 | |||
4077 | /* sigfault */ | ||
4078 | CHECK_OFFSET(si_addr); | ||
4079 | CHECK_OFFSET(si_addr_lsb); | ||
4080 | CHECK_OFFSET(si_lower); | ||
4081 | CHECK_OFFSET(si_upper); | ||
4082 | CHECK_OFFSET(si_pkey); | ||
4083 | |||
4084 | /* sigpoll */ | ||
4085 | CHECK_OFFSET(si_band); | ||
4086 | CHECK_OFFSET(si_fd); | ||
4087 | |||
4088 | /* sigsys */ | ||
4089 | CHECK_OFFSET(si_call_addr); | ||
4090 | CHECK_OFFSET(si_syscall); | ||
4091 | CHECK_OFFSET(si_arch); | ||
4092 | #undef CHECK_OFFSET | ||
4093 | } | ||
4094 | |||
4095 | void __init signals_init(void) | ||
4096 | { | ||
4097 | siginfo_buildtime_checks(); | ||
4098 | |||
3976 | sigqueue_cachep = KMEM_CACHE(sigqueue, SLAB_PANIC); | 4099 | sigqueue_cachep = KMEM_CACHE(sigqueue, SLAB_PANIC); |
3977 | } | 4100 | } |
3978 | 4101 | ||
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 4b9127e95430..eabb4c22728d 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c | |||
@@ -308,7 +308,7 @@ static void common_hrtimer_rearm(struct k_itimer *timr) | |||
308 | * To protect against the timer going away while the interrupt is queued, | 308 | * To protect against the timer going away while the interrupt is queued, |
309 | * we require that the it_requeue_pending flag be set. | 309 | * we require that the it_requeue_pending flag be set. |
310 | */ | 310 | */ |
311 | void posixtimer_rearm(struct siginfo *info) | 311 | void posixtimer_rearm(struct kernel_siginfo *info) |
312 | { | 312 | { |
313 | struct k_itimer *timr; | 313 | struct k_itimer *timr; |
314 | unsigned long flags; | 314 | unsigned long flags; |
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index f10aa5360616..6589f60d5018 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -859,7 +859,7 @@ static void __oom_kill_process(struct task_struct *victim) | |||
859 | * in order to prevent the OOM victim from depleting the memory | 859 | * in order to prevent the OOM victim from depleting the memory |
860 | * reserves from the user space under its control. | 860 | * reserves from the user space under its control. |
861 | */ | 861 | */ |
862 | do_send_sig_info(SIGKILL, SEND_SIG_FORCED, victim, PIDTYPE_TGID); | 862 | do_send_sig_info(SIGKILL, SEND_SIG_PRIV, victim, PIDTYPE_TGID); |
863 | mark_oom_victim(victim); | 863 | mark_oom_victim(victim); |
864 | pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n", | 864 | pr_err("Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB\n", |
865 | task_pid_nr(victim), victim->comm, K(victim->mm->total_vm), | 865 | task_pid_nr(victim), victim->comm, K(victim->mm->total_vm), |
@@ -897,7 +897,7 @@ static void __oom_kill_process(struct task_struct *victim) | |||
897 | */ | 897 | */ |
898 | if (unlikely(p->flags & PF_KTHREAD)) | 898 | if (unlikely(p->flags & PF_KTHREAD)) |
899 | continue; | 899 | continue; |
900 | do_send_sig_info(SIGKILL, SEND_SIG_FORCED, p, PIDTYPE_TGID); | 900 | do_send_sig_info(SIGKILL, SEND_SIG_PRIV, p, PIDTYPE_TGID); |
901 | } | 901 | } |
902 | rcu_read_unlock(); | 902 | rcu_read_unlock(); |
903 | 903 | ||
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 8b8b70620bbe..cbcb8ba51142 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c | |||
@@ -732,7 +732,7 @@ static int apparmor_task_setrlimit(struct task_struct *task, | |||
732 | return error; | 732 | return error; |
733 | } | 733 | } |
734 | 734 | ||
735 | static int apparmor_task_kill(struct task_struct *target, struct siginfo *info, | 735 | static int apparmor_task_kill(struct task_struct *target, struct kernel_siginfo *info, |
736 | int sig, const struct cred *cred) | 736 | int sig, const struct cred *cred) |
737 | { | 737 | { |
738 | struct aa_label *cl, *tl; | 738 | struct aa_label *cl, *tl; |
diff --git a/security/security.c b/security/security.c index 736e78da1ab9..0d504fceda8b 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -1147,7 +1147,7 @@ int security_task_movememory(struct task_struct *p) | |||
1147 | return call_int_hook(task_movememory, 0, p); | 1147 | return call_int_hook(task_movememory, 0, p); |
1148 | } | 1148 | } |
1149 | 1149 | ||
1150 | int security_task_kill(struct task_struct *p, struct siginfo *info, | 1150 | int security_task_kill(struct task_struct *p, struct kernel_siginfo *info, |
1151 | int sig, const struct cred *cred) | 1151 | int sig, const struct cred *cred) |
1152 | { | 1152 | { |
1153 | return call_int_hook(task_kill, 0, p, info, sig, cred); | 1153 | return call_int_hook(task_kill, 0, p, info, sig, cred); |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ad9a9b8e9979..1b500b4c78a7 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -4186,7 +4186,7 @@ static int selinux_task_movememory(struct task_struct *p) | |||
4186 | PROCESS__SETSCHED, NULL); | 4186 | PROCESS__SETSCHED, NULL); |
4187 | } | 4187 | } |
4188 | 4188 | ||
4189 | static int selinux_task_kill(struct task_struct *p, struct siginfo *info, | 4189 | static int selinux_task_kill(struct task_struct *p, struct kernel_siginfo *info, |
4190 | int sig, const struct cred *cred) | 4190 | int sig, const struct cred *cred) |
4191 | { | 4191 | { |
4192 | u32 secid; | 4192 | u32 secid; |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 340fc30ad85d..025de76af1db 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -2251,7 +2251,7 @@ static int smack_task_movememory(struct task_struct *p) | |||
2251 | * Return 0 if write access is permitted | 2251 | * Return 0 if write access is permitted |
2252 | * | 2252 | * |
2253 | */ | 2253 | */ |
2254 | static int smack_task_kill(struct task_struct *p, struct siginfo *info, | 2254 | static int smack_task_kill(struct task_struct *p, struct kernel_siginfo *info, |
2255 | int sig, const struct cred *cred) | 2255 | int sig, const struct cred *cred) |
2256 | { | 2256 | { |
2257 | struct smk_audit_info ad; | 2257 | struct smk_audit_info ad; |
diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c index ed162a6c57c5..1a2c3a1c56ce 100644 --- a/virt/kvm/arm/mmu.c +++ b/virt/kvm/arm/mmu.c | |||
@@ -1450,20 +1450,14 @@ static void invalidate_icache_guest_page(kvm_pfn_t pfn, unsigned long size) | |||
1450 | static void kvm_send_hwpoison_signal(unsigned long address, | 1450 | static void kvm_send_hwpoison_signal(unsigned long address, |
1451 | struct vm_area_struct *vma) | 1451 | struct vm_area_struct *vma) |
1452 | { | 1452 | { |
1453 | siginfo_t info; | 1453 | short lsb; |
1454 | |||
1455 | clear_siginfo(&info); | ||
1456 | info.si_signo = SIGBUS; | ||
1457 | info.si_errno = 0; | ||
1458 | info.si_code = BUS_MCEERR_AR; | ||
1459 | info.si_addr = (void __user *)address; | ||
1460 | 1454 | ||
1461 | if (is_vm_hugetlb_page(vma)) | 1455 | if (is_vm_hugetlb_page(vma)) |
1462 | info.si_addr_lsb = huge_page_shift(hstate_vma(vma)); | 1456 | lsb = huge_page_shift(hstate_vma(vma)); |
1463 | else | 1457 | else |
1464 | info.si_addr_lsb = PAGE_SHIFT; | 1458 | lsb = PAGE_SHIFT; |
1465 | 1459 | ||
1466 | send_sig_info(SIGBUS, &info, current); | 1460 | send_sig_mceerr(BUS_MCEERR_AR, (void __user *)address, lsb, current); |
1467 | } | 1461 | } |
1468 | 1462 | ||
1469 | static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, | 1463 | static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, |