
The comment in the signal code says that apps can save/restore other segments on their own. It's true that apps can *save* SS on their own, but there's no way for apps to restore it: SYSCALL effectively resets SS to __USER_DS, so any value that user code tries to load into SS gets lost on entry to sigreturn. This recycles two padding bytes in the segment selector area for SS. While we're at it, we need a second change to make this useful. If the signal we're delivering is caused by a bad SS value, saving that value isn't enough. We need to remove that bad value from the regs before we try to deliver the signal. Oddly, the i386 code already got this right. I suspect that 64-bit programs that try to run 16-bit code and use signals will have a lot of trouble without this. Signed-off-by: Andy Lutomirski <luto@amacapital.net> Reviewed-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Borislav Petkov <bp@suse.de> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/405594361340a2ec32f8e2b115c142df0e180d8e.1426193719.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
79 lines
1.9 KiB
C
79 lines
1.9 KiB
C
#ifndef _ASM_X86_SIGCONTEXT_H
|
|
#define _ASM_X86_SIGCONTEXT_H
|
|
|
|
#include <uapi/asm/sigcontext.h>
|
|
|
|
#ifdef __i386__
|
|
struct sigcontext {
|
|
unsigned short gs, __gsh;
|
|
unsigned short fs, __fsh;
|
|
unsigned short es, __esh;
|
|
unsigned short ds, __dsh;
|
|
unsigned long di;
|
|
unsigned long si;
|
|
unsigned long bp;
|
|
unsigned long sp;
|
|
unsigned long bx;
|
|
unsigned long dx;
|
|
unsigned long cx;
|
|
unsigned long ax;
|
|
unsigned long trapno;
|
|
unsigned long err;
|
|
unsigned long ip;
|
|
unsigned short cs, __csh;
|
|
unsigned long flags;
|
|
unsigned long sp_at_signal;
|
|
unsigned short ss, __ssh;
|
|
|
|
/*
|
|
* fpstate is really (struct _fpstate *) or (struct _xstate *)
|
|
* depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
|
|
* bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
|
|
* of extended memory layout. See comments at the definition of
|
|
* (struct _fpx_sw_bytes)
|
|
*/
|
|
void __user *fpstate; /* zero when no FPU/extended context */
|
|
unsigned long oldmask;
|
|
unsigned long cr2;
|
|
};
|
|
#else /* __i386__ */
|
|
struct sigcontext {
|
|
unsigned long r8;
|
|
unsigned long r9;
|
|
unsigned long r10;
|
|
unsigned long r11;
|
|
unsigned long r12;
|
|
unsigned long r13;
|
|
unsigned long r14;
|
|
unsigned long r15;
|
|
unsigned long di;
|
|
unsigned long si;
|
|
unsigned long bp;
|
|
unsigned long bx;
|
|
unsigned long dx;
|
|
unsigned long ax;
|
|
unsigned long cx;
|
|
unsigned long sp;
|
|
unsigned long ip;
|
|
unsigned long flags;
|
|
unsigned short cs;
|
|
unsigned short gs;
|
|
unsigned short fs;
|
|
unsigned short ss;
|
|
unsigned long err;
|
|
unsigned long trapno;
|
|
unsigned long oldmask;
|
|
unsigned long cr2;
|
|
|
|
/*
|
|
* fpstate is really (struct _fpstate *) or (struct _xstate *)
|
|
* depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
|
|
* bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
|
|
* of extended memory layout. See comments at the definition of
|
|
* (struct _fpx_sw_bytes)
|
|
*/
|
|
void __user *fpstate; /* zero when no FPU/extended context */
|
|
unsigned long reserved1[8];
|
|
};
|
|
#endif /* !__i386__ */
|
|
#endif /* _ASM_X86_SIGCONTEXT_H */
|