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