Merge branch 'stable-3.18' of git://git.infradead.org/users/pcmoore/selinux into...
[cascardo/linux.git] / arch / tile / kernel / compat_signal.c
1 /*
2  * Copyright 2010 Tilera Corporation. All Rights Reserved.
3  *
4  *   This program is free software; you can redistribute it and/or
5  *   modify it under the terms of the GNU General Public License
6  *   as published by the Free Software Foundation, version 2.
7  *
8  *   This program is distributed in the hope that it will be useful, but
9  *   WITHOUT ANY WARRANTY; without even the implied warranty of
10  *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
11  *   NON INFRINGEMENT.  See the GNU General Public License for
12  *   more details.
13  */
14
15 #include <linux/sched.h>
16 #include <linux/mm.h>
17 #include <linux/smp.h>
18 #include <linux/kernel.h>
19 #include <linux/signal.h>
20 #include <linux/errno.h>
21 #include <linux/wait.h>
22 #include <linux/unistd.h>
23 #include <linux/stddef.h>
24 #include <linux/personality.h>
25 #include <linux/suspend.h>
26 #include <linux/ptrace.h>
27 #include <linux/elf.h>
28 #include <linux/compat.h>
29 #include <linux/syscalls.h>
30 #include <linux/uaccess.h>
31 #include <asm/processor.h>
32 #include <asm/ucontext.h>
33 #include <asm/sigframe.h>
34 #include <asm/syscalls.h>
35 #include <asm/vdso.h>
36 #include <arch/interrupts.h>
37
38 struct compat_ucontext {
39         compat_ulong_t    uc_flags;
40         compat_uptr_t     uc_link;
41         struct compat_sigaltstack         uc_stack;
42         struct sigcontext uc_mcontext;
43         sigset_t          uc_sigmask;   /* mask last for extensibility */
44 };
45
46 struct compat_rt_sigframe {
47         unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */
48         struct compat_siginfo info;
49         struct compat_ucontext uc;
50 };
51
52 int copy_siginfo_to_user32(struct compat_siginfo __user *to, const siginfo_t *from)
53 {
54         int err;
55
56         if (!access_ok(VERIFY_WRITE, to, sizeof(struct compat_siginfo)))
57                 return -EFAULT;
58
59         /* If you change siginfo_t structure, please make sure that
60            this code is fixed accordingly.
61            It should never copy any pad contained in the structure
62            to avoid security leaks, but must copy the generic
63            3 ints plus the relevant union member.  */
64         err = __put_user(from->si_signo, &to->si_signo);
65         err |= __put_user(from->si_errno, &to->si_errno);
66         err |= __put_user((short)from->si_code, &to->si_code);
67
68         if (from->si_code < 0) {
69                 err |= __put_user(from->si_pid, &to->si_pid);
70                 err |= __put_user(from->si_uid, &to->si_uid);
71                 err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
72         } else {
73                 /*
74                  * First 32bits of unions are always present:
75                  * si_pid === si_band === si_tid === si_addr(LS half)
76                  */
77                 err |= __put_user(from->_sifields._pad[0],
78                                   &to->_sifields._pad[0]);
79                 switch (from->si_code >> 16) {
80                 case __SI_FAULT >> 16:
81                         break;
82                 case __SI_CHLD >> 16:
83                         err |= __put_user(from->si_utime, &to->si_utime);
84                         err |= __put_user(from->si_stime, &to->si_stime);
85                         err |= __put_user(from->si_status, &to->si_status);
86                         /* FALL THROUGH */
87                 default:
88                 case __SI_KILL >> 16:
89                         err |= __put_user(from->si_uid, &to->si_uid);
90                         break;
91                 case __SI_POLL >> 16:
92                         err |= __put_user(from->si_fd, &to->si_fd);
93                         break;
94                 case __SI_TIMER >> 16:
95                         err |= __put_user(from->si_overrun, &to->si_overrun);
96                         err |= __put_user(ptr_to_compat(from->si_ptr),
97                                           &to->si_ptr);
98                         break;
99                          /* This is not generated by the kernel as of now.  */
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
110 int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
111 {
112         int err;
113         u32 ptr32;
114
115         if (!access_ok(VERIFY_READ, from, sizeof(struct compat_siginfo)))
116                 return -EFAULT;
117
118         err = __get_user(to->si_signo, &from->si_signo);
119         err |= __get_user(to->si_errno, &from->si_errno);
120         err |= __get_user(to->si_code, &from->si_code);
121
122         err |= __get_user(to->si_pid, &from->si_pid);
123         err |= __get_user(to->si_uid, &from->si_uid);
124         err |= __get_user(ptr32, &from->si_ptr);
125         to->si_ptr = compat_ptr(ptr32);
126
127         return err;
128 }
129
130 /* The assembly shim for this function arranges to ignore the return value. */
131 long compat_sys_rt_sigreturn(void)
132 {
133         struct pt_regs *regs = current_pt_regs();
134         struct compat_rt_sigframe __user *frame =
135                 (struct compat_rt_sigframe __user *) compat_ptr(regs->sp);
136         sigset_t set;
137
138         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
139                 goto badframe;
140         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
141                 goto badframe;
142
143         set_current_blocked(&set);
144
145         if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
146                 goto badframe;
147
148         if (compat_restore_altstack(&frame->uc.uc_stack))
149                 goto badframe;
150
151         return 0;
152
153 badframe:
154         signal_fault("bad sigreturn frame", regs, frame, 0);
155         return 0;
156 }
157
158 /*
159  * Determine which stack to use..
160  */
161 static inline void __user *compat_get_sigframe(struct k_sigaction *ka,
162                                                struct pt_regs *regs,
163                                                size_t frame_size)
164 {
165         unsigned long sp;
166
167         /* Default to using normal stack */
168         sp = (unsigned long)compat_ptr(regs->sp);
169
170         /*
171          * If we are on the alternate signal stack and would overflow
172          * it, don't.  Return an always-bogus address instead so we
173          * will die with SIGSEGV.
174          */
175         if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
176                 return (void __user __force *)-1UL;
177
178         /* This is the X/Open sanctioned signal stack switching.  */
179         if (ka->sa.sa_flags & SA_ONSTACK) {
180                 if (sas_ss_flags(sp) == 0)
181                         sp = current->sas_ss_sp + current->sas_ss_size;
182         }
183
184         sp -= frame_size;
185         /*
186          * Align the stack pointer according to the TILE ABI,
187          * i.e. so that on function entry (sp & 15) == 0.
188          */
189         sp &= -16UL;
190         return (void __user *) sp;
191 }
192
193 int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
194                           struct pt_regs *regs)
195 {
196         unsigned long restorer;
197         struct compat_rt_sigframe __user *frame;
198         int err = 0, sig = ksig->sig;
199         int usig;
200
201         frame = compat_get_sigframe(&ksig->ka, regs, sizeof(*frame));
202
203         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
204                 goto err;
205
206         usig = current_thread_info()->exec_domain
207                 && current_thread_info()->exec_domain->signal_invmap
208                 && sig < 32
209                 ? current_thread_info()->exec_domain->signal_invmap[sig]
210                 : sig;
211
212         /* Always write at least the signal number for the stack backtracer. */
213         if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
214                 /* At sigreturn time, restore the callee-save registers too. */
215                 err |= copy_siginfo_to_user32(&frame->info, &ksig->info);
216                 regs->flags |= PT_FLAGS_RESTORE_REGS;
217         } else {
218                 err |= __put_user(ksig->info.si_signo, &frame->info.si_signo);
219         }
220
221         /* Create the ucontext.  */
222         err |= __clear_user(&frame->save_area, sizeof(frame->save_area));
223         err |= __put_user(0, &frame->uc.uc_flags);
224         err |= __put_user(0, &frame->uc.uc_link);
225         err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
226         err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
227         err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
228         if (err)
229                 goto err;
230
231         restorer = VDSO_SYM(&__vdso_rt_sigreturn);
232         if (ksig->ka.sa.sa_flags & SA_RESTORER)
233                 restorer = ptr_to_compat_reg(ksig->ka.sa.sa_restorer);
234
235         /*
236          * Set up registers for signal handler.
237          * Registers that we don't modify keep the value they had from
238          * user-space at the time we took the signal.
239          * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
240          * since some things rely on this (e.g. glibc's debug/segfault.c).
241          */
242         regs->pc = ptr_to_compat_reg(ksig->ka.sa.sa_handler);
243         regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
244         regs->sp = ptr_to_compat_reg(frame);
245         regs->lr = restorer;
246         regs->regs[0] = (unsigned long) usig;
247         regs->regs[1] = ptr_to_compat_reg(&frame->info);
248         regs->regs[2] = ptr_to_compat_reg(&frame->uc);
249         regs->flags |= PT_FLAGS_CALLER_SAVES;
250         return 0;
251
252 err:
253         trace_unhandled_signal("bad sigreturn frame", regs,
254                               (unsigned long)frame, SIGSEGV);
255         return -EFAULT;
256 }