Commit 9026843952adac5b123c7b8dc961e5c15828d9e1
1 parent
6bf9adfc90
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
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
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 |
kernel/signal.c
... | ... | @@ -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 |