Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/x86/ia32/ia32_signal.c
10817 views
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
43
void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
44
45
int 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
106
int 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
128
asmlinkage 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
143
asmlinkage 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
221
static 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
266
asmlinkage 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
291
badframe:
292
signal_fault(regs, frame, "32bit sigreturn");
293
return 0;
294
}
295
296
asmlinkage 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
325
badframe:
326
signal_fault(regs, frame, "32bit rt sigreturn");
327
return 0;
328
}
329
330
/*
331
* Set up a signal frame.
332
*/
333
334
static 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
*/
375
static 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
410
int 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
488
int 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
569