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