Linux Audio

Check our new training course

Loading...
v5.9
 1/*
 2 * This file is subject to the terms and conditions of the GNU General Public
 3 * License.  See the file "COPYING" in the main directory of this archive
 4 * for more details.
 5 *
 6 * Copyright (C) 1991, 1992  Linus Torvalds
 7 * Copyright (C) 1994 - 2000, 2006  Ralf Baechle
 8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
 9 * Copyright (C) 2016, Imagination Technologies Ltd.
10 */
11#include <linux/compat.h>
12#include <linux/compiler.h>
13#include <linux/errno.h>
14#include <linux/kernel.h>
15#include <linux/signal.h>
16#include <linux/syscalls.h>
17
 
18#include <asm/compat-signal.h>
19#include <linux/uaccess.h>
20#include <asm/unistd.h>
21
22#include "signal-common.h"
23
24/* 32-bit compatibility types */
25
26typedef unsigned int __sighandler32_t;
27typedef void (*vfptr_t)(void);
28
29/*
30 * Atomically swap in the new signal mask, and wait for a signal.
31 */
32
33asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
34{
35	return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
36}
37
38SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act,
39	struct compat_sigaction __user *, oact)
40{
41	struct k_sigaction new_ka, old_ka;
42	int ret;
43	int err = 0;
44
45	if (act) {
46		old_sigset_t mask;
47		s32 handler;
48
49		if (!access_ok(act, sizeof(*act)))
50			return -EFAULT;
51		err |= __get_user(handler, &act->sa_handler);
52		new_ka.sa.sa_handler = (void __user *)(s64)handler;
53		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
54		err |= __get_user(mask, &act->sa_mask.sig[0]);
55		if (err)
56			return -EFAULT;
57
58		siginitset(&new_ka.sa.sa_mask, mask);
59	}
60
61	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
62
63	if (!ret && oact) {
64		if (!access_ok(oact, sizeof(*oact)))
65			return -EFAULT;
66		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
67		err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
68				  &oact->sa_handler);
69		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
70		err |= __put_user(0, &oact->sa_mask.sig[1]);
71		err |= __put_user(0, &oact->sa_mask.sig[2]);
72		err |= __put_user(0, &oact->sa_mask.sig[3]);
73		if (err)
74			return -EFAULT;
75	}
76
77	return ret;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78}
v4.10.11
  1/*
  2 * This file is subject to the terms and conditions of the GNU General Public
  3 * License.  See the file "COPYING" in the main directory of this archive
  4 * for more details.
  5 *
  6 * Copyright (C) 1991, 1992  Linus Torvalds
  7 * Copyright (C) 1994 - 2000, 2006  Ralf Baechle
  8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  9 * Copyright (C) 2016, Imagination Technologies Ltd.
 10 */
 
 11#include <linux/compiler.h>
 12#include <linux/errno.h>
 13#include <linux/kernel.h>
 14#include <linux/signal.h>
 15#include <linux/syscalls.h>
 16
 17#include <asm/compat.h>
 18#include <asm/compat-signal.h>
 19#include <linux/uaccess.h>
 20#include <asm/unistd.h>
 21
 22#include "signal-common.h"
 23
 24/* 32-bit compatibility types */
 25
 26typedef unsigned int __sighandler32_t;
 27typedef void (*vfptr_t)(void);
 28
 29/*
 30 * Atomically swap in the new signal mask, and wait for a signal.
 31 */
 32
 33asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
 34{
 35	return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
 36}
 37
 38SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act,
 39	struct compat_sigaction __user *, oact)
 40{
 41	struct k_sigaction new_ka, old_ka;
 42	int ret;
 43	int err = 0;
 44
 45	if (act) {
 46		old_sigset_t mask;
 47		s32 handler;
 48
 49		if (!access_ok(VERIFY_READ, act, sizeof(*act)))
 50			return -EFAULT;
 51		err |= __get_user(handler, &act->sa_handler);
 52		new_ka.sa.sa_handler = (void __user *)(s64)handler;
 53		err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
 54		err |= __get_user(mask, &act->sa_mask.sig[0]);
 55		if (err)
 56			return -EFAULT;
 57
 58		siginitset(&new_ka.sa.sa_mask, mask);
 59	}
 60
 61	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 62
 63	if (!ret && oact) {
 64		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
 65			return -EFAULT;
 66		err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 67		err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
 68				  &oact->sa_handler);
 69		err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
 70		err |= __put_user(0, &oact->sa_mask.sig[1]);
 71		err |= __put_user(0, &oact->sa_mask.sig[2]);
 72		err |= __put_user(0, &oact->sa_mask.sig[3]);
 73		if (err)
 74			return -EFAULT;
 75	}
 76
 77	return ret;
 78}
 79
 80int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
 81{
 82	int err;
 83
 84	if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
 85		return -EFAULT;
 86
 87	/* If you change siginfo_t structure, please be sure
 88	   this code is fixed accordingly.
 89	   It should never copy any pad contained in the structure
 90	   to avoid security leaks, but must copy the generic
 91	   3 ints plus the relevant union member.
 92	   This routine must convert siginfo from 64bit to 32bit as well
 93	   at the same time.  */
 94	err = __put_user(from->si_signo, &to->si_signo);
 95	err |= __put_user(from->si_errno, &to->si_errno);
 96	err |= __put_user((short)from->si_code, &to->si_code);
 97	if (from->si_code < 0)
 98		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
 99	else {
100		switch (from->si_code >> 16) {
101		case __SI_TIMER >> 16:
102			err |= __put_user(from->si_tid, &to->si_tid);
103			err |= __put_user(from->si_overrun, &to->si_overrun);
104			err |= __put_user(from->si_int, &to->si_int);
105			break;
106		case __SI_CHLD >> 16:
107			err |= __put_user(from->si_utime, &to->si_utime);
108			err |= __put_user(from->si_stime, &to->si_stime);
109			err |= __put_user(from->si_status, &to->si_status);
110		default:
111			err |= __put_user(from->si_pid, &to->si_pid);
112			err |= __put_user(from->si_uid, &to->si_uid);
113			break;
114		case __SI_FAULT >> 16:
115			err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
116			break;
117		case __SI_POLL >> 16:
118			err |= __put_user(from->si_band, &to->si_band);
119			err |= __put_user(from->si_fd, &to->si_fd);
120			break;
121		case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
122		case __SI_MESGQ >> 16:
123			err |= __put_user(from->si_pid, &to->si_pid);
124			err |= __put_user(from->si_uid, &to->si_uid);
125			err |= __put_user(from->si_int, &to->si_int);
126			break;
127		case __SI_SYS >> 16:
128			err |= __copy_to_user(&to->si_call_addr, &from->si_call_addr,
129					      sizeof(compat_uptr_t));
130			err |= __put_user(from->si_syscall, &to->si_syscall);
131			err |= __put_user(from->si_arch, &to->si_arch);
132			break;
133		}
134	}
135	return err;
136}
137
138int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
139{
140	if (copy_from_user(to, from, 3*sizeof(int)) ||
141	    copy_from_user(to->_sifields._pad,
142			   from->_sifields._pad, SI_PAD_SIZE32))
143		return -EFAULT;
144
145	return 0;
146}