| 1 | // SPDX-License-Identifier: GPL-2.0 | 
|---|
| 2 | /* | 
|---|
| 3 | *  Copyright (C) 1991, 1992  Linus Torvalds | 
|---|
| 4 | * | 
|---|
| 5 | *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson | 
|---|
| 6 | *  2000-06-20  Pentium III FXSR, SSE support by Gareth Hughes | 
|---|
| 7 | *  2000-12-*   x86-64 compatibility mode signal handling by Andi Kleen | 
|---|
| 8 | */ | 
|---|
| 9 |  | 
|---|
| 10 | #include <linux/sched.h> | 
|---|
| 11 | #include <linux/sched/task_stack.h> | 
|---|
| 12 | #include <linux/mm.h> | 
|---|
| 13 | #include <linux/smp.h> | 
|---|
| 14 | #include <linux/kernel.h> | 
|---|
| 15 | #include <linux/errno.h> | 
|---|
| 16 | #include <linux/wait.h> | 
|---|
| 17 | #include <linux/unistd.h> | 
|---|
| 18 | #include <linux/stddef.h> | 
|---|
| 19 | #include <linux/personality.h> | 
|---|
| 20 | #include <linux/compat.h> | 
|---|
| 21 | #include <linux/binfmts.h> | 
|---|
| 22 | #include <linux/syscalls.h> | 
|---|
| 23 | #include <asm/ucontext.h> | 
|---|
| 24 | #include <linux/uaccess.h> | 
|---|
| 25 | #include <asm/fpu/signal.h> | 
|---|
| 26 | #include <asm/ptrace.h> | 
|---|
| 27 | #include <asm/user32.h> | 
|---|
| 28 | #include <uapi/asm/sigcontext.h> | 
|---|
| 29 | #include <asm/proto.h> | 
|---|
| 30 | #include <asm/vdso.h> | 
|---|
| 31 | #include <asm/sigframe.h> | 
|---|
| 32 | #include <asm/sighandling.h> | 
|---|
| 33 | #include <asm/smap.h> | 
|---|
| 34 | #include <asm/gsseg.h> | 
|---|
| 35 |  | 
|---|
| 36 | /* | 
|---|
| 37 | * The first GDT descriptor is reserved as 'NULL descriptor'.  As bits 0 | 
|---|
| 38 | * and 1 of a segment selector, i.e., the RPL bits, are NOT used to index | 
|---|
| 39 | * GDT, selector values 0~3 all point to the NULL descriptor, thus values | 
|---|
| 40 | * 0, 1, 2 and 3 are all valid NULL selector values. | 
|---|
| 41 | * | 
|---|
| 42 | * However IRET zeros ES, FS, GS, and DS segment registers if any of them | 
|---|
| 43 | * is found to have any nonzero NULL selector value, which can be used by | 
|---|
| 44 | * userspace in pre-FRED systems to spot any interrupt/exception by loading | 
|---|
| 45 | * a nonzero NULL selector and waiting for it to become zero.  Before FRED | 
|---|
| 46 | * there was nothing software could do to prevent such an information leak. | 
|---|
| 47 | * | 
|---|
| 48 | * ERETU, the only legit instruction to return to userspace from kernel | 
|---|
| 49 | * under FRED, by design does NOT zero any segment register to avoid this | 
|---|
| 50 | * problem behavior. | 
|---|
| 51 | * | 
|---|
| 52 | * As such, leave NULL selector values 0~3 unchanged. | 
|---|
| 53 | */ | 
|---|
| 54 | static inline u16 fixup_rpl(u16 sel) | 
|---|
| 55 | { | 
|---|
| 56 | return sel <= 3 ? sel : sel | 3; | 
|---|
| 57 | } | 
|---|
| 58 |  | 
|---|
| 59 | #ifdef CONFIG_IA32_EMULATION | 
|---|
| 60 | #include <asm/unistd_32_ia32.h> | 
|---|
| 61 |  | 
|---|
| 62 | static inline void reload_segments(struct sigcontext_32 *sc) | 
|---|
| 63 | { | 
|---|
| 64 | u16 cur; | 
|---|
| 65 |  | 
|---|
| 66 | /* | 
|---|
| 67 | * Reload fs and gs if they have changed in the signal | 
|---|
| 68 | * handler.  This does not handle long fs/gs base changes in | 
|---|
| 69 | * the handler, but does not clobber them at least in the | 
|---|
| 70 | * normal case. | 
|---|
| 71 | */ | 
|---|
| 72 | savesegment(gs, cur); | 
|---|
| 73 | if (fixup_rpl(sel: sc->gs) != cur) | 
|---|
| 74 | load_gs_index(selector: fixup_rpl(sel: sc->gs)); | 
|---|
| 75 | savesegment(fs, cur); | 
|---|
| 76 | if (fixup_rpl(sel: sc->fs) != cur) | 
|---|
| 77 | loadsegment(fs, fixup_rpl(sc->fs)); | 
|---|
| 78 |  | 
|---|
| 79 | savesegment(ds, cur); | 
|---|
| 80 | if (fixup_rpl(sel: sc->ds) != cur) | 
|---|
| 81 | loadsegment(ds, fixup_rpl(sc->ds)); | 
|---|
| 82 | savesegment(es, cur); | 
|---|
| 83 | if (fixup_rpl(sel: sc->es) != cur) | 
|---|
| 84 | loadsegment(es, fixup_rpl(sc->es)); | 
|---|
| 85 | } | 
|---|
| 86 |  | 
|---|
| 87 | #define sigset32_t			compat_sigset_t | 
|---|
| 88 | #define siginfo32_t			compat_siginfo_t | 
|---|
| 89 | #define restore_altstack32		compat_restore_altstack | 
|---|
| 90 | #define unsafe_save_altstack32		unsafe_compat_save_altstack | 
|---|
| 91 |  | 
|---|
| 92 | #else | 
|---|
| 93 |  | 
|---|
| 94 | #define sigset32_t			sigset_t | 
|---|
| 95 | #define siginfo32_t			siginfo_t | 
|---|
| 96 | #define __NR_ia32_sigreturn		__NR_sigreturn | 
|---|
| 97 | #define __NR_ia32_rt_sigreturn		__NR_rt_sigreturn | 
|---|
| 98 | #define restore_altstack32		restore_altstack | 
|---|
| 99 | #define unsafe_save_altstack32		unsafe_save_altstack | 
|---|
| 100 | #define __copy_siginfo_to_user32	copy_siginfo_to_user | 
|---|
| 101 |  | 
|---|
| 102 | #endif | 
|---|
| 103 |  | 
|---|
| 104 | /* | 
|---|
| 105 | * Do a signal return; undo the signal stack. | 
|---|
| 106 | */ | 
|---|
| 107 | static bool ia32_restore_sigcontext(struct pt_regs *regs, | 
|---|
| 108 | struct sigcontext_32 __user *usc) | 
|---|
| 109 | { | 
|---|
| 110 | struct sigcontext_32 sc; | 
|---|
| 111 |  | 
|---|
| 112 | /* Always make any pending restarted system calls return -EINTR */ | 
|---|
| 113 | current->restart_block.fn = do_no_restart_syscall; | 
|---|
| 114 |  | 
|---|
| 115 | if (unlikely(copy_from_user(&sc, usc, sizeof(sc)))) | 
|---|
| 116 | return false; | 
|---|
| 117 |  | 
|---|
| 118 | /* Get only the ia32 registers. */ | 
|---|
| 119 | regs->bx = sc.bx; | 
|---|
| 120 | regs->cx = sc.cx; | 
|---|
| 121 | regs->dx = sc.dx; | 
|---|
| 122 | regs->si = sc.si; | 
|---|
| 123 | regs->di = sc.di; | 
|---|
| 124 | regs->bp = sc.bp; | 
|---|
| 125 | regs->ax = sc.ax; | 
|---|
| 126 | regs->sp = sc.sp; | 
|---|
| 127 | regs->ip = sc.ip; | 
|---|
| 128 |  | 
|---|
| 129 | /* Get CS/SS and force CPL3 */ | 
|---|
| 130 | regs->cs = sc.cs | 0x03; | 
|---|
| 131 | regs->ss = sc.ss | 0x03; | 
|---|
| 132 |  | 
|---|
| 133 | regs->flags = (regs->flags & ~FIX_EFLAGS) | (sc.flags & FIX_EFLAGS); | 
|---|
| 134 | /* disable syscall checks */ | 
|---|
| 135 | regs->orig_ax = -1; | 
|---|
| 136 |  | 
|---|
| 137 | #ifdef CONFIG_IA32_EMULATION | 
|---|
| 138 | reload_segments(sc: &sc); | 
|---|
| 139 | #else | 
|---|
| 140 | loadsegment(gs, fixup_rpl(sc.gs)); | 
|---|
| 141 | regs->fs = fixup_rpl(sc.fs); | 
|---|
| 142 | regs->es = fixup_rpl(sc.es); | 
|---|
| 143 | regs->ds = fixup_rpl(sc.ds); | 
|---|
| 144 | #endif | 
|---|
| 145 |  | 
|---|
| 146 | return fpu__restore_sig(buf: compat_ptr(uptr: sc.fpstate), ia32_frame: 1); | 
|---|
| 147 | } | 
|---|
| 148 |  | 
|---|
| 149 | SYSCALL32_DEFINE0(sigreturn) | 
|---|
| 150 | { | 
|---|
| 151 | struct pt_regs *regs = current_pt_regs(); | 
|---|
| 152 | struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8); | 
|---|
| 153 | sigset_t set; | 
|---|
| 154 |  | 
|---|
| 155 | prevent_single_step_upon_eretu(regs); | 
|---|
| 156 |  | 
|---|
| 157 | if (!access_ok(frame, sizeof(*frame))) | 
|---|
| 158 | goto badframe; | 
|---|
| 159 | if (__get_user(set.sig[0], &frame->sc.oldmask) | 
|---|
| 160 | || __get_user(((__u32 *)&set)[1], &frame->extramask[0])) | 
|---|
| 161 | goto badframe; | 
|---|
| 162 |  | 
|---|
| 163 | set_current_blocked(&set); | 
|---|
| 164 |  | 
|---|
| 165 | if (!ia32_restore_sigcontext(regs, usc: &frame->sc)) | 
|---|
| 166 | goto badframe; | 
|---|
| 167 | return regs->ax; | 
|---|
| 168 |  | 
|---|
| 169 | badframe: | 
|---|
| 170 | signal_fault(regs, frame, where: "32bit sigreturn"); | 
|---|
| 171 | return 0; | 
|---|
| 172 | } | 
|---|
| 173 |  | 
|---|
| 174 | SYSCALL32_DEFINE0(rt_sigreturn) | 
|---|
| 175 | { | 
|---|
| 176 | struct pt_regs *regs = current_pt_regs(); | 
|---|
| 177 | struct rt_sigframe_ia32 __user *frame; | 
|---|
| 178 | sigset_t set; | 
|---|
| 179 |  | 
|---|
| 180 | prevent_single_step_upon_eretu(regs); | 
|---|
| 181 |  | 
|---|
| 182 | frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4); | 
|---|
| 183 |  | 
|---|
| 184 | if (!access_ok(frame, sizeof(*frame))) | 
|---|
| 185 | goto badframe; | 
|---|
| 186 | if (__get_user(*(__u64 *)&set, (__u64 __user *)&frame->uc.uc_sigmask)) | 
|---|
| 187 | goto badframe; | 
|---|
| 188 |  | 
|---|
| 189 | set_current_blocked(&set); | 
|---|
| 190 |  | 
|---|
| 191 | if (!ia32_restore_sigcontext(regs, usc: &frame->uc.uc_mcontext)) | 
|---|
| 192 | goto badframe; | 
|---|
| 193 |  | 
|---|
| 194 | if (restore_altstack32(uss: &frame->uc.uc_stack)) | 
|---|
| 195 | goto badframe; | 
|---|
| 196 |  | 
|---|
| 197 | return regs->ax; | 
|---|
| 198 |  | 
|---|
| 199 | badframe: | 
|---|
| 200 | signal_fault(regs, frame, where: "32bit rt sigreturn"); | 
|---|
| 201 | return 0; | 
|---|
| 202 | } | 
|---|
| 203 |  | 
|---|
| 204 | /* | 
|---|
| 205 | * Set up a signal frame. | 
|---|
| 206 | */ | 
|---|
| 207 |  | 
|---|
| 208 | #define get_user_seg(seg)	({ unsigned int v; savesegment(seg, v); v; }) | 
|---|
| 209 |  | 
|---|
| 210 | static __always_inline int | 
|---|
| 211 | __unsafe_setup_sigcontext32(struct sigcontext_32 __user *sc, | 
|---|
| 212 | void __user *fpstate, | 
|---|
| 213 | struct pt_regs *regs, unsigned int mask) | 
|---|
| 214 | { | 
|---|
| 215 | unsafe_put_user(get_user_seg(gs), (unsigned int __user *)&sc->gs, Efault); | 
|---|
| 216 | #ifdef CONFIG_IA32_EMULATION | 
|---|
| 217 | unsafe_put_user(get_user_seg(fs), (unsigned int __user *)&sc->fs, Efault); | 
|---|
| 218 | unsafe_put_user(get_user_seg(ds), (unsigned int __user *)&sc->ds, Efault); | 
|---|
| 219 | unsafe_put_user(get_user_seg(es), (unsigned int __user *)&sc->es, Efault); | 
|---|
| 220 | #else | 
|---|
| 221 | unsafe_put_user(regs->fs, (unsigned int __user *)&sc->fs, Efault); | 
|---|
| 222 | unsafe_put_user(regs->es, (unsigned int __user *)&sc->es, Efault); | 
|---|
| 223 | unsafe_put_user(regs->ds, (unsigned int __user *)&sc->ds, Efault); | 
|---|
| 224 | #endif | 
|---|
| 225 |  | 
|---|
| 226 | unsafe_put_user(regs->di, &sc->di, Efault); | 
|---|
| 227 | unsafe_put_user(regs->si, &sc->si, Efault); | 
|---|
| 228 | unsafe_put_user(regs->bp, &sc->bp, Efault); | 
|---|
| 229 | unsafe_put_user(regs->sp, &sc->sp, Efault); | 
|---|
| 230 | unsafe_put_user(regs->bx, &sc->bx, Efault); | 
|---|
| 231 | unsafe_put_user(regs->dx, &sc->dx, Efault); | 
|---|
| 232 | unsafe_put_user(regs->cx, &sc->cx, Efault); | 
|---|
| 233 | unsafe_put_user(regs->ax, &sc->ax, Efault); | 
|---|
| 234 | unsafe_put_user(current->thread.trap_nr, &sc->trapno, Efault); | 
|---|
| 235 | unsafe_put_user(current->thread.error_code, &sc->err, Efault); | 
|---|
| 236 | unsafe_put_user(regs->ip, &sc->ip, Efault); | 
|---|
| 237 | unsafe_put_user(regs->cs, (unsigned int __user *)&sc->cs, Efault); | 
|---|
| 238 | unsafe_put_user(regs->flags, &sc->flags, Efault); | 
|---|
| 239 | unsafe_put_user(regs->sp, &sc->sp_at_signal, Efault); | 
|---|
| 240 | unsafe_put_user(regs->ss, (unsigned int __user *)&sc->ss, Efault); | 
|---|
| 241 |  | 
|---|
| 242 | unsafe_put_user(ptr_to_compat(fpstate), &sc->fpstate, Efault); | 
|---|
| 243 |  | 
|---|
| 244 | /* non-iBCS2 extensions.. */ | 
|---|
| 245 | unsafe_put_user(mask, &sc->oldmask, Efault); | 
|---|
| 246 | unsafe_put_user(current->thread.cr2, &sc->cr2, Efault); | 
|---|
| 247 | return 0; | 
|---|
| 248 |  | 
|---|
| 249 | Efault: | 
|---|
| 250 | return -EFAULT; | 
|---|
| 251 | } | 
|---|
| 252 |  | 
|---|
| 253 | #define unsafe_put_sigcontext32(sc, fp, regs, set, label)		\ | 
|---|
| 254 | do {									\ | 
|---|
| 255 | if (__unsafe_setup_sigcontext32(sc, fp, regs, set->sig[0]))	\ | 
|---|
| 256 | goto label;						\ | 
|---|
| 257 | } while(0) | 
|---|
| 258 |  | 
|---|
| 259 | int ia32_setup_frame(struct ksignal *ksig, struct pt_regs *regs) | 
|---|
| 260 | { | 
|---|
| 261 | sigset32_t *set = (sigset32_t *) sigmask_to_save(); | 
|---|
| 262 | struct sigframe_ia32 __user *frame; | 
|---|
| 263 | void __user *restorer; | 
|---|
| 264 | void __user *fp = NULL; | 
|---|
| 265 |  | 
|---|
| 266 | /* copy_to_user optimizes that into a single 8 byte store */ | 
|---|
| 267 | static const struct { | 
|---|
| 268 | u16 poplmovl; | 
|---|
| 269 | u32 val; | 
|---|
| 270 | u16 int80; | 
|---|
| 271 | } __attribute__((packed)) code = { | 
|---|
| 272 | 0xb858,		 /* popl %eax ; movl $...,%eax */ | 
|---|
| 273 | __NR_ia32_sigreturn, | 
|---|
| 274 | 0x80cd,		/* int $0x80 */ | 
|---|
| 275 | }; | 
|---|
| 276 |  | 
|---|
| 277 | frame = get_sigframe(ksig, regs, frame_size: sizeof(*frame), fpstate: &fp); | 
|---|
| 278 |  | 
|---|
| 279 | if (ksig->ka.sa.sa_flags & SA_RESTORER) { | 
|---|
| 280 | restorer = ksig->ka.sa.sa_restorer; | 
|---|
| 281 | } else { | 
|---|
| 282 | /* Return stub is in 32bit vsyscall page */ | 
|---|
| 283 | if (current->mm->context.vdso) | 
|---|
| 284 | restorer = current->mm->context.vdso + | 
|---|
| 285 | vdso_image_32.sym___kernel_sigreturn; | 
|---|
| 286 | else | 
|---|
| 287 | restorer = &frame->retcode; | 
|---|
| 288 | } | 
|---|
| 289 |  | 
|---|
| 290 | if (!user_access_begin(frame, sizeof(*frame))) | 
|---|
| 291 | return -EFAULT; | 
|---|
| 292 |  | 
|---|
| 293 | unsafe_put_user(ksig->sig, &frame->sig, Efault); | 
|---|
| 294 | unsafe_put_sigcontext32(&frame->sc, fp, regs, set, Efault); | 
|---|
| 295 | unsafe_put_user(set->sig[1], &frame->extramask[0], Efault); | 
|---|
| 296 | unsafe_put_user(ptr_to_compat(restorer), &frame->pretcode, Efault); | 
|---|
| 297 | /* | 
|---|
| 298 | * These are actually not used anymore, but left because some | 
|---|
| 299 | * gdb versions depend on them as a marker. | 
|---|
| 300 | */ | 
|---|
| 301 | unsafe_put_user(*((u64 *)&code), (u64 __user *)frame->retcode, Efault); | 
|---|
| 302 | user_access_end(); | 
|---|
| 303 |  | 
|---|
| 304 | /* Set up registers for signal handler */ | 
|---|
| 305 | regs->sp = (unsigned long) frame; | 
|---|
| 306 | regs->ip = (unsigned long) ksig->ka.sa.sa_handler; | 
|---|
| 307 |  | 
|---|
| 308 | /* Make -mregparm=3 work */ | 
|---|
| 309 | regs->ax = ksig->sig; | 
|---|
| 310 | regs->dx = 0; | 
|---|
| 311 | regs->cx = 0; | 
|---|
| 312 |  | 
|---|
| 313 | #ifdef CONFIG_IA32_EMULATION | 
|---|
| 314 | loadsegment(ds, __USER_DS); | 
|---|
| 315 | loadsegment(es, __USER_DS); | 
|---|
| 316 | #else | 
|---|
| 317 | regs->ds = __USER_DS; | 
|---|
| 318 | regs->es = __USER_DS; | 
|---|
| 319 | #endif | 
|---|
| 320 |  | 
|---|
| 321 | regs->cs = __USER32_CS; | 
|---|
| 322 | regs->ss = __USER_DS; | 
|---|
| 323 |  | 
|---|
| 324 | return 0; | 
|---|
| 325 | Efault: | 
|---|
| 326 | user_access_end(); | 
|---|
| 327 | return -EFAULT; | 
|---|
| 328 | } | 
|---|
| 329 |  | 
|---|
| 330 | int ia32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) | 
|---|
| 331 | { | 
|---|
| 332 | sigset32_t *set = (sigset32_t *) sigmask_to_save(); | 
|---|
| 333 | struct rt_sigframe_ia32 __user *frame; | 
|---|
| 334 | void __user *restorer; | 
|---|
| 335 | void __user *fp = NULL; | 
|---|
| 336 |  | 
|---|
| 337 | /* unsafe_put_user optimizes that into a single 8 byte store */ | 
|---|
| 338 | static const struct { | 
|---|
| 339 | u8 movl; | 
|---|
| 340 | u32 val; | 
|---|
| 341 | u16 int80; | 
|---|
| 342 | u8  pad; | 
|---|
| 343 | } __attribute__((packed)) code = { | 
|---|
| 344 | 0xb8, | 
|---|
| 345 | __NR_ia32_rt_sigreturn, | 
|---|
| 346 | 0x80cd, | 
|---|
| 347 | 0, | 
|---|
| 348 | }; | 
|---|
| 349 |  | 
|---|
| 350 | frame = get_sigframe(ksig, regs, frame_size: sizeof(*frame), fpstate: &fp); | 
|---|
| 351 |  | 
|---|
| 352 | if (!user_access_begin(frame, sizeof(*frame))) | 
|---|
| 353 | return -EFAULT; | 
|---|
| 354 |  | 
|---|
| 355 | unsafe_put_user(ksig->sig, &frame->sig, Efault); | 
|---|
| 356 | unsafe_put_user(ptr_to_compat(&frame->info), &frame->pinfo, Efault); | 
|---|
| 357 | unsafe_put_user(ptr_to_compat(&frame->uc), &frame->puc, Efault); | 
|---|
| 358 |  | 
|---|
| 359 | /* Create the ucontext.  */ | 
|---|
| 360 | if (static_cpu_has(X86_FEATURE_XSAVE)) | 
|---|
| 361 | unsafe_put_user(UC_FP_XSTATE, &frame->uc.uc_flags, Efault); | 
|---|
| 362 | else | 
|---|
| 363 | unsafe_put_user(0, &frame->uc.uc_flags, Efault); | 
|---|
| 364 | unsafe_put_user(0, &frame->uc.uc_link, Efault); | 
|---|
| 365 | unsafe_save_altstack32(&frame->uc.uc_stack, regs->sp, Efault); | 
|---|
| 366 |  | 
|---|
| 367 | if (ksig->ka.sa.sa_flags & SA_RESTORER) | 
|---|
| 368 | restorer = ksig->ka.sa.sa_restorer; | 
|---|
| 369 | else | 
|---|
| 370 | restorer = current->mm->context.vdso + | 
|---|
| 371 | vdso_image_32.sym___kernel_rt_sigreturn; | 
|---|
| 372 | unsafe_put_user(ptr_to_compat(restorer), &frame->pretcode, Efault); | 
|---|
| 373 |  | 
|---|
| 374 | /* | 
|---|
| 375 | * Not actually used anymore, but left because some gdb | 
|---|
| 376 | * versions need it. | 
|---|
| 377 | */ | 
|---|
| 378 | unsafe_put_user(*((u64 *)&code), (u64 __user *)frame->retcode, Efault); | 
|---|
| 379 | unsafe_put_sigcontext32(&frame->uc.uc_mcontext, fp, regs, set, Efault); | 
|---|
| 380 | unsafe_put_user(*(__u64 *)set, (__u64 __user *)&frame->uc.uc_sigmask, Efault); | 
|---|
| 381 | user_access_end(); | 
|---|
| 382 |  | 
|---|
| 383 | if (__copy_siginfo_to_user32(to: &frame->info, from: &ksig->info)) | 
|---|
| 384 | return -EFAULT; | 
|---|
| 385 |  | 
|---|
| 386 | /* Set up registers for signal handler */ | 
|---|
| 387 | regs->sp = (unsigned long) frame; | 
|---|
| 388 | regs->ip = (unsigned long) ksig->ka.sa.sa_handler; | 
|---|
| 389 |  | 
|---|
| 390 | /* Make -mregparm=3 work */ | 
|---|
| 391 | regs->ax = ksig->sig; | 
|---|
| 392 | regs->dx = (unsigned long) &frame->info; | 
|---|
| 393 | regs->cx = (unsigned long) &frame->uc; | 
|---|
| 394 |  | 
|---|
| 395 | #ifdef CONFIG_IA32_EMULATION | 
|---|
| 396 | loadsegment(ds, __USER_DS); | 
|---|
| 397 | loadsegment(es, __USER_DS); | 
|---|
| 398 | #else | 
|---|
| 399 | regs->ds = __USER_DS; | 
|---|
| 400 | regs->es = __USER_DS; | 
|---|
| 401 | #endif | 
|---|
| 402 |  | 
|---|
| 403 | regs->cs = __USER32_CS; | 
|---|
| 404 | regs->ss = __USER_DS; | 
|---|
| 405 |  | 
|---|
| 406 | return 0; | 
|---|
| 407 | Efault: | 
|---|
| 408 | user_access_end(); | 
|---|
| 409 | return -EFAULT; | 
|---|
| 410 | } | 
|---|
| 411 |  | 
|---|
| 412 | /* | 
|---|
| 413 | * The siginfo_t structure and handing code is very easy | 
|---|
| 414 | * to break in several ways.  It must always be updated when new | 
|---|
| 415 | * updates are made to the main siginfo_t, and | 
|---|
| 416 | * copy_siginfo_to_user32() must be updated when the | 
|---|
| 417 | * (arch-independent) copy_siginfo_to_user() is updated. | 
|---|
| 418 | * | 
|---|
| 419 | * It is also easy to put a new member in the siginfo_t | 
|---|
| 420 | * which has implicit alignment which can move internal structure | 
|---|
| 421 | * alignment around breaking the ABI.  This can happen if you, | 
|---|
| 422 | * for instance, put a plain 64-bit value in there. | 
|---|
| 423 | */ | 
|---|
| 424 |  | 
|---|
| 425 | /* | 
|---|
| 426 | * If adding a new si_code, there is probably new data in | 
|---|
| 427 | * the siginfo.  Make sure folks bumping the si_code | 
|---|
| 428 | * limits also have to look at this code.  Make sure any | 
|---|
| 429 | * new fields are handled in copy_siginfo_to_user32()! | 
|---|
| 430 | */ | 
|---|
| 431 | static_assert(NSIGILL  == 11); | 
|---|
| 432 | static_assert(NSIGFPE  == 15); | 
|---|
| 433 | static_assert(NSIGSEGV == 10); | 
|---|
| 434 | static_assert(NSIGBUS  == 5); | 
|---|
| 435 | static_assert(NSIGTRAP == 6); | 
|---|
| 436 | static_assert(NSIGCHLD == 6); | 
|---|
| 437 | static_assert(NSIGSYS  == 2); | 
|---|
| 438 |  | 
|---|
| 439 | /* This is part of the ABI and can never change in size: */ | 
|---|
| 440 | static_assert(sizeof(siginfo32_t) == 128); | 
|---|
| 441 |  | 
|---|
| 442 | /* This is a part of the ABI and can never change in alignment */ | 
|---|
| 443 | static_assert(__alignof__(siginfo32_t) == 4); | 
|---|
| 444 |  | 
|---|
| 445 | /* | 
|---|
| 446 | * The offsets of all the (unioned) si_fields are fixed | 
|---|
| 447 | * in the ABI, of course.  Make sure none of them ever | 
|---|
| 448 | * move and are always at the beginning: | 
|---|
| 449 | */ | 
|---|
| 450 | static_assert(offsetof(siginfo32_t, _sifields) == 3 * sizeof(int)); | 
|---|
| 451 |  | 
|---|
| 452 | static_assert(offsetof(siginfo32_t, si_signo) == 0); | 
|---|
| 453 | static_assert(offsetof(siginfo32_t, si_errno) == 4); | 
|---|
| 454 | static_assert(offsetof(siginfo32_t, si_code)  == 8); | 
|---|
| 455 |  | 
|---|
| 456 | /* | 
|---|
| 457 | * Ensure that the size of each si_field never changes. | 
|---|
| 458 | * If it does, it is a sign that the | 
|---|
| 459 | * copy_siginfo_to_user32() code below needs to updated | 
|---|
| 460 | * along with the size in the CHECK_SI_SIZE(). | 
|---|
| 461 | * | 
|---|
| 462 | * We repeat this check for both the generic and compat | 
|---|
| 463 | * siginfos. | 
|---|
| 464 | * | 
|---|
| 465 | * Note: it is OK for these to grow as long as the whole | 
|---|
| 466 | * structure stays within the padding size (checked | 
|---|
| 467 | * above). | 
|---|
| 468 | */ | 
|---|
| 469 |  | 
|---|
| 470 | #define CHECK_SI_OFFSET(name)						\ | 
|---|
| 471 | static_assert(offsetof(siginfo32_t, _sifields) ==		\ | 
|---|
| 472 | offsetof(siginfo32_t, _sifields.name)) | 
|---|
| 473 |  | 
|---|
| 474 | #define CHECK_SI_SIZE(name, size)					\ | 
|---|
| 475 | static_assert(sizeof_field(siginfo32_t, _sifields.name) == size) | 
|---|
| 476 |  | 
|---|
| 477 | CHECK_SI_OFFSET(_kill); | 
|---|
| 478 | CHECK_SI_SIZE  (_kill, 2*sizeof(int)); | 
|---|
| 479 | static_assert(offsetof(siginfo32_t, si_pid) == 0xC); | 
|---|
| 480 | static_assert(offsetof(siginfo32_t, si_uid) == 0x10); | 
|---|
| 481 |  | 
|---|
| 482 | CHECK_SI_OFFSET(_timer); | 
|---|
| 483 | #ifdef CONFIG_COMPAT | 
|---|
| 484 | /* compat_siginfo_t doesn't have si_sys_private */ | 
|---|
| 485 | CHECK_SI_SIZE  (_timer, 3*sizeof(int)); | 
|---|
| 486 | #else | 
|---|
| 487 | CHECK_SI_SIZE  (_timer, 4*sizeof(int)); | 
|---|
| 488 | #endif | 
|---|
| 489 | static_assert(offsetof(siginfo32_t, si_tid)     == 0x0C); | 
|---|
| 490 | static_assert(offsetof(siginfo32_t, si_overrun) == 0x10); | 
|---|
| 491 | static_assert(offsetof(siginfo32_t, si_value)   == 0x14); | 
|---|
| 492 |  | 
|---|
| 493 | CHECK_SI_OFFSET(_rt); | 
|---|
| 494 | CHECK_SI_SIZE  (_rt, 3*sizeof(int)); | 
|---|
| 495 | static_assert(offsetof(siginfo32_t, si_pid)   == 0x0C); | 
|---|
| 496 | static_assert(offsetof(siginfo32_t, si_uid)   == 0x10); | 
|---|
| 497 | static_assert(offsetof(siginfo32_t, si_value) == 0x14); | 
|---|
| 498 |  | 
|---|
| 499 | CHECK_SI_OFFSET(_sigchld); | 
|---|
| 500 | CHECK_SI_SIZE  (_sigchld, 5*sizeof(int)); | 
|---|
| 501 | static_assert(offsetof(siginfo32_t, si_pid)    == 0x0C); | 
|---|
| 502 | static_assert(offsetof(siginfo32_t, si_uid)    == 0x10); | 
|---|
| 503 | static_assert(offsetof(siginfo32_t, si_status) == 0x14); | 
|---|
| 504 | static_assert(offsetof(siginfo32_t, si_utime)  == 0x18); | 
|---|
| 505 | static_assert(offsetof(siginfo32_t, si_stime)  == 0x1C); | 
|---|
| 506 |  | 
|---|
| 507 | CHECK_SI_OFFSET(_sigfault); | 
|---|
| 508 | CHECK_SI_SIZE  (_sigfault, 4*sizeof(int)); | 
|---|
| 509 | static_assert(offsetof(siginfo32_t, si_addr) == 0x0C); | 
|---|
| 510 |  | 
|---|
| 511 | static_assert(offsetof(siginfo32_t, si_trapno) == 0x10); | 
|---|
| 512 |  | 
|---|
| 513 | static_assert(offsetof(siginfo32_t, si_addr_lsb) == 0x10); | 
|---|
| 514 |  | 
|---|
| 515 | static_assert(offsetof(siginfo32_t, si_lower) == 0x14); | 
|---|
| 516 | static_assert(offsetof(siginfo32_t, si_upper) == 0x18); | 
|---|
| 517 |  | 
|---|
| 518 | static_assert(offsetof(siginfo32_t, si_pkey) == 0x14); | 
|---|
| 519 |  | 
|---|
| 520 | static_assert(offsetof(siginfo32_t, si_perf_data) == 0x10); | 
|---|
| 521 | static_assert(offsetof(siginfo32_t, si_perf_type) == 0x14); | 
|---|
| 522 | static_assert(offsetof(siginfo32_t, si_perf_flags) == 0x18); | 
|---|
| 523 |  | 
|---|
| 524 | CHECK_SI_OFFSET(_sigpoll); | 
|---|
| 525 | CHECK_SI_SIZE  (_sigpoll, 2*sizeof(int)); | 
|---|
| 526 | static_assert(offsetof(siginfo32_t, si_band) == 0x0C); | 
|---|
| 527 | static_assert(offsetof(siginfo32_t, si_fd)   == 0x10); | 
|---|
| 528 |  | 
|---|
| 529 | CHECK_SI_OFFSET(_sigsys); | 
|---|
| 530 | CHECK_SI_SIZE  (_sigsys, 3*sizeof(int)); | 
|---|
| 531 | static_assert(offsetof(siginfo32_t, si_call_addr) == 0x0C); | 
|---|
| 532 | static_assert(offsetof(siginfo32_t, si_syscall)   == 0x10); | 
|---|
| 533 | static_assert(offsetof(siginfo32_t, si_arch)      == 0x14); | 
|---|
| 534 |  | 
|---|
| 535 | /* any new si_fields should be added here */ | 
|---|
| 536 |  | 
|---|