• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/arch/x86/ia32/
1/*
2 *  linux/arch/x86_64/ia32/ia32_signal.c
3 *
4 *  Copyright (C) 1991, 1992  Linus Torvalds
5 *
6 *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
7 *  2000-06-20  Pentium III FXSR, SSE support by Gareth Hughes
8 *  2000-12-*   x86-64 compatibility mode signal handling by Andi Kleen
9 */
10
11#include <linux/sched.h>
12#include <linux/mm.h>
13#include <linux/smp.h>
14#include <linux/kernel.h>
15#include <linux/signal.h>
16#include <linux/errno.h>
17#include <linux/wait.h>
18#include <linux/ptrace.h>
19#include <linux/unistd.h>
20#include <linux/stddef.h>
21#include <linux/personality.h>
22#include <linux/compat.h>
23#include <linux/binfmts.h>
24#include <asm/ucontext.h>
25#include <asm/uaccess.h>
26#include <asm/i387.h>
27#include <asm/ptrace.h>
28#include <asm/ia32_unistd.h>
29#include <asm/user32.h>
30#include <asm/sigcontext32.h>
31#include <asm/proto.h>
32#include <asm/vdso.h>
33#include <asm/sigframe.h>
34#include <asm/sys_ia32.h>
35
36#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
37
38#define FIX_EFLAGS	(X86_EFLAGS_AC | X86_EFLAGS_OF | \
39			 X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \
40			 X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \
41			 X86_EFLAGS_CF)
42
43void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
44
45int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
46{
47	int err = 0;
48
49	if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
50		return -EFAULT;
51
52	put_user_try {
53		/* If you change siginfo_t structure, please make sure that
54		   this code is fixed accordingly.
55		   It should never copy any pad contained in the structure
56		   to avoid security leaks, but must copy the generic
57		   3 ints plus the relevant union member.  */
58		put_user_ex(from->si_signo, &to->si_signo);
59		put_user_ex(from->si_errno, &to->si_errno);
60		put_user_ex((short)from->si_code, &to->si_code);
61
62		if (from->si_code < 0) {
63			put_user_ex(from->si_pid, &to->si_pid);
64			put_user_ex(from->si_uid, &to->si_uid);
65			put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
66		} else {
67			/*
68			 * First 32bits of unions are always present:
69			 * si_pid === si_band === si_tid === si_addr(LS half)
70			 */
71			put_user_ex(from->_sifields._pad[0],
72					  &to->_sifields._pad[0]);
73			switch (from->si_code >> 16) {
74			case __SI_FAULT >> 16:
75				break;
76			case __SI_CHLD >> 16:
77				put_user_ex(from->si_utime, &to->si_utime);
78				put_user_ex(from->si_stime, &to->si_stime);
79				put_user_ex(from->si_status, &to->si_status);
80				/* FALL THROUGH */
81			default:
82			case __SI_KILL >> 16:
83				put_user_ex(from->si_uid, &to->si_uid);
84				break;
85			case __SI_POLL >> 16:
86				put_user_ex(from->si_fd, &to->si_fd);
87				break;
88			case __SI_TIMER >> 16:
89				put_user_ex(from->si_overrun, &to->si_overrun);
90				put_user_ex(ptr_to_compat(from->si_ptr),
91					    &to->si_ptr);
92				break;
93				 /* This is not generated by the kernel as of now.  */
94			case __SI_RT >> 16:
95			case __SI_MESGQ >> 16:
96				put_user_ex(from->si_uid, &to->si_uid);
97				put_user_ex(from->si_int, &to->si_int);
98				break;
99			}
100		}
101	} put_user_catch(err);
102
103	return err;
104}
105
106int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
107{
108	int err = 0;
109	u32 ptr32;
110
111	if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
112		return -EFAULT;
113
114	get_user_try {
115		get_user_ex(to->si_signo, &from->si_signo);
116		get_user_ex(to->si_errno, &from->si_errno);
117		get_user_ex(to->si_code, &from->si_code);
118
119		get_user_ex(to->si_pid, &from->si_pid);
120		get_user_ex(to->si_uid, &from->si_uid);
121		get_user_ex(ptr32, &from->si_ptr);
122		to->si_ptr = compat_ptr(ptr32);
123	} get_user_catch(err);
124
125	return err;
126}
127
128asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
129{
130	mask &= _BLOCKABLE;
131	spin_lock_irq(&current->sighand->siglock);
132	current->saved_sigmask = current->blocked;
133	siginitset(&current->blocked, mask);
134	recalc_sigpending();
135	spin_unlock_irq(&current->sighand->siglock);
136
137	current->state = TASK_INTERRUPTIBLE;
138	schedule();
139	set_restore_sigmask();
140	return -ERESTARTNOHAND;
141}
142
143asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
144				  stack_ia32_t __user *uoss_ptr,
145				  struct pt_regs *regs)
146{
147	stack_t uss, uoss;
148	int ret, err = 0;
149	mm_segment_t seg;
150
151	if (uss_ptr) {
152		u32 ptr;
153
154		memset(&uss, 0, sizeof(stack_t));
155		if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)))
156			return -EFAULT;
157
158		get_user_try {
159			get_user_ex(ptr, &uss_ptr->ss_sp);
160			get_user_ex(uss.ss_flags, &uss_ptr->ss_flags);
161			get_user_ex(uss.ss_size, &uss_ptr->ss_size);
162		} get_user_catch(err);
163
164		if (err)
165			return -EFAULT;
166		uss.ss_sp = compat_ptr(ptr);
167	}
168	seg = get_fs();
169	set_fs(KERNEL_DS);
170	ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp);
171	set_fs(seg);
172	if (ret >= 0 && uoss_ptr)  {
173		if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)))
174			return -EFAULT;
175
176		put_user_try {
177			put_user_ex(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp);
178			put_user_ex(uoss.ss_flags, &uoss_ptr->ss_flags);
179			put_user_ex(uoss.ss_size, &uoss_ptr->ss_size);
180		} put_user_catch(err);
181
182		if (err)
183			ret = -EFAULT;
184	}
185	return ret;
186}
187
188/*
189 * Do a signal return; undo the signal stack.
190 */
191#define loadsegment_gs(v)	load_gs_index(v)
192#define loadsegment_fs(v)	loadsegment(fs, v)
193#define loadsegment_ds(v)	loadsegment(ds, v)
194#define loadsegment_es(v)	loadsegment(es, v)
195
196#define get_user_seg(seg)	({ unsigned int v; savesegment(seg, v); v; })
197#define set_user_seg(seg, v)	loadsegment_##seg(v)
198
199#define COPY(x)			{		\
200	get_user_ex(regs->x, &sc->x);		\
201}
202
203#define GET_SEG(seg)		({			\
204	unsigned short tmp;				\
205	get_user_ex(tmp, &sc->seg);			\
206	tmp;						\
207})
208
209#define COPY_SEG_CPL3(seg)	do {			\
210	regs->seg = GET_SEG(seg) | 3;			\
211} while (0)
212
213#define RELOAD_SEG(seg)		{		\
214	unsigned int pre = GET_SEG(seg);	\
215	unsigned int cur = get_user_seg(seg);	\
216	pre |= 3;				\
217	if (pre != cur)				\
218		set_user_seg(seg, pre);		\
219}
220
221static int ia32_restore_sigcontext(struct pt_regs *regs,
222				   struct sigcontext_ia32 __user *sc,
223				   unsigned int *pax)
224{
225	unsigned int tmpflags, err = 0;
226	void __user *buf;
227	u32 tmp;
228
229	/* Always make any pending restarted system calls return -EINTR */
230	current_thread_info()->restart_block.fn = do_no_restart_syscall;
231
232	get_user_try {
233		/*
234		 * Reload fs and gs if they have changed in the signal
235		 * handler.  This does not handle long fs/gs base changes in
236		 * the handler, but does not clobber them at least in the
237		 * normal case.
238		 */
239		RELOAD_SEG(gs);
240		RELOAD_SEG(fs);
241		RELOAD_SEG(ds);
242		RELOAD_SEG(es);
243
244		COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
245		COPY(dx); COPY(cx); COPY(ip);
246		/* Don't touch extended registers */
247
248		COPY_SEG_CPL3(cs);
249		COPY_SEG_CPL3(ss);
250
251		get_user_ex(tmpflags, &sc->flags);
252		regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
253		/* disable syscall checks */
254		regs->orig_ax = -1;
255
256		get_user_ex(tmp, &sc->fpstate);
257		buf = compat_ptr(tmp);
258		err |= restore_i387_xstate_ia32(buf);
259
260		get_user_ex(*pax, &sc->ax);
261	} get_user_catch(err);
262
263	return err;
264}
265
266asmlinkage long sys32_sigreturn(struct pt_regs *regs)
267{
268	struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
269	sigset_t set;
270	unsigned int ax;
271
272	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
273		goto badframe;
274	if (__get_user(set.sig[0], &frame->sc.oldmask)
275	    || (_COMPAT_NSIG_WORDS > 1
276		&& __copy_from_user((((char *) &set.sig) + 4),
277				    &frame->extramask,
278				    sizeof(frame->extramask))))
279		goto badframe;
280
281	sigdelsetmask(&set, ~_BLOCKABLE);
282	spin_lock_irq(&current->sighand->siglock);
283	current->blocked = set;
284	recalc_sigpending();
285	spin_unlock_irq(&current->sighand->siglock);
286
287	if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
288		goto badframe;
289	return ax;
290
291badframe:
292	signal_fault(regs, frame, "32bit sigreturn");
293	return 0;
294}
295
296asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
297{
298	struct rt_sigframe_ia32 __user *frame;
299	sigset_t set;
300	unsigned int ax;
301	struct pt_regs tregs;
302
303	frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
304
305	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
306		goto badframe;
307	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
308		goto badframe;
309
310	sigdelsetmask(&set, ~_BLOCKABLE);
311	spin_lock_irq(&current->sighand->siglock);
312	current->blocked = set;
313	recalc_sigpending();
314	spin_unlock_irq(&current->sighand->siglock);
315
316	if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
317		goto badframe;
318
319	tregs = *regs;
320	if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
321		goto badframe;
322
323	return ax;
324
325badframe:
326	signal_fault(regs, frame, "32bit rt sigreturn");
327	return 0;
328}
329
330/*
331 * Set up a signal frame.
332 */
333
334static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
335				 void __user *fpstate,
336				 struct pt_regs *regs, unsigned int mask)
337{
338	int err = 0;
339
340	put_user_try {
341		put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
342		put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
343		put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
344		put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
345
346		put_user_ex(regs->di, &sc->di);
347		put_user_ex(regs->si, &sc->si);
348		put_user_ex(regs->bp, &sc->bp);
349		put_user_ex(regs->sp, &sc->sp);
350		put_user_ex(regs->bx, &sc->bx);
351		put_user_ex(regs->dx, &sc->dx);
352		put_user_ex(regs->cx, &sc->cx);
353		put_user_ex(regs->ax, &sc->ax);
354		put_user_ex(current->thread.trap_no, &sc->trapno);
355		put_user_ex(current->thread.error_code, &sc->err);
356		put_user_ex(regs->ip, &sc->ip);
357		put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
358		put_user_ex(regs->flags, &sc->flags);
359		put_user_ex(regs->sp, &sc->sp_at_signal);
360		put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
361
362		put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
363
364		/* non-iBCS2 extensions.. */
365		put_user_ex(mask, &sc->oldmask);
366		put_user_ex(current->thread.cr2, &sc->cr2);
367	} put_user_catch(err);
368
369	return err;
370}
371
372/*
373 * Determine which stack to use..
374 */
375static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
376				 size_t frame_size,
377				 void **fpstate)
378{
379	unsigned long sp;
380
381	/* Default to using normal stack */
382	sp = regs->sp;
383
384	/* This is the X/Open sanctioned signal stack switching.  */
385	if (ka->sa.sa_flags & SA_ONSTACK) {
386		if (sas_ss_flags(sp) == 0)
387			sp = current->sas_ss_sp + current->sas_ss_size;
388	}
389
390	/* This is the legacy signal stack switching. */
391	else if ((regs->ss & 0xffff) != __USER32_DS &&
392		!(ka->sa.sa_flags & SA_RESTORER) &&
393		 ka->sa.sa_restorer)
394		sp = (unsigned long) ka->sa.sa_restorer;
395
396	if (used_math()) {
397		sp = sp - sig_xstate_ia32_size;
398		*fpstate = (struct _fpstate_ia32 *) sp;
399		if (save_i387_xstate_ia32(*fpstate) < 0)
400			return (void __user *) -1L;
401	}
402
403	sp -= frame_size;
404	/* Align the stack pointer according to the i386 ABI,
405	 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
406	sp = ((sp + 4) & -16ul) - 4;
407	return (void __user *) sp;
408}
409
410int ia32_setup_frame(int sig, struct k_sigaction *ka,
411		     compat_sigset_t *set, struct pt_regs *regs)
412{
413	struct sigframe_ia32 __user *frame;
414	void __user *restorer;
415	int err = 0;
416	void __user *fpstate = NULL;
417
418	/* copy_to_user optimizes that into a single 8 byte store */
419	static const struct {
420		u16 poplmovl;
421		u32 val;
422		u16 int80;
423	} __attribute__((packed)) code = {
424		0xb858,		 /* popl %eax ; movl $...,%eax */
425		__NR_ia32_sigreturn,
426		0x80cd,		/* int $0x80 */
427	};
428
429	frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
430
431	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
432		return -EFAULT;
433
434	if (__put_user(sig, &frame->sig))
435		return -EFAULT;
436
437	if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
438		return -EFAULT;
439
440	if (_COMPAT_NSIG_WORDS > 1) {
441		if (__copy_to_user(frame->extramask, &set->sig[1],
442				   sizeof(frame->extramask)))
443			return -EFAULT;
444	}
445
446	if (ka->sa.sa_flags & SA_RESTORER) {
447		restorer = ka->sa.sa_restorer;
448	} else {
449		/* Return stub is in 32bit vsyscall page */
450		if (current->mm->context.vdso)
451			restorer = VDSO32_SYMBOL(current->mm->context.vdso,
452						 sigreturn);
453		else
454			restorer = &frame->retcode;
455	}
456
457	put_user_try {
458		put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
459
460		/*
461		 * These are actually not used anymore, but left because some
462		 * gdb versions depend on them as a marker.
463		 */
464		put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
465	} put_user_catch(err);
466
467	if (err)
468		return -EFAULT;
469
470	/* Set up registers for signal handler */
471	regs->sp = (unsigned long) frame;
472	regs->ip = (unsigned long) ka->sa.sa_handler;
473
474	/* Make -mregparm=3 work */
475	regs->ax = sig;
476	regs->dx = 0;
477	regs->cx = 0;
478
479	loadsegment(ds, __USER32_DS);
480	loadsegment(es, __USER32_DS);
481
482	regs->cs = __USER32_CS;
483	regs->ss = __USER32_DS;
484
485	return 0;
486}
487
488int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
489			compat_sigset_t *set, struct pt_regs *regs)
490{
491	struct rt_sigframe_ia32 __user *frame;
492	void __user *restorer;
493	int err = 0;
494	void __user *fpstate = NULL;
495
496	/* __copy_to_user optimizes that into a single 8 byte store */
497	static const struct {
498		u8 movl;
499		u32 val;
500		u16 int80;
501		u8  pad;
502	} __attribute__((packed)) code = {
503		0xb8,
504		__NR_ia32_rt_sigreturn,
505		0x80cd,
506		0,
507	};
508
509	frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
510
511	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
512		return -EFAULT;
513
514	put_user_try {
515		put_user_ex(sig, &frame->sig);
516		put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
517		put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
518		err |= copy_siginfo_to_user32(&frame->info, info);
519
520		/* Create the ucontext.  */
521		if (cpu_has_xsave)
522			put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
523		else
524			put_user_ex(0, &frame->uc.uc_flags);
525		put_user_ex(0, &frame->uc.uc_link);
526		put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
527		put_user_ex(sas_ss_flags(regs->sp),
528			    &frame->uc.uc_stack.ss_flags);
529		put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
530		err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
531					     regs, set->sig[0]);
532		err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
533
534		if (ka->sa.sa_flags & SA_RESTORER)
535			restorer = ka->sa.sa_restorer;
536		else
537			restorer = VDSO32_SYMBOL(current->mm->context.vdso,
538						 rt_sigreturn);
539		put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
540
541		/*
542		 * Not actually used anymore, but left because some gdb
543		 * versions need it.
544		 */
545		put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
546	} put_user_catch(err);
547
548	if (err)
549		return -EFAULT;
550
551	/* Set up registers for signal handler */
552	regs->sp = (unsigned long) frame;
553	regs->ip = (unsigned long) ka->sa.sa_handler;
554
555	/* Make -mregparm=3 work */
556	regs->ax = sig;
557	regs->dx = (unsigned long) &frame->info;
558	regs->cx = (unsigned long) &frame->uc;
559
560	loadsegment(ds, __USER32_DS);
561	loadsegment(es, __USER32_DS);
562
563	regs->cs = __USER32_CS;
564	regs->ss = __USER32_DS;
565
566	return 0;
567}
568