Commit 9026843952adac5b123c7b8dc961e5c15828d9e1

Authored by Al Viro
1 parent 6bf9adfc90

generic compat_sys_sigaltstack()

Again, conditional on CONFIG_GENERIC_SIGALTSTACK

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 10 changed files with 67 additions and 67 deletions Side-by-side Diff

arch/x86/ia32/ia32_signal.c
... ... @@ -136,52 +136,6 @@
136 136 return sigsuspend(&blocked);
137 137 }
138 138  
139   -asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
140   - stack_ia32_t __user *uoss_ptr,
141   - struct pt_regs *regs)
142   -{
143   - stack_t uss, uoss;
144   - int ret, err = 0;
145   - mm_segment_t seg;
146   -
147   - if (uss_ptr) {
148   - u32 ptr;
149   -
150   - memset(&uss, 0, sizeof(stack_t));
151   - if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)))
152   - return -EFAULT;
153   -
154   - get_user_try {
155   - get_user_ex(ptr, &uss_ptr->ss_sp);
156   - get_user_ex(uss.ss_flags, &uss_ptr->ss_flags);
157   - get_user_ex(uss.ss_size, &uss_ptr->ss_size);
158   - } get_user_catch(err);
159   -
160   - if (err)
161   - return -EFAULT;
162   - uss.ss_sp = compat_ptr(ptr);
163   - }
164   - seg = get_fs();
165   - set_fs(KERNEL_DS);
166   - ret = do_sigaltstack((stack_t __force __user *) (uss_ptr ? &uss : NULL),
167   - (stack_t __force __user *) &uoss, regs->sp);
168   - set_fs(seg);
169   - if (ret >= 0 && uoss_ptr) {
170   - if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)))
171   - return -EFAULT;
172   -
173   - put_user_try {
174   - put_user_ex(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp);
175   - put_user_ex(uoss.ss_flags, &uoss_ptr->ss_flags);
176   - put_user_ex(uoss.ss_size, &uoss_ptr->ss_size);
177   - } put_user_catch(err);
178   -
179   - if (err)
180   - ret = -EFAULT;
181   - }
182   - return ret;
183   -}
184   -
185 139 /*
186 140 * Do a signal return; undo the signal stack.
187 141 */
... ... @@ -292,7 +246,6 @@
292 246 struct rt_sigframe_ia32 __user *frame;
293 247 sigset_t set;
294 248 unsigned int ax;
295   - struct pt_regs tregs;
296 249  
297 250 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
298 251  
... ... @@ -306,8 +259,7 @@
306 259 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
307 260 goto badframe;
308 261  
309   - tregs = *regs;
310   - if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
  262 + if (compat_restore_altstack(&frame->uc.uc_stack))
311 263 goto badframe;
312 264  
313 265 return ax;
arch/x86/ia32/ia32entry.S
... ... @@ -464,7 +464,6 @@
464 464  
465 465 PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn, %rdi
466 466 PTREGSCALL stub32_sigreturn, sys32_sigreturn, %rdi
467   - PTREGSCALL stub32_sigaltstack, sys32_sigaltstack, %rdx
468 467 PTREGSCALL stub32_execve, compat_sys_execve, %rcx
469 468 PTREGSCALL stub32_fork, sys_fork, %rdi
470 469 PTREGSCALL stub32_vfork, sys_vfork, %rdi
arch/x86/include/asm/ia32.h
... ... @@ -29,16 +29,10 @@
29 29 unsigned int sa_restorer; /* Another 32 bit pointer */
30 30 };
31 31  
32   -typedef struct sigaltstack_ia32 {
33   - unsigned int ss_sp;
34   - int ss_flags;
35   - unsigned int ss_size;
36   -} stack_ia32_t;
37   -
38 32 struct ucontext_ia32 {
39 33 unsigned int uc_flags;
40 34 unsigned int uc_link;
41   - stack_ia32_t uc_stack;
  35 + compat_stack_t uc_stack;
42 36 struct sigcontext_ia32 uc_mcontext;
43 37 compat_sigset_t uc_sigmask; /* mask last for extensibility */
44 38 };
... ... @@ -46,7 +40,7 @@
46 40 struct ucontext_x32 {
47 41 unsigned int uc_flags;
48 42 unsigned int uc_link;
49   - stack_ia32_t uc_stack;
  43 + compat_stack_t uc_stack;
50 44 unsigned int uc__pad0; /* needed for alignment */
51 45 struct sigcontext uc_mcontext; /* the 64-bit sigcontext type */
52 46 compat_sigset_t uc_sigmask; /* mask last for extensibility */
arch/x86/include/asm/sys_ia32.h
... ... @@ -69,8 +69,6 @@
69 69  
70 70 /* ia32/ia32_signal.c */
71 71 asmlinkage long sys32_sigsuspend(int, int, old_sigset_t);
72   -asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *,
73   - stack_ia32_t __user *, struct pt_regs *);
74 72 asmlinkage long sys32_sigreturn(struct pt_regs *);
75 73 asmlinkage long sys32_rt_sigreturn(struct pt_regs *);
76 74  
arch/x86/kernel/entry_64.S
... ... @@ -912,8 +912,6 @@
912 912 END(stub_rt_sigreturn)
913 913  
914 914 #ifdef CONFIG_X86_X32_ABI
915   - PTREGSCALL stub_x32_sigaltstack, sys32_sigaltstack, %rdx
916   -
917 915 ENTRY(stub_x32_rt_sigreturn)
918 916 CFI_STARTPROC
919 917 addq $8, %rsp
arch/x86/kernel/signal.c
... ... @@ -857,7 +857,6 @@
857 857 struct rt_sigframe_x32 __user *frame;
858 858 sigset_t set;
859 859 unsigned long ax;
860   - struct pt_regs tregs;
861 860  
862 861 frame = (struct rt_sigframe_x32 __user *)(regs->sp - 8);
863 862  
... ... @@ -871,8 +870,7 @@
871 870 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
872 871 goto badframe;
873 872  
874   - tregs = *regs;
875   - if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
  873 + if (compat_restore_altstack(&frame->uc.uc_stack))
876 874 goto badframe;
877 875  
878 876 return ax;
arch/x86/syscalls/syscall_32.tbl
... ... @@ -192,7 +192,7 @@
192 192 183 i386 getcwd sys_getcwd
193 193 184 i386 capget sys_capget
194 194 185 i386 capset sys_capset
195   -186 i386 sigaltstack sys_sigaltstack stub32_sigaltstack
  195 +186 i386 sigaltstack sys_sigaltstack compat_sys_sigaltstack
196 196 187 i386 sendfile sys_sendfile sys32_sendfile
197 197 188 i386 getpmsg
198 198 189 i386 putpmsg
arch/x86/syscalls/syscall_64.tbl
... ... @@ -337,7 +337,7 @@
337 337 522 x32 rt_sigpending sys32_rt_sigpending
338 338 523 x32 rt_sigtimedwait compat_sys_rt_sigtimedwait
339 339 524 x32 rt_sigqueueinfo sys32_rt_sigqueueinfo
340   -525 x32 sigaltstack stub_x32_sigaltstack
  340 +525 x32 sigaltstack compat_sys_sigaltstack
341 341 526 x32 timer_create compat_sys_timer_create
342 342 527 x32 mq_notify compat_sys_mq_notify
343 343 528 x32 kexec_load compat_sys_kexec_load
include/linux/compat.h
... ... @@ -68,6 +68,16 @@
68 68 #ifndef compat_user_stack_pointer
69 69 #define compat_user_stack_pointer() current_user_stack_pointer()
70 70 #endif
  71 +#ifdef CONFIG_GENERIC_SIGALTSTACK
  72 +#ifndef compat_sigaltstack /* we'll need that for MIPS */
  73 +typedef struct compat_sigaltstack {
  74 + compat_uptr_t ss_sp;
  75 + int ss_flags;
  76 + compat_size_t ss_size;
  77 +} compat_stack_t;
  78 +#endif
  79 +#endif
  80 +
71 81 #define compat_jiffies_to_clock_t(x) \
72 82 (((unsigned long)(x) * COMPAT_USER_HZ) / HZ)
73 83  
... ... @@ -632,6 +642,12 @@
632 642  
633 643 asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,
634 644 compat_off_t __user *offset, compat_size_t count);
  645 +#ifdef CONFIG_GENERIC_SIGALTSTACK
  646 +asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr,
  647 + compat_stack_t __user *uoss_ptr);
  648 +
  649 +int compat_restore_altstack(const compat_stack_t __user *uss);
  650 +#endif
635 651  
636 652 #else
637 653  
... ... @@ -31,6 +31,7 @@
31 31 #include <linux/nsproxy.h>
32 32 #include <linux/user_namespace.h>
33 33 #include <linux/uprobes.h>
  34 +#include <linux/compat.h>
34 35 #define CREATE_TRACE_POINTS
35 36 #include <trace/events/signal.h>
36 37  
... ... @@ -3115,6 +3116,50 @@
3115 3116 /* squash all but EFAULT for now */
3116 3117 return err == -EFAULT ? err : 0;
3117 3118 }
  3119 +
  3120 +#ifdef CONFIG_COMPAT
  3121 +#ifdef CONFIG_GENERIC_SIGALTSTACK
  3122 +asmlinkage long compat_sys_sigaltstack(const compat_stack_t __user *uss_ptr,
  3123 + compat_stack_t __user *uoss_ptr)
  3124 +{
  3125 + stack_t uss, uoss;
  3126 + int ret;
  3127 + mm_segment_t seg;
  3128 +
  3129 + if (uss_ptr) {
  3130 + compat_stack_t uss32;
  3131 +
  3132 + memset(&uss, 0, sizeof(stack_t));
  3133 + if (copy_from_user(&uss32, uss_ptr, sizeof(compat_stack_t)))
  3134 + return -EFAULT;
  3135 + uss.ss_sp = compat_ptr(uss32.ss_sp);
  3136 + uss.ss_flags = uss32.ss_flags;
  3137 + uss.ss_size = uss32.ss_size;
  3138 + }
  3139 + seg = get_fs();
  3140 + set_fs(KERNEL_DS);
  3141 + ret = do_sigaltstack((stack_t __force __user *) (uss_ptr ? &uss : NULL),
  3142 + (stack_t __force __user *) &uoss,
  3143 + compat_user_stack_pointer());
  3144 + set_fs(seg);
  3145 + if (ret >= 0 && uoss_ptr) {
  3146 + if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(compat_stack_t)) ||
  3147 + __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) ||
  3148 + __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
  3149 + __put_user(uoss.ss_size, &uoss_ptr->ss_size))
  3150 + ret = -EFAULT;
  3151 + }
  3152 + return ret;
  3153 +}
  3154 +
  3155 +int compat_restore_altstack(const compat_stack_t __user *uss)
  3156 +{
  3157 + int err = compat_sys_sigaltstack(uss, NULL);
  3158 + /* squash all but -EFAULT for now */
  3159 + return err == -EFAULT ? err : 0;
  3160 +}
  3161 +#endif
  3162 +#endif
3118 3163  
3119 3164 #ifdef __ARCH_WANT_SYS_SIGPENDING
3120 3165