1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/sched.h>
16#include <linux/sched/task_stack.h>
17#include <linux/mm.h>
18#include <linux/smp.h>
19#include <linux/kernel.h>
20#include <linux/signal.h>
21#include <linux/errno.h>
22#include <linux/wait.h>
23#include <linux/unistd.h>
24#include <linux/stddef.h>
25#include <linux/personality.h>
26#include <linux/suspend.h>
27#include <linux/ptrace.h>
28#include <linux/elf.h>
29#include <linux/compat.h>
30#include <linux/syscalls.h>
31#include <linux/uaccess.h>
32#include <asm/processor.h>
33#include <asm/ucontext.h>
34#include <asm/sigframe.h>
35#include <asm/syscalls.h>
36#include <asm/vdso.h>
37#include <arch/interrupts.h>
38
39struct compat_ucontext {
40 compat_ulong_t uc_flags;
41 compat_uptr_t uc_link;
42 struct compat_sigaltstack uc_stack;
43 struct sigcontext uc_mcontext;
44 sigset_t uc_sigmask;
45};
46
47struct compat_rt_sigframe {
48 unsigned char save_area[C_ABI_SAVE_AREA_SIZE];
49 struct compat_siginfo info;
50 struct compat_ucontext uc;
51};
52
53int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *from)
54{
55 int err;
56
57 if (!access_ok(VERIFY_WRITE, to, sizeof(struct compat_siginfo)))
58 return -EFAULT;
59
60
61
62
63
64
65 err = __put_user(from->si_signo, &to->si_signo);
66 err |= __put_user(from->si_errno, &to->si_errno);
67 err |= __put_user((short)from->si_code, &to->si_code);
68
69 if (from->si_code < 0) {
70 err |= __put_user(from->si_pid, &to->si_pid);
71 err |= __put_user(from->si_uid, &to->si_uid);
72 err |= __put_user(from->si_int, &to->si_int);
73 } else {
74
75
76
77
78 err |= __put_user(from->_sifields._pad[0],
79 &to->_sifields._pad[0]);
80 switch (from->si_code >> 16) {
81 case __SI_FAULT >> 16:
82 break;
83 case __SI_CHLD >> 16:
84 err |= __put_user(from->si_utime, &to->si_utime);
85 err |= __put_user(from->si_stime, &to->si_stime);
86 err |= __put_user(from->si_status, &to->si_status);
87
88 default:
89 case __SI_KILL >> 16:
90 err |= __put_user(from->si_uid, &to->si_uid);
91 break;
92 case __SI_POLL >> 16:
93 err |= __put_user(from->si_fd, &to->si_fd);
94 break;
95 case __SI_TIMER >> 16:
96 err |= __put_user(from->si_overrun, &to->si_overrun);
97 err |= __put_user(from->si_int, &to->si_int);
98 break;
99
100 case __SI_RT >> 16:
101 case __SI_MESGQ >> 16:
102 err |= __put_user(from->si_uid, &to->si_uid);
103 err |= __put_user(from->si_int, &to->si_int);
104 break;
105 }
106 }
107 return err;
108}
109
110int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
111{
112 int err;
113
114 if (!access_ok(VERIFY_READ, from, sizeof(struct compat_siginfo)))
115 return -EFAULT;
116
117 err = __get_user(to->si_signo, &from->si_signo);
118 err |= __get_user(to->si_errno, &from->si_errno);
119 err |= __get_user(to->si_code, &from->si_code);
120
121 err |= __get_user(to->si_pid, &from->si_pid);
122 err |= __get_user(to->si_uid, &from->si_uid);
123 err |= __get_user(to->si_int, &from->si_int);
124
125 return err;
126}
127
128
129long compat_sys_rt_sigreturn(void)
130{
131 struct pt_regs *regs = current_pt_regs();
132 struct compat_rt_sigframe __user *frame =
133 (struct compat_rt_sigframe __user *) compat_ptr(regs->sp);
134 sigset_t set;
135
136 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
137 goto badframe;
138 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
139 goto badframe;
140
141 set_current_blocked(&set);
142
143 if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
144 goto badframe;
145
146 if (compat_restore_altstack(&frame->uc.uc_stack))
147 goto badframe;
148
149 return 0;
150
151badframe:
152 signal_fault("bad sigreturn frame", regs, frame, 0);
153 return 0;
154}
155
156
157
158
159static inline void __user *compat_get_sigframe(struct k_sigaction *ka,
160 struct pt_regs *regs,
161 size_t frame_size)
162{
163 unsigned long sp;
164
165
166 sp = (unsigned long)compat_ptr(regs->sp);
167
168
169
170
171
172
173 if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
174 return (void __user __force *)-1UL;
175
176
177 if (ka->sa.sa_flags & SA_ONSTACK) {
178 if (sas_ss_flags(sp) == 0)
179 sp = current->sas_ss_sp + current->sas_ss_size;
180 }
181
182 sp -= frame_size;
183
184
185
186
187 sp &= -16UL;
188 return (void __user *) sp;
189}
190
191int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
192 struct pt_regs *regs)
193{
194 unsigned long restorer;
195 struct compat_rt_sigframe __user *frame;
196 int err = 0, sig = ksig->sig;
197
198 frame = compat_get_sigframe(&ksig->ka, regs, sizeof(*frame));
199
200 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
201 goto err;
202
203
204 if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
205
206 err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
207 regs->flags |= PT_FLAGS_RESTORE_REGS;
208 } else {
209 err |= __put_user(ksig->info.si_signo, &frame->info.si_signo);
210 }
211
212
213 err |= __clear_user(&frame->save_area, sizeof(frame->save_area));
214 err |= __put_user(0, &frame->uc.uc_flags);
215 err |= __put_user(0, &frame->uc.uc_link);
216 err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
217 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
218 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
219 if (err)
220 goto err;
221
222 restorer = VDSO_SYM(&__vdso_rt_sigreturn);
223 if (ksig->ka.sa.sa_flags & SA_RESTORER)
224 restorer = ptr_to_compat_reg(ksig->ka.sa.sa_restorer);
225
226
227
228
229
230
231
232
233 regs->pc = ptr_to_compat_reg(ksig->ka.sa.sa_handler);
234 regs->ex1 = PL_ICS_EX1(USER_PL, 1);
235 regs->sp = ptr_to_compat_reg(frame);
236 regs->lr = restorer;
237 regs->regs[0] = (unsigned long) sig;
238 regs->regs[1] = ptr_to_compat_reg(&frame->info);
239 regs->regs[2] = ptr_to_compat_reg(&frame->uc);
240 regs->flags |= PT_FLAGS_CALLER_SAVES;
241 return 0;
242
243err:
244 trace_unhandled_signal("bad sigreturn frame", regs,
245 (unsigned long)frame, SIGSEGV);
246 return -EFAULT;
247}
248