mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-18 03:06:43 +00:00
x86: get rid of put_user_try in __setup_rt_frame() (both 32bit and 64bit)
Straightforward, except for save_altstack_ex() stuck in those. Replace that thing with an analogue that would use unsafe_put_user() instead of put_user_ex() (called compat_save_altstack()) and be done with that. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
57d563c829
commit
119cd59fcf
@ -365,38 +365,37 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
|
|||||||
|
|
||||||
frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fpstate);
|
frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fpstate);
|
||||||
|
|
||||||
if (!access_ok(frame, sizeof(*frame)))
|
if (!user_access_begin(frame, sizeof(*frame)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
put_user_try {
|
unsafe_put_user(sig, &frame->sig, Efault);
|
||||||
put_user_ex(sig, &frame->sig);
|
unsafe_put_user(&frame->info, &frame->pinfo, Efault);
|
||||||
put_user_ex(&frame->info, &frame->pinfo);
|
unsafe_put_user(&frame->uc, &frame->puc, Efault);
|
||||||
put_user_ex(&frame->uc, &frame->puc);
|
|
||||||
|
|
||||||
/* Create the ucontext. */
|
/* Create the ucontext. */
|
||||||
if (static_cpu_has(X86_FEATURE_XSAVE))
|
if (static_cpu_has(X86_FEATURE_XSAVE))
|
||||||
put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
|
unsafe_put_user(UC_FP_XSTATE, &frame->uc.uc_flags, Efault);
|
||||||
else
|
else
|
||||||
put_user_ex(0, &frame->uc.uc_flags);
|
unsafe_put_user(0, &frame->uc.uc_flags, Efault);
|
||||||
put_user_ex(0, &frame->uc.uc_link);
|
unsafe_put_user(0, &frame->uc.uc_link, Efault);
|
||||||
save_altstack_ex(&frame->uc.uc_stack, regs->sp);
|
unsafe_save_altstack(&frame->uc.uc_stack, regs->sp, Efault);
|
||||||
|
|
||||||
/* Set up to return from userspace. */
|
/* Set up to return from userspace. */
|
||||||
restorer = current->mm->context.vdso +
|
restorer = current->mm->context.vdso +
|
||||||
vdso_image_32.sym___kernel_rt_sigreturn;
|
vdso_image_32.sym___kernel_rt_sigreturn;
|
||||||
if (ksig->ka.sa.sa_flags & SA_RESTORER)
|
if (ksig->ka.sa.sa_flags & SA_RESTORER)
|
||||||
restorer = ksig->ka.sa.sa_restorer;
|
restorer = ksig->ka.sa.sa_restorer;
|
||||||
put_user_ex(restorer, &frame->pretcode);
|
unsafe_put_user(restorer, &frame->pretcode, Efault);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is movl $__NR_rt_sigreturn, %ax ; int $0x80
|
* This is movl $__NR_rt_sigreturn, %ax ; int $0x80
|
||||||
*
|
*
|
||||||
* WE DO NOT USE IT ANY MORE! It's only left here for historical
|
* WE DO NOT USE IT ANY MORE! It's only left here for historical
|
||||||
* reasons and because gdb uses it as a signature to notice
|
* reasons and because gdb uses it as a signature to notice
|
||||||
* signal handler stack frames.
|
* signal handler stack frames.
|
||||||
*/
|
*/
|
||||||
put_user_ex(*((u64 *)&rt_retcode), (u64 *)frame->retcode);
|
unsafe_put_user(*((u64 *)&rt_retcode), (u64 *)frame->retcode, Efault);
|
||||||
} put_user_catch(err);
|
user_access_end();
|
||||||
|
|
||||||
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
|
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
|
||||||
err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
|
err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
|
||||||
@ -419,6 +418,9 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
|
|||||||
regs->cs = __USER_CS;
|
regs->cs = __USER_CS;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Efault:
|
||||||
|
user_access_end();
|
||||||
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
#else /* !CONFIG_X86_32 */
|
#else /* !CONFIG_X86_32 */
|
||||||
static unsigned long frame_uc_flags(struct pt_regs *regs)
|
static unsigned long frame_uc_flags(struct pt_regs *regs)
|
||||||
@ -444,6 +446,10 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
|
|||||||
unsigned long uc_flags;
|
unsigned long uc_flags;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
/* x86-64 should always use SA_RESTORER. */
|
||||||
|
if (!(ksig->ka.sa.sa_flags & SA_RESTORER))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
frame = get_sigframe(&ksig->ka, regs, sizeof(struct rt_sigframe), &fp);
|
frame = get_sigframe(&ksig->ka, regs, sizeof(struct rt_sigframe), &fp);
|
||||||
|
|
||||||
if (!access_ok(frame, sizeof(*frame)))
|
if (!access_ok(frame, sizeof(*frame)))
|
||||||
@ -455,23 +461,18 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uc_flags = frame_uc_flags(regs);
|
uc_flags = frame_uc_flags(regs);
|
||||||
|
if (!user_access_begin(frame, sizeof(*frame)))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
put_user_try {
|
/* Create the ucontext. */
|
||||||
/* Create the ucontext. */
|
unsafe_put_user(uc_flags, &frame->uc.uc_flags, Efault);
|
||||||
put_user_ex(uc_flags, &frame->uc.uc_flags);
|
unsafe_put_user(0, &frame->uc.uc_link, Efault);
|
||||||
put_user_ex(0, &frame->uc.uc_link);
|
unsafe_save_altstack(&frame->uc.uc_stack, regs->sp, Efault);
|
||||||
save_altstack_ex(&frame->uc.uc_stack, regs->sp);
|
|
||||||
|
|
||||||
/* Set up to return from userspace. If provided, use a stub
|
/* Set up to return from userspace. If provided, use a stub
|
||||||
already in userspace. */
|
already in userspace. */
|
||||||
/* x86-64 should always use SA_RESTORER. */
|
unsafe_put_user(ksig->ka.sa.sa_restorer, &frame->pretcode, Efault);
|
||||||
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
|
user_access_end();
|
||||||
put_user_ex(ksig->ka.sa.sa_restorer, &frame->pretcode);
|
|
||||||
} else {
|
|
||||||
/* could use a vstub here */
|
|
||||||
err |= -EFAULT;
|
|
||||||
}
|
|
||||||
} put_user_catch(err);
|
|
||||||
|
|
||||||
err |= setup_sigcontext(&frame->uc.uc_mcontext, fp, regs, set->sig[0]);
|
err |= setup_sigcontext(&frame->uc.uc_mcontext, fp, regs, set->sig[0]);
|
||||||
err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
|
err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
|
||||||
@ -515,6 +516,10 @@ static int __setup_rt_frame(int sig, struct ksignal *ksig,
|
|||||||
force_valid_ss(regs);
|
force_valid_ss(regs);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
Efault:
|
||||||
|
user_access_end();
|
||||||
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_X86_32 */
|
#endif /* CONFIG_X86_32 */
|
||||||
|
|
||||||
|
@ -444,12 +444,12 @@ void signals_init(void);
|
|||||||
int restore_altstack(const stack_t __user *);
|
int restore_altstack(const stack_t __user *);
|
||||||
int __save_altstack(stack_t __user *, unsigned long);
|
int __save_altstack(stack_t __user *, unsigned long);
|
||||||
|
|
||||||
#define save_altstack_ex(uss, sp) do { \
|
#define unsafe_save_altstack(uss, sp, label) do { \
|
||||||
stack_t __user *__uss = uss; \
|
stack_t __user *__uss = uss; \
|
||||||
struct task_struct *t = current; \
|
struct task_struct *t = current; \
|
||||||
put_user_ex((void __user *)t->sas_ss_sp, &__uss->ss_sp); \
|
unsafe_put_user((void __user *)t->sas_ss_sp, &__uss->ss_sp, label); \
|
||||||
put_user_ex(t->sas_ss_flags, &__uss->ss_flags); \
|
unsafe_put_user(t->sas_ss_flags, &__uss->ss_flags, label); \
|
||||||
put_user_ex(t->sas_ss_size, &__uss->ss_size); \
|
unsafe_put_user(t->sas_ss_size, &__uss->ss_size, label); \
|
||||||
if (t->sas_ss_flags & SS_AUTODISARM) \
|
if (t->sas_ss_flags & SS_AUTODISARM) \
|
||||||
sas_ss_reset(t); \
|
sas_ss_reset(t); \
|
||||||
} while (0);
|
} while (0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user