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