]> git.ipfire.org Git - thirdparty/kernel/linux.git/blame - arch/x86/kernel/signal_compat.c
License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[thirdparty/kernel/linux.git] / arch / x86 / kernel / signal_compat.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
c0bfd26e
BG
2#include <linux/compat.h>
3#include <linux/uaccess.h>
68463510 4#include <linux/ptrace.h>
c0bfd26e 5
02e8fda2
DH
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 != 8);
29 BUILD_BUG_ON(NSIGFPE != 8);
30 BUILD_BUG_ON(NSIGSEGV != 4);
31 BUILD_BUG_ON(NSIGBUS != 5);
32 BUILD_BUG_ON(NSIGTRAP != 4);
33 BUILD_BUG_ON(NSIGCHLD != 6);
34 BUILD_BUG_ON(NSIGSYS != 1);
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 /*
47 * Ensure that the size of each si_field never changes.
48 * If it does, it is a sign that the
49 * copy_siginfo_to_user32() code below needs to updated
50 * along with the size in the CHECK_SI_SIZE().
51 *
52 * We repeat this check for both the generic and compat
53 * siginfos.
54 *
55 * Note: it is OK for these to grow as long as the whole
56 * structure stays within the padding size (checked
57 * above).
58 */
59#define CHECK_CSI_SIZE(name, size) BUILD_BUG_ON(size != sizeof(((compat_siginfo_t *)0)->_sifields.name))
60#define CHECK_SI_SIZE(name, size) BUILD_BUG_ON(size != sizeof(((siginfo_t *)0)->_sifields.name))
61
62 CHECK_CSI_OFFSET(_kill);
63 CHECK_CSI_SIZE (_kill, 2*sizeof(int));
64 CHECK_SI_SIZE (_kill, 2*sizeof(int));
65
66 CHECK_CSI_OFFSET(_timer);
67 CHECK_CSI_SIZE (_timer, 5*sizeof(int));
68 CHECK_SI_SIZE (_timer, 6*sizeof(int));
69
70 CHECK_CSI_OFFSET(_rt);
71 CHECK_CSI_SIZE (_rt, 3*sizeof(int));
72 CHECK_SI_SIZE (_rt, 4*sizeof(int));
73
74 CHECK_CSI_OFFSET(_sigchld);
75 CHECK_CSI_SIZE (_sigchld, 5*sizeof(int));
76 CHECK_SI_SIZE (_sigchld, 8*sizeof(int));
77
78 CHECK_CSI_OFFSET(_sigchld_x32);
79 CHECK_CSI_SIZE (_sigchld_x32, 7*sizeof(int));
80 /* no _sigchld_x32 in the generic siginfo_t */
81
82 CHECK_CSI_OFFSET(_sigfault);
83 CHECK_CSI_SIZE (_sigfault, 4*sizeof(int));
84 CHECK_SI_SIZE (_sigfault, 8*sizeof(int));
85
86 CHECK_CSI_OFFSET(_sigpoll);
87 CHECK_CSI_SIZE (_sigpoll, 2*sizeof(int));
88 CHECK_SI_SIZE (_sigpoll, 4*sizeof(int));
89
90 CHECK_CSI_OFFSET(_sigsys);
91 CHECK_CSI_SIZE (_sigsys, 3*sizeof(int));
92 CHECK_SI_SIZE (_sigsys, 4*sizeof(int));
93
94 /* any new si_fields should be added here */
95}
96
68463510
DS
97void sigaction_compat_abi(struct k_sigaction *act, struct k_sigaction *oact)
98{
99 /* Don't leak in-kernel non-uapi flags to user-space */
100 if (oact)
101 oact->sa.sa_flags &= ~(SA_IA32_ABI | SA_X32_ABI);
102
103 if (!act)
104 return;
105
106 /* Don't let flags to be set from userspace */
107 act->sa.sa_flags &= ~(SA_IA32_ABI | SA_X32_ABI);
108
68463510
DS
109 if (in_ia32_syscall())
110 act->sa.sa_flags |= SA_IA32_ABI;
111 if (in_x32_syscall())
112 act->sa.sa_flags |= SA_X32_ABI;
113}
114
115int __copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from,
116 bool x32_ABI)
c0bfd26e
BG
117{
118 int err = 0;
c0bfd26e 119
02e8fda2
DH
120 signal_compat_build_tests();
121
c0bfd26e
BG
122 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
123 return -EFAULT;
124
125 put_user_try {
126 /* If you change siginfo_t structure, please make sure that
127 this code is fixed accordingly.
128 It should never copy any pad contained in the structure
129 to avoid security leaks, but must copy the generic
130 3 ints plus the relevant union member. */
131 put_user_ex(from->si_signo, &to->si_signo);
132 put_user_ex(from->si_errno, &to->si_errno);
cc731525 133 put_user_ex(from->si_code, &to->si_code);
c0bfd26e
BG
134
135 if (from->si_code < 0) {
136 put_user_ex(from->si_pid, &to->si_pid);
137 put_user_ex(from->si_uid, &to->si_uid);
138 put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
139 } else {
140 /*
141 * First 32bits of unions are always present:
142 * si_pid === si_band === si_tid === si_addr(LS half)
143 */
144 put_user_ex(from->_sifields._pad[0],
145 &to->_sifields._pad[0]);
cc731525
EB
146 switch (siginfo_layout(from->si_signo, from->si_code)) {
147 case SIL_FAULT:
a4455082
DH
148 if (from->si_signo == SIGBUS &&
149 (from->si_code == BUS_MCEERR_AR ||
150 from->si_code == BUS_MCEERR_AO))
151 put_user_ex(from->si_addr_lsb, &to->si_addr_lsb);
152
153 if (from->si_signo == SIGSEGV) {
154 if (from->si_code == SEGV_BNDERR) {
cfac6dfa
JR
155 compat_uptr_t lower = (unsigned long)from->si_lower;
156 compat_uptr_t upper = (unsigned long)from->si_upper;
a4455082
DH
157 put_user_ex(lower, &to->si_lower);
158 put_user_ex(upper, &to->si_upper);
159 }
160 if (from->si_code == SEGV_PKUERR)
161 put_user_ex(from->si_pkey, &to->si_pkey);
162 }
c0bfd26e 163 break;
cc731525 164 case SIL_SYS:
c0bfd26e
BG
165 put_user_ex(from->si_syscall, &to->si_syscall);
166 put_user_ex(from->si_arch, &to->si_arch);
167 break;
cc731525 168 case SIL_CHLD:
68463510 169 if (!x32_ABI) {
c0bfd26e
BG
170 put_user_ex(from->si_utime, &to->si_utime);
171 put_user_ex(from->si_stime, &to->si_stime);
172 } else {
173 put_user_ex(from->si_utime, &to->_sifields._sigchld_x32._utime);
174 put_user_ex(from->si_stime, &to->_sifields._sigchld_x32._stime);
175 }
176 put_user_ex(from->si_status, &to->si_status);
177 /* FALL THROUGH */
cc731525 178 case SIL_KILL:
c0bfd26e
BG
179 put_user_ex(from->si_uid, &to->si_uid);
180 break;
cc731525 181 case SIL_POLL:
c0bfd26e
BG
182 put_user_ex(from->si_fd, &to->si_fd);
183 break;
cc731525 184 case SIL_TIMER:
c0bfd26e
BG
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;
cc731525 189 case SIL_RT:
c0bfd26e
BG
190 put_user_ex(from->si_uid, &to->si_uid);
191 put_user_ex(from->si_int, &to->si_int);
192 break;
193 }
194 }
195 } put_user_catch(err);
196
197 return err;
198}
199
68463510
DS
200/* from syscall's path, where we know the ABI */
201int copy_siginfo_to_user32(compat_siginfo_t __user *to, const siginfo_t *from)
202{
203 return __copy_siginfo_to_user32(to, from, in_x32_syscall());
204}
205
c0bfd26e
BG
206int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
207{
208 int err = 0;
209 u32 ptr32;
210
211 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
212 return -EFAULT;
213
214 get_user_try {
215 get_user_ex(to->si_signo, &from->si_signo);
216 get_user_ex(to->si_errno, &from->si_errno);
217 get_user_ex(to->si_code, &from->si_code);
218
219 get_user_ex(to->si_pid, &from->si_pid);
220 get_user_ex(to->si_uid, &from->si_uid);
221 get_user_ex(ptr32, &from->si_ptr);
222 to->si_ptr = compat_ptr(ptr32);
223 } get_user_catch(err);
224
225 return err;
226}