Linux Audio

Check our new training course

Loading...
v4.6
 
 1#include <linux/compat.h>
 2#include <linux/uaccess.h>
 
 3
 4int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
 
 
 
 
 
 
 
 
 
 
 
 
 5{
 6	int err = 0;
 7	bool ia32 = test_thread_flag(TIF_IA32);
 8
 9	if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
10		return -EFAULT;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
12	put_user_try {
13		/* If you change siginfo_t structure, please make sure that
14		   this code is fixed accordingly.
15		   It should never copy any pad contained in the structure
16		   to avoid security leaks, but must copy the generic
17		   3 ints plus the relevant union member.  */
18		put_user_ex(from->si_signo, &to->si_signo);
19		put_user_ex(from->si_errno, &to->si_errno);
20		put_user_ex((short)from->si_code, &to->si_code);
21
22		if (from->si_code < 0) {
23			put_user_ex(from->si_pid, &to->si_pid);
24			put_user_ex(from->si_uid, &to->si_uid);
25			put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
26		} else {
27			/*
28			 * First 32bits of unions are always present:
29			 * si_pid === si_band === si_tid === si_addr(LS half)
30			 */
31			put_user_ex(from->_sifields._pad[0],
32					  &to->_sifields._pad[0]);
33			switch (from->si_code >> 16) {
34			case __SI_FAULT >> 16:
35				break;
36			case __SI_SYS >> 16:
37				put_user_ex(from->si_syscall, &to->si_syscall);
38				put_user_ex(from->si_arch, &to->si_arch);
39				break;
40			case __SI_CHLD >> 16:
41				if (ia32) {
42					put_user_ex(from->si_utime, &to->si_utime);
43					put_user_ex(from->si_stime, &to->si_stime);
44				} else {
45					put_user_ex(from->si_utime, &to->_sifields._sigchld_x32._utime);
46					put_user_ex(from->si_stime, &to->_sifields._sigchld_x32._stime);
47				}
48				put_user_ex(from->si_status, &to->si_status);
49				/* FALL THROUGH */
50			default:
51			case __SI_KILL >> 16:
52				put_user_ex(from->si_uid, &to->si_uid);
53				break;
54			case __SI_POLL >> 16:
55				put_user_ex(from->si_fd, &to->si_fd);
56				break;
57			case __SI_TIMER >> 16:
58				put_user_ex(from->si_overrun, &to->si_overrun);
59				put_user_ex(ptr_to_compat(from->si_ptr),
60					    &to->si_ptr);
61				break;
62				 /* This is not generated by the kernel as of now.  */
63			case __SI_RT >> 16:
64			case __SI_MESGQ >> 16:
65				put_user_ex(from->si_uid, &to->si_uid);
66				put_user_ex(from->si_int, &to->si_int);
67				break;
68			}
69		}
70	} put_user_catch(err);
71
72	return err;
73}
74
75int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
76{
77	int err = 0;
78	u32 ptr32;
79
80	if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
81		return -EFAULT;
82
83	get_user_try {
84		get_user_ex(to->si_signo, &from->si_signo);
85		get_user_ex(to->si_errno, &from->si_errno);
86		get_user_ex(to->si_code, &from->si_code);
87
88		get_user_ex(to->si_pid, &from->si_pid);
89		get_user_ex(to->si_uid, &from->si_uid);
90		get_user_ex(ptr32, &from->si_ptr);
91		to->si_ptr = compat_ptr(ptr32);
92	} get_user_catch(err);
93
94	return err;
 
 
 
95}
v5.14.15
  1// SPDX-License-Identifier: GPL-2.0
  2#include <linux/compat.h>
  3#include <linux/uaccess.h>
  4#include <linux/ptrace.h>
  5
  6/*
  7 * The compat_siginfo_t structure and handing code is very easy
  8 * to break in several ways.  It must always be updated when new
  9 * updates are made to the main siginfo_t, and
 10 * copy_siginfo_to_user32() must be updated when the
 11 * (arch-independent) copy_siginfo_to_user() is updated.
 12 *
 13 * It is also easy to put a new member in the compat_siginfo_t
 14 * which has implicit alignment which can move internal structure
 15 * alignment around breaking the ABI.  This can happen if you,
 16 * for instance, put a plain 64-bit value in there.
 17 */
 18static inline void signal_compat_build_tests(void)
 19{
 20	int _sifields_offset = offsetof(compat_siginfo_t, _sifields);
 
 21
 22	/*
 23	 * If adding a new si_code, there is probably new data in
 24	 * the siginfo.  Make sure folks bumping the si_code
 25	 * limits also have to look at this code.  Make sure any
 26	 * new fields are handled in copy_siginfo_to_user32()!
 27	 */
 28	BUILD_BUG_ON(NSIGILL  != 11);
 29	BUILD_BUG_ON(NSIGFPE  != 15);
 30	BUILD_BUG_ON(NSIGSEGV != 9);
 31	BUILD_BUG_ON(NSIGBUS  != 5);
 32	BUILD_BUG_ON(NSIGTRAP != 6);
 33	BUILD_BUG_ON(NSIGCHLD != 6);
 34	BUILD_BUG_ON(NSIGSYS  != 2);
 35
 36	/* This is part of the ABI and can never change in size: */
 37	BUILD_BUG_ON(sizeof(compat_siginfo_t) != 128);
 38	/*
 39	 * The offsets of all the (unioned) si_fields are fixed
 40	 * in the ABI, of course.  Make sure none of them ever
 41	 * move and are always at the beginning:
 42	 */
 43	BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields) != 3 * sizeof(int));
 44#define CHECK_CSI_OFFSET(name)	  BUILD_BUG_ON(_sifields_offset != offsetof(compat_siginfo_t, _sifields.name))
 45
 46	BUILD_BUG_ON(offsetof(siginfo_t, si_signo) != 0);
 47	BUILD_BUG_ON(offsetof(siginfo_t, si_errno) != 4);
 48	BUILD_BUG_ON(offsetof(siginfo_t, si_code)  != 8);
 49
 50	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_signo) != 0);
 51	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_errno) != 4);
 52	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_code)  != 8);
 53	 /*
 54	 * Ensure that the size of each si_field never changes.
 55	 * If it does, it is a sign that the
 56	 * copy_siginfo_to_user32() code below needs to updated
 57	 * along with the size in the CHECK_SI_SIZE().
 58	 *
 59	 * We repeat this check for both the generic and compat
 60	 * siginfos.
 61	 *
 62	 * Note: it is OK for these to grow as long as the whole
 63	 * structure stays within the padding size (checked
 64	 * above).
 65	 */
 66#define CHECK_CSI_SIZE(name, size) BUILD_BUG_ON(size != sizeof(((compat_siginfo_t *)0)->_sifields.name))
 67#define CHECK_SI_SIZE(name, size) BUILD_BUG_ON(size != sizeof(((siginfo_t *)0)->_sifields.name))
 68
 69	CHECK_CSI_OFFSET(_kill);
 70	CHECK_CSI_SIZE  (_kill, 2*sizeof(int));
 71	CHECK_SI_SIZE   (_kill, 2*sizeof(int));
 72
 73	BUILD_BUG_ON(offsetof(siginfo_t, si_pid) != 0x10);
 74	BUILD_BUG_ON(offsetof(siginfo_t, si_uid) != 0x14);
 75	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid) != 0xC);
 76	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid) != 0x10);
 77
 78	CHECK_CSI_OFFSET(_timer);
 79	CHECK_CSI_SIZE  (_timer, 3*sizeof(int));
 80	CHECK_SI_SIZE   (_timer, 6*sizeof(int));
 81
 82	BUILD_BUG_ON(offsetof(siginfo_t, si_tid)     != 0x10);
 83	BUILD_BUG_ON(offsetof(siginfo_t, si_overrun) != 0x14);
 84	BUILD_BUG_ON(offsetof(siginfo_t, si_value)   != 0x18);
 85	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_tid)     != 0x0C);
 86	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_overrun) != 0x10);
 87	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_value)   != 0x14);
 88
 89	CHECK_CSI_OFFSET(_rt);
 90	CHECK_CSI_SIZE  (_rt, 3*sizeof(int));
 91	CHECK_SI_SIZE   (_rt, 4*sizeof(int));
 92
 93	BUILD_BUG_ON(offsetof(siginfo_t, si_pid)   != 0x10);
 94	BUILD_BUG_ON(offsetof(siginfo_t, si_uid)   != 0x14);
 95	BUILD_BUG_ON(offsetof(siginfo_t, si_value) != 0x18);
 96	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid)   != 0x0C);
 97	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid)   != 0x10);
 98	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_value) != 0x14);
 99
100	CHECK_CSI_OFFSET(_sigchld);
101	CHECK_CSI_SIZE  (_sigchld, 5*sizeof(int));
102	CHECK_SI_SIZE   (_sigchld, 8*sizeof(int));
103
104	BUILD_BUG_ON(offsetof(siginfo_t, si_pid)    != 0x10);
105	BUILD_BUG_ON(offsetof(siginfo_t, si_uid)    != 0x14);
106	BUILD_BUG_ON(offsetof(siginfo_t, si_status) != 0x18);
107	BUILD_BUG_ON(offsetof(siginfo_t, si_utime)  != 0x20);
108	BUILD_BUG_ON(offsetof(siginfo_t, si_stime)  != 0x28);
109	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pid)    != 0x0C);
110	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_uid)    != 0x10);
111	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_status) != 0x14);
112	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_utime)  != 0x18);
113	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_stime)  != 0x1C);
114
115#ifdef CONFIG_X86_X32_ABI
116	CHECK_CSI_OFFSET(_sigchld_x32);
117	CHECK_CSI_SIZE  (_sigchld_x32, 7*sizeof(int));
118	/* no _sigchld_x32 in the generic siginfo_t */
119	BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields._sigchld_x32._utime)  != 0x18);
120	BUILD_BUG_ON(offsetof(compat_siginfo_t, _sifields._sigchld_x32._stime)  != 0x20);
121#endif
122
123	CHECK_CSI_OFFSET(_sigfault);
124	CHECK_CSI_SIZE  (_sigfault, 4*sizeof(int));
125	CHECK_SI_SIZE   (_sigfault, 8*sizeof(int));
126
127	BUILD_BUG_ON(offsetof(siginfo_t, si_addr) != 0x10);
128	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr) != 0x0C);
129
130	BUILD_BUG_ON(offsetof(siginfo_t, si_trapno) != 0x18);
131	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_trapno) != 0x10);
132
133	BUILD_BUG_ON(offsetof(siginfo_t, si_addr_lsb) != 0x18);
134	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr_lsb) != 0x10);
135
136	BUILD_BUG_ON(offsetof(siginfo_t, si_lower) != 0x20);
137	BUILD_BUG_ON(offsetof(siginfo_t, si_upper) != 0x28);
138	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_lower) != 0x14);
139	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_upper) != 0x18);
140
141	BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x20);
142	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pkey) != 0x14);
143
144	BUILD_BUG_ON(offsetof(siginfo_t, si_perf_data) != 0x18);
145	BUILD_BUG_ON(offsetof(siginfo_t, si_perf_type) != 0x20);
146	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_data) != 0x10);
147	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_type) != 0x14);
148
149	CHECK_CSI_OFFSET(_sigpoll);
150	CHECK_CSI_SIZE  (_sigpoll, 2*sizeof(int));
151	CHECK_SI_SIZE   (_sigpoll, 4*sizeof(int));
152
153	BUILD_BUG_ON(offsetof(siginfo_t, si_band)   != 0x10);
154	BUILD_BUG_ON(offsetof(siginfo_t, si_fd)     != 0x18);
155	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_band) != 0x0C);
156	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_fd)   != 0x10);
157
158	CHECK_CSI_OFFSET(_sigsys);
159	CHECK_CSI_SIZE  (_sigsys, 3*sizeof(int));
160	CHECK_SI_SIZE   (_sigsys, 4*sizeof(int));
161
162	BUILD_BUG_ON(offsetof(siginfo_t, si_call_addr) != 0x10);
163	BUILD_BUG_ON(offsetof(siginfo_t, si_syscall)   != 0x18);
164	BUILD_BUG_ON(offsetof(siginfo_t, si_arch)      != 0x1C);
165	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_call_addr) != 0x0C);
166	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_syscall)   != 0x10);
167	BUILD_BUG_ON(offsetof(compat_siginfo_t, si_arch)      != 0x14);
168
169	/* any new si_fields should be added here */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170}
171
172void sigaction_compat_abi(struct k_sigaction *act, struct k_sigaction *oact)
173{
174	signal_compat_build_tests();
 
 
 
 
175
176	if (!act)
177		return;
 
 
 
 
 
 
 
 
178
179	if (in_ia32_syscall())
180		act->sa.sa_flags |= SA_IA32_ABI;
181	if (in_x32_syscall())
182		act->sa.sa_flags |= SA_X32_ABI;
183}