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