Commit | Line | Data |
---|---|---|
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 | */ | |
18 | static 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 | */ | |
ac54058d | 28 | BUILD_BUG_ON(NSIGILL != 11); |
75abf642 | 29 | BUILD_BUG_ON(NSIGFPE != 15); |
74f10824 | 30 | BUILD_BUG_ON(NSIGSEGV != 9); |
02e8fda2 | 31 | BUILD_BUG_ON(NSIGBUS != 5); |
fb6cc127 | 32 | BUILD_BUG_ON(NSIGTRAP != 6); |
02e8fda2 | 33 | BUILD_BUG_ON(NSIGCHLD != 6); |
1d7637d8 | 34 | BUILD_BUG_ON(NSIGSYS != 2); |
02e8fda2 DH |
35 | |
36 | /* This is part of the ABI and can never change in size: */ | |
50ae8130 | 37 | BUILD_BUG_ON(sizeof(siginfo_t) != 128); |
02e8fda2 | 38 | BUILD_BUG_ON(sizeof(compat_siginfo_t) != 128); |
50ae8130 EB |
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 | ||
02e8fda2 DH |
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 | ||
f6a01549 EB |
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); | |
02e8fda2 DH |
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 | ||
f6a01549 EB |
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 | ||
02e8fda2 | 84 | CHECK_CSI_OFFSET(_timer); |
2f82a46f | 85 | CHECK_CSI_SIZE (_timer, 3*sizeof(int)); |
02e8fda2 DH |
86 | CHECK_SI_SIZE (_timer, 6*sizeof(int)); |
87 | ||
f6a01549 EB |
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 | ||
02e8fda2 DH |
95 | CHECK_CSI_OFFSET(_rt); |
96 | CHECK_CSI_SIZE (_rt, 3*sizeof(int)); | |
97 | CHECK_SI_SIZE (_rt, 4*sizeof(int)); | |
98 | ||
f6a01549 EB |
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 | ||
02e8fda2 DH |
106 | CHECK_CSI_OFFSET(_sigchld); |
107 | CHECK_CSI_SIZE (_sigchld, 5*sizeof(int)); | |
108 | CHECK_SI_SIZE (_sigchld, 8*sizeof(int)); | |
109 | ||
f6a01549 EB |
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 | ||
b713da69 | 121 | #ifdef CONFIG_X86_X32_ABI |
02e8fda2 DH |
122 | CHECK_CSI_OFFSET(_sigchld_x32); |
123 | CHECK_CSI_SIZE (_sigchld_x32, 7*sizeof(int)); | |
124 | /* no _sigchld_x32 in the generic siginfo_t */ | |
f6a01549 EB |
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); | |
b713da69 | 127 | #endif |
02e8fda2 DH |
128 | |
129 | CHECK_CSI_OFFSET(_sigfault); | |
130 | CHECK_CSI_SIZE (_sigfault, 4*sizeof(int)); | |
131 | CHECK_SI_SIZE (_sigfault, 8*sizeof(int)); | |
132 | ||
f6a01549 EB |
133 | BUILD_BUG_ON(offsetof(siginfo_t, si_addr) != 0x10); |
134 | BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr) != 0x0C); | |
135 | ||
add0b32e EB |
136 | BUILD_BUG_ON(offsetof(siginfo_t, si_trapno) != 0x18); |
137 | BUILD_BUG_ON(offsetof(compat_siginfo_t, si_trapno) != 0x10); | |
138 | ||
f6a01549 EB |
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 | ||
0683b531 EB |
150 | BUILD_BUG_ON(offsetof(siginfo_t, si_perf_data) != 0x18); |
151 | BUILD_BUG_ON(offsetof(siginfo_t, si_perf_type) != 0x20); | |
78ed93d7 | 152 | BUILD_BUG_ON(offsetof(siginfo_t, si_perf_flags) != 0x24); |
0683b531 EB |
153 | BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_data) != 0x10); |
154 | BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_type) != 0x14); | |
78ed93d7 | 155 | BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_flags) != 0x18); |
fb6cc127 | 156 | |
02e8fda2 DH |
157 | CHECK_CSI_OFFSET(_sigpoll); |
158 | CHECK_CSI_SIZE (_sigpoll, 2*sizeof(int)); | |
159 | CHECK_SI_SIZE (_sigpoll, 4*sizeof(int)); | |
160 | ||
f6a01549 EB |
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 | ||
02e8fda2 DH |
166 | CHECK_CSI_OFFSET(_sigsys); |
167 | CHECK_CSI_SIZE (_sigsys, 3*sizeof(int)); | |
168 | CHECK_SI_SIZE (_sigsys, 4*sizeof(int)); | |
169 | ||
f6a01549 EB |
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 | ||
02e8fda2 DH |
177 | /* any new si_fields should be added here */ |
178 | } | |
179 | ||
68463510 DS |
180 | void sigaction_compat_abi(struct k_sigaction *act, struct k_sigaction *oact) |
181 | { | |
ea64d5ac EB |
182 | signal_compat_build_tests(); |
183 | ||
68463510 DS |
184 | if (!act) |
185 | return; | |
186 | ||
68463510 DS |
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 | } |