Loading...
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 != 7);
31 BUILD_BUG_ON(NSIGBUS != 5);
32 BUILD_BUG_ON(NSIGTRAP != 5);
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 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_addr_lsb) != 0x18);
131 BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr_lsb) != 0x10);
132
133 BUILD_BUG_ON(offsetof(siginfo_t, si_lower) != 0x20);
134 BUILD_BUG_ON(offsetof(siginfo_t, si_upper) != 0x28);
135 BUILD_BUG_ON(offsetof(compat_siginfo_t, si_lower) != 0x14);
136 BUILD_BUG_ON(offsetof(compat_siginfo_t, si_upper) != 0x18);
137
138 BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x20);
139 BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pkey) != 0x14);
140
141 CHECK_CSI_OFFSET(_sigpoll);
142 CHECK_CSI_SIZE (_sigpoll, 2*sizeof(int));
143 CHECK_SI_SIZE (_sigpoll, 4*sizeof(int));
144
145 BUILD_BUG_ON(offsetof(siginfo_t, si_band) != 0x10);
146 BUILD_BUG_ON(offsetof(siginfo_t, si_fd) != 0x18);
147 BUILD_BUG_ON(offsetof(compat_siginfo_t, si_band) != 0x0C);
148 BUILD_BUG_ON(offsetof(compat_siginfo_t, si_fd) != 0x10);
149
150 CHECK_CSI_OFFSET(_sigsys);
151 CHECK_CSI_SIZE (_sigsys, 3*sizeof(int));
152 CHECK_SI_SIZE (_sigsys, 4*sizeof(int));
153
154 BUILD_BUG_ON(offsetof(siginfo_t, si_call_addr) != 0x10);
155 BUILD_BUG_ON(offsetof(siginfo_t, si_syscall) != 0x18);
156 BUILD_BUG_ON(offsetof(siginfo_t, si_arch) != 0x1C);
157 BUILD_BUG_ON(offsetof(compat_siginfo_t, si_call_addr) != 0x0C);
158 BUILD_BUG_ON(offsetof(compat_siginfo_t, si_syscall) != 0x10);
159 BUILD_BUG_ON(offsetof(compat_siginfo_t, si_arch) != 0x14);
160
161 /* any new si_fields should be added here */
162}
163
164void sigaction_compat_abi(struct k_sigaction *act, struct k_sigaction *oact)
165{
166 signal_compat_build_tests();
167
168 /* Don't leak in-kernel non-uapi flags to user-space */
169 if (oact)
170 oact->sa.sa_flags &= ~(SA_IA32_ABI | SA_X32_ABI);
171
172 if (!act)
173 return;
174
175 /* Don't let flags to be set from userspace */
176 act->sa.sa_flags &= ~(SA_IA32_ABI | SA_X32_ABI);
177
178 if (in_ia32_syscall())
179 act->sa.sa_flags |= SA_IA32_ABI;
180 if (in_x32_syscall())
181 act->sa.sa_flags |= SA_X32_ABI;
182}
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}