Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.2.
  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 <arch/interrupts.h>
 36
 37struct compat_sigaction {
 38	compat_uptr_t sa_handler;
 39	compat_ulong_t sa_flags;
 40	compat_uptr_t sa_restorer;
 41	sigset_t sa_mask __packed;
 42};
 43
 44struct compat_sigaltstack {
 45	compat_uptr_t ss_sp;
 46	int ss_flags;
 47	compat_size_t ss_size;
 48};
 49
 50struct compat_ucontext {
 51	compat_ulong_t	  uc_flags;
 52	compat_uptr_t     uc_link;
 53	struct compat_sigaltstack	  uc_stack;
 54	struct sigcontext uc_mcontext;
 55	sigset_t	  uc_sigmask;	/* mask last for extensibility */
 56};
 57
 58#define COMPAT_SI_PAD_SIZE	((SI_MAX_SIZE - 3 * sizeof(int)) / sizeof(int))
 59
 60struct compat_siginfo {
 61	int si_signo;
 62	int si_errno;
 63	int si_code;
 64
 65	union {
 66		int _pad[COMPAT_SI_PAD_SIZE];
 67
 68		/* kill() */
 69		struct {
 70			unsigned int _pid;	/* sender's pid */
 71			unsigned int _uid;	/* sender's uid */
 72		} _kill;
 73
 74		/* POSIX.1b timers */
 75		struct {
 76			compat_timer_t _tid;	/* timer id */
 77			int _overrun;		/* overrun count */
 78			compat_sigval_t _sigval;	/* same as below */
 79			int _sys_private;	/* not to be passed to user */
 80			int _overrun_incr;	/* amount to add to overrun */
 81		} _timer;
 82
 83		/* POSIX.1b signals */
 84		struct {
 85			unsigned int _pid;	/* sender's pid */
 86			unsigned int _uid;	/* sender's uid */
 87			compat_sigval_t _sigval;
 88		} _rt;
 89
 90		/* SIGCHLD */
 91		struct {
 92			unsigned int _pid;	/* which child */
 93			unsigned int _uid;	/* sender's uid */
 94			int _status;		/* exit code */
 95			compat_clock_t _utime;
 96			compat_clock_t _stime;
 97		} _sigchld;
 98
 99		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
100		struct {
101			unsigned int _addr;	/* faulting insn/memory ref. */
102#ifdef __ARCH_SI_TRAPNO
103			int _trapno;	/* TRAP # which caused the signal */
104#endif
105		} _sigfault;
106
107		/* SIGPOLL */
108		struct {
109			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
110			int _fd;
111		} _sigpoll;
112	} _sifields;
113};
114
115struct compat_rt_sigframe {
116	unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */
117	struct compat_siginfo info;
118	struct compat_ucontext uc;
119};
120
121long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
122			     struct compat_sigaction __user *oact,
123			     size_t sigsetsize)
124{
125	struct k_sigaction new_sa, old_sa;
126	int ret = -EINVAL;
127
128	/* XXX: Don't preclude handling different sized sigset_t's.  */
129	if (sigsetsize != sizeof(sigset_t))
130		goto out;
131
132	if (act) {
133		compat_uptr_t handler, restorer;
134
135		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
136		    __get_user(handler, &act->sa_handler) ||
137		    __get_user(new_sa.sa.sa_flags, &act->sa_flags) ||
138		    __get_user(restorer, &act->sa_restorer) ||
139		    __copy_from_user(&new_sa.sa.sa_mask, &act->sa_mask,
140				     sizeof(sigset_t)))
141			return -EFAULT;
142		new_sa.sa.sa_handler = compat_ptr(handler);
143		new_sa.sa.sa_restorer = compat_ptr(restorer);
144	}
145
146	ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
147
148	if (!ret && oact) {
149		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
150		    __put_user(ptr_to_compat(old_sa.sa.sa_handler),
151			       &oact->sa_handler) ||
152		    __put_user(ptr_to_compat(old_sa.sa.sa_restorer),
153			       &oact->sa_restorer) ||
154		    __put_user(old_sa.sa.sa_flags, &oact->sa_flags) ||
155		    __copy_to_user(&oact->sa_mask, &old_sa.sa.sa_mask,
156				   sizeof(sigset_t)))
157			return -EFAULT;
158	}
159out:
160	return ret;
161}
162
163long compat_sys_rt_sigqueueinfo(int pid, int sig,
164				struct compat_siginfo __user *uinfo)
165{
166	siginfo_t info;
167	int ret;
168	mm_segment_t old_fs = get_fs();
169
170	if (copy_siginfo_from_user32(&info, uinfo))
171		return -EFAULT;
172	set_fs(KERNEL_DS);
173	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __force __user *)&info);
174	set_fs(old_fs);
175	return ret;
176}
177
178int copy_siginfo_to_user32(struct compat_siginfo __user *to, siginfo_t *from)
179{
180	int err;
181
182	if (!access_ok(VERIFY_WRITE, to, sizeof(struct compat_siginfo)))
183		return -EFAULT;
184
185	/* If you change siginfo_t structure, please make sure that
186	   this code is fixed accordingly.
187	   It should never copy any pad contained in the structure
188	   to avoid security leaks, but must copy the generic
189	   3 ints plus the relevant union member.  */
190	err = __put_user(from->si_signo, &to->si_signo);
191	err |= __put_user(from->si_errno, &to->si_errno);
192	err |= __put_user((short)from->si_code, &to->si_code);
193
194	if (from->si_code < 0) {
195		err |= __put_user(from->si_pid, &to->si_pid);
196		err |= __put_user(from->si_uid, &to->si_uid);
197		err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
198	} else {
199		/*
200		 * First 32bits of unions are always present:
201		 * si_pid === si_band === si_tid === si_addr(LS half)
202		 */
203		err |= __put_user(from->_sifields._pad[0],
204				  &to->_sifields._pad[0]);
205		switch (from->si_code >> 16) {
206		case __SI_FAULT >> 16:
207			break;
208		case __SI_CHLD >> 16:
209			err |= __put_user(from->si_utime, &to->si_utime);
210			err |= __put_user(from->si_stime, &to->si_stime);
211			err |= __put_user(from->si_status, &to->si_status);
212			/* FALL THROUGH */
213		default:
214		case __SI_KILL >> 16:
215			err |= __put_user(from->si_uid, &to->si_uid);
216			break;
217		case __SI_POLL >> 16:
218			err |= __put_user(from->si_fd, &to->si_fd);
219			break;
220		case __SI_TIMER >> 16:
221			err |= __put_user(from->si_overrun, &to->si_overrun);
222			err |= __put_user(ptr_to_compat(from->si_ptr),
223					  &to->si_ptr);
224			break;
225			 /* This is not generated by the kernel as of now.  */
226		case __SI_RT >> 16:
227		case __SI_MESGQ >> 16:
228			err |= __put_user(from->si_uid, &to->si_uid);
229			err |= __put_user(from->si_int, &to->si_int);
230			break;
231		}
232	}
233	return err;
234}
235
236int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
237{
238	int err;
239	u32 ptr32;
240
241	if (!access_ok(VERIFY_READ, from, sizeof(struct compat_siginfo)))
242		return -EFAULT;
243
244	err = __get_user(to->si_signo, &from->si_signo);
245	err |= __get_user(to->si_errno, &from->si_errno);
246	err |= __get_user(to->si_code, &from->si_code);
247
248	err |= __get_user(to->si_pid, &from->si_pid);
249	err |= __get_user(to->si_uid, &from->si_uid);
250	err |= __get_user(ptr32, &from->si_ptr);
251	to->si_ptr = compat_ptr(ptr32);
252
253	return err;
254}
255
256long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
257			    struct compat_sigaltstack __user *uoss_ptr,
258			    struct pt_regs *regs)
259{
260	stack_t uss, uoss;
261	int ret;
262	mm_segment_t seg;
263
264	if (uss_ptr) {
265		u32 ptr;
266
267		memset(&uss, 0, sizeof(stack_t));
268		if (!access_ok(VERIFY_READ, uss_ptr, sizeof(*uss_ptr)) ||
269			    __get_user(ptr, &uss_ptr->ss_sp) ||
270			    __get_user(uss.ss_flags, &uss_ptr->ss_flags) ||
271			    __get_user(uss.ss_size, &uss_ptr->ss_size))
272			return -EFAULT;
273		uss.ss_sp = compat_ptr(ptr);
274	}
275	seg = get_fs();
276	set_fs(KERNEL_DS);
277	ret = do_sigaltstack(uss_ptr ? (stack_t __user __force *)&uss : NULL,
278			     (stack_t __user __force *)&uoss,
279			     (unsigned long)compat_ptr(regs->sp));
280	set_fs(seg);
281	if (ret >= 0 && uoss_ptr)  {
282		if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(*uoss_ptr)) ||
283		    __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) ||
284		    __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
285		    __put_user(uoss.ss_size, &uoss_ptr->ss_size))
286			ret = -EFAULT;
287	}
288	return ret;
289}
290
291/* The assembly shim for this function arranges to ignore the return value. */
292long compat_sys_rt_sigreturn(struct pt_regs *regs)
293{
294	struct compat_rt_sigframe __user *frame =
295		(struct compat_rt_sigframe __user *) compat_ptr(regs->sp);
296	sigset_t set;
297
298	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
299		goto badframe;
300	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
301		goto badframe;
302
303	set_current_blocked(&set);
304
305	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
306		goto badframe;
307
308	if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0)
309		goto badframe;
310
311	return 0;
312
313badframe:
314	signal_fault("bad sigreturn frame", regs, frame, 0);
315	return 0;
316}
317
318/*
319 * Determine which stack to use..
320 */
321static inline void __user *compat_get_sigframe(struct k_sigaction *ka,
322					       struct pt_regs *regs,
323					       size_t frame_size)
324{
325	unsigned long sp;
326
327	/* Default to using normal stack */
328	sp = (unsigned long)compat_ptr(regs->sp);
329
330	/*
331	 * If we are on the alternate signal stack and would overflow
332	 * it, don't.  Return an always-bogus address instead so we
333	 * will die with SIGSEGV.
334	 */
335	if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
336		return (void __user __force *)-1UL;
337
338	/* This is the X/Open sanctioned signal stack switching.  */
339	if (ka->sa.sa_flags & SA_ONSTACK) {
340		if (sas_ss_flags(sp) == 0)
341			sp = current->sas_ss_sp + current->sas_ss_size;
342	}
343
344	sp -= frame_size;
345	/*
346	 * Align the stack pointer according to the TILE ABI,
347	 * i.e. so that on function entry (sp & 15) == 0.
348	 */
349	sp &= -16UL;
350	return (void __user *) sp;
351}
352
353int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
354			  sigset_t *set, struct pt_regs *regs)
355{
356	unsigned long restorer;
357	struct compat_rt_sigframe __user *frame;
358	int err = 0;
359	int usig;
360
361	frame = compat_get_sigframe(ka, regs, sizeof(*frame));
362
363	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
364		goto give_sigsegv;
365
366	usig = current_thread_info()->exec_domain
367		&& current_thread_info()->exec_domain->signal_invmap
368		&& sig < 32
369		? current_thread_info()->exec_domain->signal_invmap[sig]
370		: sig;
371
372	/* Always write at least the signal number for the stack backtracer. */
373	if (ka->sa.sa_flags & SA_SIGINFO) {
374		/* At sigreturn time, restore the callee-save registers too. */
375		err |= copy_siginfo_to_user32(&frame->info, info);
376		regs->flags |= PT_FLAGS_RESTORE_REGS;
377	} else {
378		err |= __put_user(info->si_signo, &frame->info.si_signo);
379	}
380
381	/* Create the ucontext.  */
382	err |= __clear_user(&frame->save_area, sizeof(frame->save_area));
383	err |= __put_user(0, &frame->uc.uc_flags);
384	err |= __put_user(0, &frame->uc.uc_link);
385	err |= __put_user(ptr_to_compat((void *)(current->sas_ss_sp)),
386			  &frame->uc.uc_stack.ss_sp);
387	err |= __put_user(sas_ss_flags(regs->sp),
388			  &frame->uc.uc_stack.ss_flags);
389	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
390	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
391	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
392	if (err)
393		goto give_sigsegv;
394
395	restorer = VDSO_BASE;
396	if (ka->sa.sa_flags & SA_RESTORER)
397		restorer = ptr_to_compat_reg(ka->sa.sa_restorer);
398
399	/*
400	 * Set up registers for signal handler.
401	 * Registers that we don't modify keep the value they had from
402	 * user-space at the time we took the signal.
403	 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
404	 * since some things rely on this (e.g. glibc's debug/segfault.c).
405	 */
406	regs->pc = ptr_to_compat_reg(ka->sa.sa_handler);
407	regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
408	regs->sp = ptr_to_compat_reg(frame);
409	regs->lr = restorer;
410	regs->regs[0] = (unsigned long) usig;
411	regs->regs[1] = ptr_to_compat_reg(&frame->info);
412	regs->regs[2] = ptr_to_compat_reg(&frame->uc);
413	regs->flags |= PT_FLAGS_CALLER_SAVES;
414
415	/*
416	 * Notify any tracer that was single-stepping it.
417	 * The tracer may want to single-step inside the
418	 * handler too.
419	 */
420	if (test_thread_flag(TIF_SINGLESTEP))
421		ptrace_notify(SIGTRAP);
422
423	return 0;
424
425give_sigsegv:
426	signal_fault("bad setup frame", regs, frame, sig);
427	return -EFAULT;
428}