xref: /openbmc/linux/arch/parisc/kernel/signal32.c (revision e00a844a)
1 /*    Signal support for 32-bit kernel builds
2  *
3  *    Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
4  *    Copyright (C) 2006 Kyle McMartin <kyle at parisc-linux.org>
5  *
6  *    Code was mostly borrowed from kernel/signal.c.
7  *    See kernel/signal.c for additional Copyrights.
8  *
9  *
10  *    This program is free software; you can redistribute it and/or modify
11  *    it under the terms of the GNU General Public License as published by
12  *    the Free Software Foundation; either version 2 of the License, or
13  *    (at your option) any later version.
14  *
15  *    This program is distributed in the hope that it will be useful,
16  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *    GNU General Public License for more details.
19  *
20  *    You should have received a copy of the GNU General Public License
21  *    along with this program; if not, write to the Free Software
22  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  */
24 
25 #include <linux/compat.h>
26 #include <linux/module.h>
27 #include <linux/unistd.h>
28 #include <linux/init.h>
29 #include <linux/sched.h>
30 #include <linux/syscalls.h>
31 #include <linux/types.h>
32 #include <linux/errno.h>
33 
34 #include <linux/uaccess.h>
35 
36 #include "signal32.h"
37 
38 #define DEBUG_COMPAT_SIG 0
39 #define DEBUG_COMPAT_SIG_LEVEL 2
40 
41 #if DEBUG_COMPAT_SIG
42 #define DBG(LEVEL, ...) \
43 	((DEBUG_COMPAT_SIG_LEVEL >= LEVEL) \
44 	? printk(__VA_ARGS__) : (void) 0)
45 #else
46 #define DBG(LEVEL, ...)
47 #endif
48 
49 long
50 restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
51 		struct pt_regs *regs)
52 {
53 	long err = 0;
54 	compat_uint_t compat_reg;
55 	compat_uint_t compat_regt;
56 	int regn;
57 
58 	/* When loading 32-bit values into 64-bit registers make
59 	   sure to clear the upper 32-bits */
60 	DBG(2,"restore_sigcontext32: PER_LINUX32 process\n");
61 	DBG(2,"restore_sigcontext32: sc = 0x%p, rf = 0x%p, regs = 0x%p\n", sc, rf, regs);
62 	DBG(2,"restore_sigcontext32: compat_sigcontext is %#lx bytes\n", sizeof(*sc));
63 	for(regn=0; regn < 32; regn++){
64 		err |= __get_user(compat_reg,&sc->sc_gr[regn]);
65 		regs->gr[regn] = compat_reg;
66 		/* Load upper half */
67 		err |= __get_user(compat_regt,&rf->rf_gr[regn]);
68 		regs->gr[regn] = ((u64)compat_regt << 32) | (u64)compat_reg;
69 		DBG(3,"restore_sigcontext32: gr%02d = %#lx (%#x / %#x)\n",
70 				regn, regs->gr[regn], compat_regt, compat_reg);
71 	}
72 	DBG(2,"restore_sigcontext32: sc->sc_fr = 0x%p (%#lx)\n",sc->sc_fr, sizeof(sc->sc_fr));
73 	/* XXX: BE WARNED FR's are 64-BIT! */
74 	err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
75 
76 	/* Better safe than sorry, pass __get_user two things of
77 	   the same size and let gcc do the upward conversion to
78 	   64-bits */
79 	err |= __get_user(compat_reg, &sc->sc_iaoq[0]);
80 	/* Load upper half */
81 	err |= __get_user(compat_regt, &rf->rf_iaoq[0]);
82 	regs->iaoq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
83 	DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt);
84 	DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n",
85 			&sc->sc_iaoq[0], compat_reg);
86 
87 	err |= __get_user(compat_reg, &sc->sc_iaoq[1]);
88 	/* Load upper half */
89 	err |= __get_user(compat_regt, &rf->rf_iaoq[1]);
90 	regs->iaoq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
91 	DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt);
92 	DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n",
93 			&sc->sc_iaoq[1],compat_reg);
94 	DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n",
95 			regs->iaoq[0],regs->iaoq[1]);
96 
97 	err |= __get_user(compat_reg, &sc->sc_iasq[0]);
98 	/* Load the upper half for iasq */
99 	err |= __get_user(compat_regt, &rf->rf_iasq[0]);
100 	regs->iasq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
101 	DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt);
102 
103 	err |= __get_user(compat_reg, &sc->sc_iasq[1]);
104 	/* Load the upper half for iasq */
105 	err |= __get_user(compat_regt, &rf->rf_iasq[1]);
106 	regs->iasq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
107 	DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt);
108 	DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n",
109 		regs->iasq[0],regs->iasq[1]);
110 
111 	err |= __get_user(compat_reg, &sc->sc_sar);
112 	/* Load the upper half for sar */
113 	err |= __get_user(compat_regt, &rf->rf_sar);
114 	regs->sar = ((u64)compat_regt << 32) | (u64)compat_reg;
115 	DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);
116 	DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);
117 	DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);
118 
119 	return err;
120 }
121 
122 /*
123  * Set up the sigcontext structure for this process.
124  * This is not an easy task if the kernel is 64-bit, it will require
125  * that we examine the process personality to determine if we need to
126  * truncate for a 32-bit userspace.
127  */
128 long
129 setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
130 		struct pt_regs *regs, int in_syscall)
131 {
132 	compat_int_t flags = 0;
133 	long err = 0;
134 	compat_uint_t compat_reg;
135 	compat_uint_t compat_regb;
136 	int regn;
137 
138 	if (on_sig_stack((unsigned long) sc))
139 		flags |= PARISC_SC_FLAG_ONSTACK;
140 
141 	if (in_syscall) {
142 
143 		DBG(1,"setup_sigcontext32: in_syscall\n");
144 
145 		flags |= PARISC_SC_FLAG_IN_SYSCALL;
146 		/* Truncate gr31 */
147 		compat_reg = (compat_uint_t)(regs->gr[31]);
148 		/* regs->iaoq is undefined in the syscall return path */
149 		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
150 		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
151 				&sc->sc_iaoq[0], compat_reg);
152 
153 		/* Store upper half */
154 		compat_reg = (compat_uint_t)(regs->gr[31] >> 32);
155 		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
156 		DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
157 
158 
159 		compat_reg = (compat_uint_t)(regs->gr[31]+4);
160 		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
161 		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
162 				&sc->sc_iaoq[1], compat_reg);
163 		/* Store upper half */
164 		compat_reg = (compat_uint_t)((regs->gr[31]+4) >> 32);
165 		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
166 		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
167 
168 		/* Truncate sr3 */
169 		compat_reg = (compat_uint_t)(regs->sr[3]);
170 		err |= __put_user(compat_reg, &sc->sc_iasq[0]);
171 		err |= __put_user(compat_reg, &sc->sc_iasq[1]);
172 
173 		/* Store upper half */
174 		compat_reg = (compat_uint_t)(regs->sr[3] >> 32);
175 		err |= __put_user(compat_reg, &rf->rf_iasq[0]);
176 		err |= __put_user(compat_reg, &rf->rf_iasq[1]);
177 
178 		DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
179 		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
180 		DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",
181 			regs->gr[31], regs->gr[31]+4);
182 
183 	} else {
184 
185 		compat_reg = (compat_uint_t)(regs->iaoq[0]);
186 		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
187 		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
188 				&sc->sc_iaoq[0], compat_reg);
189 		/* Store upper half */
190 		compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);
191 		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
192 		DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
193 
194 		compat_reg = (compat_uint_t)(regs->iaoq[1]);
195 		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
196 		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
197 				&sc->sc_iaoq[1], compat_reg);
198 		/* Store upper half */
199 		compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);
200 		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
201 		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
202 
203 
204 		compat_reg = (compat_uint_t)(regs->iasq[0]);
205 		err |= __put_user(compat_reg, &sc->sc_iasq[0]);
206 		DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
207 				&sc->sc_iasq[0], compat_reg);
208 		/* Store upper half */
209 		compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);
210 		err |= __put_user(compat_reg, &rf->rf_iasq[0]);
211 		DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
212 
213 
214 		compat_reg = (compat_uint_t)(regs->iasq[1]);
215 		err |= __put_user(compat_reg, &sc->sc_iasq[1]);
216 		DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
217 				&sc->sc_iasq[1], compat_reg);
218 		/* Store upper half */
219 		compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);
220 		err |= __put_user(compat_reg, &rf->rf_iasq[1]);
221 		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
222 
223 		/* Print out the IAOQ for debugging */
224 		DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n",
225 			regs->iaoq[0], regs->iaoq[1]);
226 	}
227 
228 	err |= __put_user(flags, &sc->sc_flags);
229 
230 	DBG(1,"setup_sigcontext32: Truncating general registers.\n");
231 
232 	for(regn=0; regn < 32; regn++){
233 		/* Truncate a general register */
234 		compat_reg = (compat_uint_t)(regs->gr[regn]);
235 		err |= __put_user(compat_reg, &sc->sc_gr[regn]);
236 		/* Store upper half */
237 		compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);
238 		err |= __put_user(compat_regb, &rf->rf_gr[regn]);
239 
240 		/* DEBUG: Write out the "upper / lower" register data */
241 		DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn,
242 				compat_regb, compat_reg);
243 	}
244 
245 	/* Copy the floating point registers (same size)
246 	   XXX: BE WARNED FR's are 64-BIT! */
247 	DBG(1,"setup_sigcontext32: Copying from regs to sc, "
248 	      "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
249 		sizeof(regs->fr), sizeof(sc->sc_fr));
250 	err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
251 
252 	compat_reg = (compat_uint_t)(regs->sar);
253 	err |= __put_user(compat_reg, &sc->sc_sar);
254 	DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);
255 	/* Store upper half */
256 	compat_reg = (compat_uint_t)(regs->sar >> 32);
257 	err |= __put_user(compat_reg, &rf->rf_sar);
258 	DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);
259 	DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);
260 
261 	return err;
262 }
263 
264 int
265 copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
266 {
267 	compat_uptr_t addr;
268 	int err;
269 
270 	if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
271 		return -EFAULT;
272 
273 	err = __get_user(to->si_signo, &from->si_signo);
274 	err |= __get_user(to->si_errno, &from->si_errno);
275 	err |= __get_user(to->si_code, &from->si_code);
276 
277 	if (to->si_code < 0)
278 		err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
279 	else {
280 		switch (siginfo_layout(to->si_signo, to->si_code)) {
281 		      case SIL_CHLD:
282 			err |= __get_user(to->si_utime, &from->si_utime);
283 			err |= __get_user(to->si_stime, &from->si_stime);
284 			err |= __get_user(to->si_status, &from->si_status);
285 		      default:
286 		      case SIL_KILL:
287 			err |= __get_user(to->si_pid, &from->si_pid);
288 			err |= __get_user(to->si_uid, &from->si_uid);
289 			break;
290 		      case SIL_FAULT:
291 			err |= __get_user(addr, &from->si_addr);
292 			to->si_addr = compat_ptr(addr);
293 			break;
294 		      case SIL_POLL:
295 			err |= __get_user(to->si_band, &from->si_band);
296 			err |= __get_user(to->si_fd, &from->si_fd);
297 			break;
298 		      case SIL_RT:
299 			err |= __get_user(to->si_pid, &from->si_pid);
300 			err |= __get_user(to->si_uid, &from->si_uid);
301 			err |= __get_user(to->si_int, &from->si_int);
302 			break;
303 		}
304 	}
305 	return err;
306 }
307 
308 int
309 copy_siginfo_to_user32 (compat_siginfo_t __user *to, const siginfo_t *from)
310 {
311 	compat_uptr_t addr;
312 	compat_int_t val;
313 	int err;
314 
315 	if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
316 		return -EFAULT;
317 
318 	/* If you change siginfo_t structure, please be sure
319 	   this code is fixed accordingly.
320 	   It should never copy any pad contained in the structure
321 	   to avoid security leaks, but must copy the generic
322 	   3 ints plus the relevant union member.
323 	   This routine must convert siginfo from 64bit to 32bit as well
324 	   at the same time.  */
325 	err = __put_user(from->si_signo, &to->si_signo);
326 	err |= __put_user(from->si_errno, &to->si_errno);
327 	err |= __put_user(from->si_code, &to->si_code);
328 	if (from->si_code < 0)
329 		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
330 	else {
331 		switch (siginfo_layout(from->si_signo, from->si_code)) {
332 		case SIL_CHLD:
333 			err |= __put_user(from->si_utime, &to->si_utime);
334 			err |= __put_user(from->si_stime, &to->si_stime);
335 			err |= __put_user(from->si_status, &to->si_status);
336 		case SIL_KILL:
337 			err |= __put_user(from->si_pid, &to->si_pid);
338 			err |= __put_user(from->si_uid, &to->si_uid);
339 			break;
340 		case SIL_FAULT:
341 			addr = ptr_to_compat(from->si_addr);
342 			err |= __put_user(addr, &to->si_addr);
343 			break;
344 		case SIL_POLL:
345 			err |= __put_user(from->si_band, &to->si_band);
346 			err |= __put_user(from->si_fd, &to->si_fd);
347 			break;
348 		case SIL_TIMER:
349 			err |= __put_user(from->si_tid, &to->si_tid);
350 			err |= __put_user(from->si_overrun, &to->si_overrun);
351 			val = (compat_int_t)from->si_int;
352 			err |= __put_user(val, &to->si_int);
353 			break;
354 		case SIL_RT:
355 			err |= __put_user(from->si_uid, &to->si_uid);
356 			err |= __put_user(from->si_pid, &to->si_pid);
357 			val = (compat_int_t)from->si_int;
358 			err |= __put_user(val, &to->si_int);
359 			break;
360 		case SIL_SYS:
361 			err |= __put_user(ptr_to_compat(from->si_call_addr), &to->si_call_addr);
362 			err |= __put_user(from->si_syscall, &to->si_syscall);
363 			err |= __put_user(from->si_arch, &to->si_arch);
364 			break;
365 		}
366 	}
367 	return err;
368 }
369