Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/parisc/kernel/signal32.c
10817 views
1
/* Signal support for 32-bit kernel builds
2
*
3
* Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
4
* Copyright (C) 2006 Kyle McMartin <kyle at parisc-linux.org>
5
*
6
* Code was mostly borrowed from kernel/signal.c.
7
* See kernel/signal.c for additional Copyrights.
8
*
9
*
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
14
*
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
19
*
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
*/
24
25
#include <linux/compat.h>
26
#include <linux/module.h>
27
#include <linux/unistd.h>
28
#include <linux/init.h>
29
#include <linux/sched.h>
30
#include <linux/syscalls.h>
31
#include <linux/types.h>
32
#include <linux/errno.h>
33
34
#include <asm/uaccess.h>
35
36
#include "signal32.h"
37
#include "sys32.h"
38
39
#define DEBUG_COMPAT_SIG 0
40
#define DEBUG_COMPAT_SIG_LEVEL 2
41
42
#if DEBUG_COMPAT_SIG
43
#define DBG(LEVEL, ...) \
44
((DEBUG_COMPAT_SIG_LEVEL >= LEVEL) \
45
? printk(__VA_ARGS__) : (void) 0)
46
#else
47
#define DBG(LEVEL, ...)
48
#endif
49
50
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
51
52
inline void
53
sigset_32to64(sigset_t *s64, compat_sigset_t *s32)
54
{
55
s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32);
56
}
57
58
inline void
59
sigset_64to32(compat_sigset_t *s32, sigset_t *s64)
60
{
61
s32->sig[0] = s64->sig[0] & 0xffffffffUL;
62
s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
63
}
64
65
static int
66
put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
67
{
68
compat_sigset_t s;
69
70
if (sz != sizeof *set) panic("put_sigset32()");
71
sigset_64to32(&s, set);
72
73
return copy_to_user(up, &s, sizeof s);
74
}
75
76
static int
77
get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
78
{
79
compat_sigset_t s;
80
int r;
81
82
if (sz != sizeof *set) panic("put_sigset32()");
83
84
if ((r = copy_from_user(&s, up, sz)) == 0) {
85
sigset_32to64(set, &s);
86
}
87
88
return r;
89
}
90
91
int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, compat_sigset_t __user *oset,
92
unsigned int sigsetsize)
93
{
94
sigset_t old_set, new_set;
95
int ret;
96
97
if (set && get_sigset32(set, &new_set, sigsetsize))
98
return -EFAULT;
99
100
KERNEL_SYSCALL(ret, sys_rt_sigprocmask, how, set ? (sigset_t __user *)&new_set : NULL,
101
oset ? (sigset_t __user *)&old_set : NULL, sigsetsize);
102
103
if (!ret && oset && put_sigset32(oset, &old_set, sigsetsize))
104
return -EFAULT;
105
106
return ret;
107
}
108
109
110
int sys32_rt_sigpending(compat_sigset_t __user *uset, unsigned int sigsetsize)
111
{
112
int ret;
113
sigset_t set;
114
115
KERNEL_SYSCALL(ret, sys_rt_sigpending, (sigset_t __user *)&set, sigsetsize);
116
117
if (!ret && put_sigset32(uset, &set, sigsetsize))
118
return -EFAULT;
119
120
return ret;
121
}
122
123
long
124
sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, struct sigaction32 __user *oact,
125
size_t sigsetsize)
126
{
127
struct k_sigaction32 new_sa32, old_sa32;
128
struct k_sigaction new_sa, old_sa;
129
int ret = -EINVAL;
130
131
if (act) {
132
if (copy_from_user(&new_sa32.sa, act, sizeof new_sa32.sa))
133
return -EFAULT;
134
new_sa.sa.sa_handler = (__sighandler_t)(unsigned long)new_sa32.sa.sa_handler;
135
new_sa.sa.sa_flags = new_sa32.sa.sa_flags;
136
sigset_32to64(&new_sa.sa.sa_mask, &new_sa32.sa.sa_mask);
137
}
138
139
ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
140
141
if (!ret && oact) {
142
sigset_64to32(&old_sa32.sa.sa_mask, &old_sa.sa.sa_mask);
143
old_sa32.sa.sa_flags = old_sa.sa.sa_flags;
144
old_sa32.sa.sa_handler = (__sighandler_t32)(unsigned long)old_sa.sa.sa_handler;
145
if (copy_to_user(oact, &old_sa32.sa, sizeof old_sa32.sa))
146
return -EFAULT;
147
}
148
return ret;
149
}
150
151
int
152
do_sigaltstack32 (const compat_stack_t __user *uss32, compat_stack_t __user *uoss32, unsigned long sp)
153
{
154
compat_stack_t ss32, oss32;
155
stack_t ss, oss;
156
stack_t *ssp = NULL, *ossp = NULL;
157
int ret;
158
159
if (uss32) {
160
if (copy_from_user(&ss32, uss32, sizeof ss32))
161
return -EFAULT;
162
163
ss.ss_sp = (void __user *)(unsigned long)ss32.ss_sp;
164
ss.ss_flags = ss32.ss_flags;
165
ss.ss_size = ss32.ss_size;
166
167
ssp = &ss;
168
}
169
170
if (uoss32)
171
ossp = &oss;
172
173
KERNEL_SYSCALL(ret, do_sigaltstack, (const stack_t __user *)ssp, (stack_t __user *)ossp, sp);
174
175
if (!ret && uoss32) {
176
oss32.ss_sp = (unsigned int)(unsigned long)oss.ss_sp;
177
oss32.ss_flags = oss.ss_flags;
178
oss32.ss_size = oss.ss_size;
179
if (copy_to_user(uoss32, &oss32, sizeof *uoss32))
180
return -EFAULT;
181
}
182
183
return ret;
184
}
185
186
long
187
restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
188
struct pt_regs *regs)
189
{
190
long err = 0;
191
compat_uint_t compat_reg;
192
compat_uint_t compat_regt;
193
int regn;
194
195
/* When loading 32-bit values into 64-bit registers make
196
sure to clear the upper 32-bits */
197
DBG(2,"restore_sigcontext32: PER_LINUX32 process\n");
198
DBG(2,"restore_sigcontext32: sc = 0x%p, rf = 0x%p, regs = 0x%p\n", sc, rf, regs);
199
DBG(2,"restore_sigcontext32: compat_sigcontext is %#lx bytes\n", sizeof(*sc));
200
for(regn=0; regn < 32; regn++){
201
err |= __get_user(compat_reg,&sc->sc_gr[regn]);
202
regs->gr[regn] = compat_reg;
203
/* Load upper half */
204
err |= __get_user(compat_regt,&rf->rf_gr[regn]);
205
regs->gr[regn] = ((u64)compat_regt << 32) | (u64)compat_reg;
206
DBG(3,"restore_sigcontext32: gr%02d = %#lx (%#x / %#x)\n",
207
regn, regs->gr[regn], compat_regt, compat_reg);
208
}
209
DBG(2,"restore_sigcontext32: sc->sc_fr = 0x%p (%#lx)\n",sc->sc_fr, sizeof(sc->sc_fr));
210
/* XXX: BE WARNED FR's are 64-BIT! */
211
err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
212
213
/* Better safe than sorry, pass __get_user two things of
214
the same size and let gcc do the upward conversion to
215
64-bits */
216
err |= __get_user(compat_reg, &sc->sc_iaoq[0]);
217
/* Load upper half */
218
err |= __get_user(compat_regt, &rf->rf_iaoq[0]);
219
regs->iaoq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
220
DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt);
221
DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n",
222
&sc->sc_iaoq[0], compat_reg);
223
224
err |= __get_user(compat_reg, &sc->sc_iaoq[1]);
225
/* Load upper half */
226
err |= __get_user(compat_regt, &rf->rf_iaoq[1]);
227
regs->iaoq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
228
DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt);
229
DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n",
230
&sc->sc_iaoq[1],compat_reg);
231
DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n",
232
regs->iaoq[0],regs->iaoq[1]);
233
234
err |= __get_user(compat_reg, &sc->sc_iasq[0]);
235
/* Load the upper half for iasq */
236
err |= __get_user(compat_regt, &rf->rf_iasq[0]);
237
regs->iasq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
238
DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt);
239
240
err |= __get_user(compat_reg, &sc->sc_iasq[1]);
241
/* Load the upper half for iasq */
242
err |= __get_user(compat_regt, &rf->rf_iasq[1]);
243
regs->iasq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
244
DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt);
245
DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n",
246
regs->iasq[0],regs->iasq[1]);
247
248
err |= __get_user(compat_reg, &sc->sc_sar);
249
/* Load the upper half for sar */
250
err |= __get_user(compat_regt, &rf->rf_sar);
251
regs->sar = ((u64)compat_regt << 32) | (u64)compat_reg;
252
DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);
253
DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);
254
DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);
255
256
return err;
257
}
258
259
/*
260
* Set up the sigcontext structure for this process.
261
* This is not an easy task if the kernel is 64-bit, it will require
262
* that we examine the process personality to determine if we need to
263
* truncate for a 32-bit userspace.
264
*/
265
long
266
setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
267
struct pt_regs *regs, int in_syscall)
268
{
269
compat_int_t flags = 0;
270
long err = 0;
271
compat_uint_t compat_reg;
272
compat_uint_t compat_regb;
273
int regn;
274
275
if (on_sig_stack((unsigned long) sc))
276
flags |= PARISC_SC_FLAG_ONSTACK;
277
278
if (in_syscall) {
279
280
DBG(1,"setup_sigcontext32: in_syscall\n");
281
282
flags |= PARISC_SC_FLAG_IN_SYSCALL;
283
/* Truncate gr31 */
284
compat_reg = (compat_uint_t)(regs->gr[31]);
285
/* regs->iaoq is undefined in the syscall return path */
286
err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
287
DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
288
&sc->sc_iaoq[0], compat_reg);
289
290
/* Store upper half */
291
compat_reg = (compat_uint_t)(regs->gr[31] >> 32);
292
err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
293
DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
294
295
296
compat_reg = (compat_uint_t)(regs->gr[31]+4);
297
err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
298
DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
299
&sc->sc_iaoq[1], compat_reg);
300
/* Store upper half */
301
compat_reg = (compat_uint_t)((regs->gr[31]+4) >> 32);
302
err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
303
DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
304
305
/* Truncate sr3 */
306
compat_reg = (compat_uint_t)(regs->sr[3]);
307
err |= __put_user(compat_reg, &sc->sc_iasq[0]);
308
err |= __put_user(compat_reg, &sc->sc_iasq[1]);
309
310
/* Store upper half */
311
compat_reg = (compat_uint_t)(regs->sr[3] >> 32);
312
err |= __put_user(compat_reg, &rf->rf_iasq[0]);
313
err |= __put_user(compat_reg, &rf->rf_iasq[1]);
314
315
DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
316
DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
317
DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",
318
regs->gr[31], regs->gr[31]+4);
319
320
} else {
321
322
compat_reg = (compat_uint_t)(regs->iaoq[0]);
323
err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
324
DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
325
&sc->sc_iaoq[0], compat_reg);
326
/* Store upper half */
327
compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);
328
err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
329
DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
330
331
compat_reg = (compat_uint_t)(regs->iaoq[1]);
332
err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
333
DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
334
&sc->sc_iaoq[1], compat_reg);
335
/* Store upper half */
336
compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);
337
err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
338
DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
339
340
341
compat_reg = (compat_uint_t)(regs->iasq[0]);
342
err |= __put_user(compat_reg, &sc->sc_iasq[0]);
343
DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
344
&sc->sc_iasq[0], compat_reg);
345
/* Store upper half */
346
compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);
347
err |= __put_user(compat_reg, &rf->rf_iasq[0]);
348
DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
349
350
351
compat_reg = (compat_uint_t)(regs->iasq[1]);
352
err |= __put_user(compat_reg, &sc->sc_iasq[1]);
353
DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
354
&sc->sc_iasq[1], compat_reg);
355
/* Store upper half */
356
compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);
357
err |= __put_user(compat_reg, &rf->rf_iasq[1]);
358
DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
359
360
/* Print out the IAOQ for debugging */
361
DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n",
362
regs->iaoq[0], regs->iaoq[1]);
363
}
364
365
err |= __put_user(flags, &sc->sc_flags);
366
367
DBG(1,"setup_sigcontext32: Truncating general registers.\n");
368
369
for(regn=0; regn < 32; regn++){
370
/* Truncate a general register */
371
compat_reg = (compat_uint_t)(regs->gr[regn]);
372
err |= __put_user(compat_reg, &sc->sc_gr[regn]);
373
/* Store upper half */
374
compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);
375
err |= __put_user(compat_regb, &rf->rf_gr[regn]);
376
377
/* DEBUG: Write out the "upper / lower" register data */
378
DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn,
379
compat_regb, compat_reg);
380
}
381
382
/* Copy the floating point registers (same size)
383
XXX: BE WARNED FR's are 64-BIT! */
384
DBG(1,"setup_sigcontext32: Copying from regs to sc, "
385
"sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
386
sizeof(regs->fr), sizeof(sc->sc_fr));
387
err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
388
389
compat_reg = (compat_uint_t)(regs->sar);
390
err |= __put_user(compat_reg, &sc->sc_sar);
391
DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);
392
/* Store upper half */
393
compat_reg = (compat_uint_t)(regs->sar >> 32);
394
err |= __put_user(compat_reg, &rf->rf_sar);
395
DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);
396
DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);
397
398
return err;
399
}
400
401
int
402
copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
403
{
404
compat_uptr_t addr;
405
int err;
406
407
if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
408
return -EFAULT;
409
410
err = __get_user(to->si_signo, &from->si_signo);
411
err |= __get_user(to->si_errno, &from->si_errno);
412
err |= __get_user(to->si_code, &from->si_code);
413
414
if (to->si_code < 0)
415
err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
416
else {
417
switch (to->si_code >> 16) {
418
case __SI_CHLD >> 16:
419
err |= __get_user(to->si_utime, &from->si_utime);
420
err |= __get_user(to->si_stime, &from->si_stime);
421
err |= __get_user(to->si_status, &from->si_status);
422
default:
423
err |= __get_user(to->si_pid, &from->si_pid);
424
err |= __get_user(to->si_uid, &from->si_uid);
425
break;
426
case __SI_FAULT >> 16:
427
err |= __get_user(addr, &from->si_addr);
428
to->si_addr = compat_ptr(addr);
429
break;
430
case __SI_POLL >> 16:
431
err |= __get_user(to->si_band, &from->si_band);
432
err |= __get_user(to->si_fd, &from->si_fd);
433
break;
434
case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
435
case __SI_MESGQ >> 16:
436
err |= __get_user(to->si_pid, &from->si_pid);
437
err |= __get_user(to->si_uid, &from->si_uid);
438
err |= __get_user(to->si_int, &from->si_int);
439
break;
440
}
441
}
442
return err;
443
}
444
445
int
446
copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
447
{
448
compat_uptr_t addr;
449
compat_int_t val;
450
int err;
451
452
if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
453
return -EFAULT;
454
455
/* If you change siginfo_t structure, please be sure
456
this code is fixed accordingly.
457
It should never copy any pad contained in the structure
458
to avoid security leaks, but must copy the generic
459
3 ints plus the relevant union member.
460
This routine must convert siginfo from 64bit to 32bit as well
461
at the same time. */
462
err = __put_user(from->si_signo, &to->si_signo);
463
err |= __put_user(from->si_errno, &to->si_errno);
464
err |= __put_user((short)from->si_code, &to->si_code);
465
if (from->si_code < 0)
466
err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
467
else {
468
switch (from->si_code >> 16) {
469
case __SI_CHLD >> 16:
470
err |= __put_user(from->si_utime, &to->si_utime);
471
err |= __put_user(from->si_stime, &to->si_stime);
472
err |= __put_user(from->si_status, &to->si_status);
473
default:
474
err |= __put_user(from->si_pid, &to->si_pid);
475
err |= __put_user(from->si_uid, &to->si_uid);
476
break;
477
case __SI_FAULT >> 16:
478
addr = ptr_to_compat(from->si_addr);
479
err |= __put_user(addr, &to->si_addr);
480
break;
481
case __SI_POLL >> 16:
482
err |= __put_user(from->si_band, &to->si_band);
483
err |= __put_user(from->si_fd, &to->si_fd);
484
break;
485
case __SI_TIMER >> 16:
486
err |= __put_user(from->si_tid, &to->si_tid);
487
err |= __put_user(from->si_overrun, &to->si_overrun);
488
val = (compat_int_t)from->si_int;
489
err |= __put_user(val, &to->si_int);
490
break;
491
case __SI_RT >> 16: /* Not generated by the kernel as of now. */
492
case __SI_MESGQ >> 16:
493
err |= __put_user(from->si_uid, &to->si_uid);
494
err |= __put_user(from->si_pid, &to->si_pid);
495
val = (compat_int_t)from->si_int;
496
err |= __put_user(val, &to->si_int);
497
break;
498
}
499
}
500
return err;
501
}
502
503
asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
504
struct compat_siginfo __user *uinfo)
505
{
506
siginfo_t info;
507
508
if (copy_siginfo_from_user32(&info, uinfo))
509
return -EFAULT;
510
511
/* Not even root can pretend to send signals from the kernel.
512
Nor can they impersonate a kill(), which adds source info. */
513
if (info.si_code >= 0)
514
return -EPERM;
515
info.si_signo = sig;
516
517
/* POSIX.1b doesn't mention process groups. */
518
return kill_proc_info(sig, &info, pid);
519
}
520
521
522