xref: /openbmc/linux/arch/parisc/kernel/signal32.c (revision f35e839a)
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 <asm/uaccess.h>
35 
36 #include "signal32.h"
37 #include "sys32.h"
38 
39 #define DEBUG_COMPAT_SIG 0
40 #define DEBUG_COMPAT_SIG_LEVEL 2
41 
42 #if DEBUG_COMPAT_SIG
43 #define DBG(LEVEL, ...) \
44 	((DEBUG_COMPAT_SIG_LEVEL >= LEVEL) \
45 	? printk(__VA_ARGS__) : (void) 0)
46 #else
47 #define DBG(LEVEL, ...)
48 #endif
49 
50 inline void
51 sigset_32to64(sigset_t *s64, compat_sigset_t *s32)
52 {
53 	s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32);
54 }
55 
56 inline void
57 sigset_64to32(compat_sigset_t *s32, sigset_t *s64)
58 {
59 	s32->sig[0] = s64->sig[0] & 0xffffffffUL;
60 	s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
61 }
62 
63 long
64 restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
65 		struct pt_regs *regs)
66 {
67 	long err = 0;
68 	compat_uint_t compat_reg;
69 	compat_uint_t compat_regt;
70 	int regn;
71 
72 	/* When loading 32-bit values into 64-bit registers make
73 	   sure to clear the upper 32-bits */
74 	DBG(2,"restore_sigcontext32: PER_LINUX32 process\n");
75 	DBG(2,"restore_sigcontext32: sc = 0x%p, rf = 0x%p, regs = 0x%p\n", sc, rf, regs);
76 	DBG(2,"restore_sigcontext32: compat_sigcontext is %#lx bytes\n", sizeof(*sc));
77 	for(regn=0; regn < 32; regn++){
78 		err |= __get_user(compat_reg,&sc->sc_gr[regn]);
79 		regs->gr[regn] = compat_reg;
80 		/* Load upper half */
81 		err |= __get_user(compat_regt,&rf->rf_gr[regn]);
82 		regs->gr[regn] = ((u64)compat_regt << 32) | (u64)compat_reg;
83 		DBG(3,"restore_sigcontext32: gr%02d = %#lx (%#x / %#x)\n",
84 				regn, regs->gr[regn], compat_regt, compat_reg);
85 	}
86 	DBG(2,"restore_sigcontext32: sc->sc_fr = 0x%p (%#lx)\n",sc->sc_fr, sizeof(sc->sc_fr));
87 	/* XXX: BE WARNED FR's are 64-BIT! */
88 	err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
89 
90 	/* Better safe than sorry, pass __get_user two things of
91 	   the same size and let gcc do the upward conversion to
92 	   64-bits */
93 	err |= __get_user(compat_reg, &sc->sc_iaoq[0]);
94 	/* Load upper half */
95 	err |= __get_user(compat_regt, &rf->rf_iaoq[0]);
96 	regs->iaoq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
97 	DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt);
98 	DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n",
99 			&sc->sc_iaoq[0], compat_reg);
100 
101 	err |= __get_user(compat_reg, &sc->sc_iaoq[1]);
102 	/* Load upper half */
103 	err |= __get_user(compat_regt, &rf->rf_iaoq[1]);
104 	regs->iaoq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
105 	DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt);
106 	DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n",
107 			&sc->sc_iaoq[1],compat_reg);
108 	DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n",
109 			regs->iaoq[0],regs->iaoq[1]);
110 
111 	err |= __get_user(compat_reg, &sc->sc_iasq[0]);
112 	/* Load the upper half for iasq */
113 	err |= __get_user(compat_regt, &rf->rf_iasq[0]);
114 	regs->iasq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
115 	DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt);
116 
117 	err |= __get_user(compat_reg, &sc->sc_iasq[1]);
118 	/* Load the upper half for iasq */
119 	err |= __get_user(compat_regt, &rf->rf_iasq[1]);
120 	regs->iasq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
121 	DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt);
122 	DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n",
123 		regs->iasq[0],regs->iasq[1]);
124 
125 	err |= __get_user(compat_reg, &sc->sc_sar);
126 	/* Load the upper half for sar */
127 	err |= __get_user(compat_regt, &rf->rf_sar);
128 	regs->sar = ((u64)compat_regt << 32) | (u64)compat_reg;
129 	DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);
130 	DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);
131 	DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);
132 
133 	return err;
134 }
135 
136 /*
137  * Set up the sigcontext structure for this process.
138  * This is not an easy task if the kernel is 64-bit, it will require
139  * that we examine the process personality to determine if we need to
140  * truncate for a 32-bit userspace.
141  */
142 long
143 setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
144 		struct pt_regs *regs, int in_syscall)
145 {
146 	compat_int_t flags = 0;
147 	long err = 0;
148 	compat_uint_t compat_reg;
149 	compat_uint_t compat_regb;
150 	int regn;
151 
152 	if (on_sig_stack((unsigned long) sc))
153 		flags |= PARISC_SC_FLAG_ONSTACK;
154 
155 	if (in_syscall) {
156 
157 		DBG(1,"setup_sigcontext32: in_syscall\n");
158 
159 		flags |= PARISC_SC_FLAG_IN_SYSCALL;
160 		/* Truncate gr31 */
161 		compat_reg = (compat_uint_t)(regs->gr[31]);
162 		/* regs->iaoq is undefined in the syscall return path */
163 		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
164 		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
165 				&sc->sc_iaoq[0], compat_reg);
166 
167 		/* Store upper half */
168 		compat_reg = (compat_uint_t)(regs->gr[31] >> 32);
169 		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
170 		DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
171 
172 
173 		compat_reg = (compat_uint_t)(regs->gr[31]+4);
174 		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
175 		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
176 				&sc->sc_iaoq[1], compat_reg);
177 		/* Store upper half */
178 		compat_reg = (compat_uint_t)((regs->gr[31]+4) >> 32);
179 		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
180 		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
181 
182 		/* Truncate sr3 */
183 		compat_reg = (compat_uint_t)(regs->sr[3]);
184 		err |= __put_user(compat_reg, &sc->sc_iasq[0]);
185 		err |= __put_user(compat_reg, &sc->sc_iasq[1]);
186 
187 		/* Store upper half */
188 		compat_reg = (compat_uint_t)(regs->sr[3] >> 32);
189 		err |= __put_user(compat_reg, &rf->rf_iasq[0]);
190 		err |= __put_user(compat_reg, &rf->rf_iasq[1]);
191 
192 		DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
193 		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
194 		DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",
195 			regs->gr[31], regs->gr[31]+4);
196 
197 	} else {
198 
199 		compat_reg = (compat_uint_t)(regs->iaoq[0]);
200 		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
201 		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
202 				&sc->sc_iaoq[0], compat_reg);
203 		/* Store upper half */
204 		compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);
205 		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
206 		DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
207 
208 		compat_reg = (compat_uint_t)(regs->iaoq[1]);
209 		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
210 		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
211 				&sc->sc_iaoq[1], compat_reg);
212 		/* Store upper half */
213 		compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);
214 		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
215 		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
216 
217 
218 		compat_reg = (compat_uint_t)(regs->iasq[0]);
219 		err |= __put_user(compat_reg, &sc->sc_iasq[0]);
220 		DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
221 				&sc->sc_iasq[0], compat_reg);
222 		/* Store upper half */
223 		compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);
224 		err |= __put_user(compat_reg, &rf->rf_iasq[0]);
225 		DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
226 
227 
228 		compat_reg = (compat_uint_t)(regs->iasq[1]);
229 		err |= __put_user(compat_reg, &sc->sc_iasq[1]);
230 		DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
231 				&sc->sc_iasq[1], compat_reg);
232 		/* Store upper half */
233 		compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);
234 		err |= __put_user(compat_reg, &rf->rf_iasq[1]);
235 		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
236 
237 		/* Print out the IAOQ for debugging */
238 		DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n",
239 			regs->iaoq[0], regs->iaoq[1]);
240 	}
241 
242 	err |= __put_user(flags, &sc->sc_flags);
243 
244 	DBG(1,"setup_sigcontext32: Truncating general registers.\n");
245 
246 	for(regn=0; regn < 32; regn++){
247 		/* Truncate a general register */
248 		compat_reg = (compat_uint_t)(regs->gr[regn]);
249 		err |= __put_user(compat_reg, &sc->sc_gr[regn]);
250 		/* Store upper half */
251 		compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);
252 		err |= __put_user(compat_regb, &rf->rf_gr[regn]);
253 
254 		/* DEBUG: Write out the "upper / lower" register data */
255 		DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn,
256 				compat_regb, compat_reg);
257 	}
258 
259 	/* Copy the floating point registers (same size)
260 	   XXX: BE WARNED FR's are 64-BIT! */
261 	DBG(1,"setup_sigcontext32: Copying from regs to sc, "
262 	      "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
263 		sizeof(regs->fr), sizeof(sc->sc_fr));
264 	err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
265 
266 	compat_reg = (compat_uint_t)(regs->sar);
267 	err |= __put_user(compat_reg, &sc->sc_sar);
268 	DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);
269 	/* Store upper half */
270 	compat_reg = (compat_uint_t)(regs->sar >> 32);
271 	err |= __put_user(compat_reg, &rf->rf_sar);
272 	DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);
273 	DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);
274 
275 	return err;
276 }
277 
278 int
279 copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
280 {
281 	compat_uptr_t addr;
282 	int err;
283 
284 	if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
285 		return -EFAULT;
286 
287 	err = __get_user(to->si_signo, &from->si_signo);
288 	err |= __get_user(to->si_errno, &from->si_errno);
289 	err |= __get_user(to->si_code, &from->si_code);
290 
291 	if (to->si_code < 0)
292 		err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
293 	else {
294 		switch (to->si_code >> 16) {
295 		      case __SI_CHLD >> 16:
296 			err |= __get_user(to->si_utime, &from->si_utime);
297 			err |= __get_user(to->si_stime, &from->si_stime);
298 			err |= __get_user(to->si_status, &from->si_status);
299 		      default:
300 			err |= __get_user(to->si_pid, &from->si_pid);
301 			err |= __get_user(to->si_uid, &from->si_uid);
302 			break;
303 		      case __SI_FAULT >> 16:
304 			err |= __get_user(addr, &from->si_addr);
305 			to->si_addr = compat_ptr(addr);
306 			break;
307 		      case __SI_POLL >> 16:
308 			err |= __get_user(to->si_band, &from->si_band);
309 			err |= __get_user(to->si_fd, &from->si_fd);
310 			break;
311 		      case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
312 		      case __SI_MESGQ >> 16:
313 			err |= __get_user(to->si_pid, &from->si_pid);
314 			err |= __get_user(to->si_uid, &from->si_uid);
315 			err |= __get_user(to->si_int, &from->si_int);
316 			break;
317 		}
318 	}
319 	return err;
320 }
321 
322 int
323 copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
324 {
325 	compat_uptr_t addr;
326 	compat_int_t val;
327 	int err;
328 
329 	if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
330 		return -EFAULT;
331 
332 	/* If you change siginfo_t structure, please be sure
333 	   this code is fixed accordingly.
334 	   It should never copy any pad contained in the structure
335 	   to avoid security leaks, but must copy the generic
336 	   3 ints plus the relevant union member.
337 	   This routine must convert siginfo from 64bit to 32bit as well
338 	   at the same time.  */
339 	err = __put_user(from->si_signo, &to->si_signo);
340 	err |= __put_user(from->si_errno, &to->si_errno);
341 	err |= __put_user((short)from->si_code, &to->si_code);
342 	if (from->si_code < 0)
343 		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
344 	else {
345 		switch (from->si_code >> 16) {
346 		case __SI_CHLD >> 16:
347 			err |= __put_user(from->si_utime, &to->si_utime);
348 			err |= __put_user(from->si_stime, &to->si_stime);
349 			err |= __put_user(from->si_status, &to->si_status);
350 		default:
351 			err |= __put_user(from->si_pid, &to->si_pid);
352 			err |= __put_user(from->si_uid, &to->si_uid);
353 			break;
354 		case __SI_FAULT >> 16:
355 			addr = ptr_to_compat(from->si_addr);
356 			err |= __put_user(addr, &to->si_addr);
357 			break;
358 		case __SI_POLL >> 16:
359 			err |= __put_user(from->si_band, &to->si_band);
360 			err |= __put_user(from->si_fd, &to->si_fd);
361 			break;
362 		case __SI_TIMER >> 16:
363 			err |= __put_user(from->si_tid, &to->si_tid);
364 			err |= __put_user(from->si_overrun, &to->si_overrun);
365 			val = (compat_int_t)from->si_int;
366 			err |= __put_user(val, &to->si_int);
367 			break;
368 		case __SI_RT >> 16:	/* Not generated by the kernel as of now.  */
369 		case __SI_MESGQ >> 16:
370 			err |= __put_user(from->si_uid, &to->si_uid);
371 			err |= __put_user(from->si_pid, &to->si_pid);
372 			val = (compat_int_t)from->si_int;
373 			err |= __put_user(val, &to->si_int);
374 			break;
375 		}
376 	}
377 	return err;
378 }
379