Commit e2390741 authored by Al Viro's avatar Al Viro
Browse files

x86: ia32_setup_frame(): consolidate uaccess areas



Currently we have user_access block, followed by __put_user(),
deciding what the restorer will be and finally a put_user_try
block.

Moving the calculation of restorer first allows the rest
(actual copyout work) to coalesce into a single user_access block.

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 44a1d996
Loading
Loading
Loading
Loading
+12 −27
Original line number Diff line number Diff line
@@ -236,7 +236,6 @@ int ia32_setup_frame(int sig, struct ksignal *ksig,
{
	struct sigframe_ia32 __user *frame;
	void __user *restorer;
	int err = 0;
	void __user *fp = NULL;

	/* copy_to_user optimizes that into a single 8 byte store */
@@ -252,21 +251,6 @@ int ia32_setup_frame(int sig, struct ksignal *ksig,

	frame = get_sigframe(ksig, regs, sizeof(*frame), &fp);

	if (!access_ok(frame, sizeof(*frame)))
		return -EFAULT;

	if (__put_user(sig, &frame->sig))
		return -EFAULT;

	if (!user_access_begin(&frame->sc, sizeof(struct sigcontext_32)))
		return -EFAULT;

	unsafe_put_sigcontext32(&frame->sc, fp, regs, set, Efault);
	user_access_end();

	if (__put_user(set->sig[1], &frame->extramask[0]))
		return -EFAULT;

	if (ksig->ka.sa.sa_flags & SA_RESTORER) {
		restorer = ksig->ka.sa.sa_restorer;
	} else {
@@ -278,18 +262,19 @@ int ia32_setup_frame(int sig, struct ksignal *ksig,
			restorer = &frame->retcode;
	}

	put_user_try {
		put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
	if (!user_access_begin(frame, sizeof(*frame)))
		return -EFAULT;

	unsafe_put_user(sig, &frame->sig, Efault);
	unsafe_put_sigcontext32(&frame->sc, fp, regs, set, Efault);
	unsafe_put_user(set->sig[1], &frame->extramask[0], Efault);
	unsafe_put_user(ptr_to_compat(restorer), &frame->pretcode, Efault);
	/*
	 * These are actually not used anymore, but left because some
	 * gdb versions depend on them as a marker.
	 */
		put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
	} put_user_catch(err);

	if (err)
		return -EFAULT;
	unsafe_put_user(*((u64 *)&code), (u64 __user *)frame->retcode, Efault);
	user_access_end();

	/* Set up registers for signal handler */
	regs->sp = (unsigned long) frame;