Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bcb8c8d0 authored by Matt Fleming's avatar Matt Fleming Committed by Al Viro
Browse files

microblaze: fix signal masking



There are a couple of problems with the current signal code,

1. If we failed to setup the signal stack frame then we should not be
   masking any signals.

2. ka->sa.sa_mask is only added to the current blocked signals list if
   SA_NODEFER is set in ka->sa.sa_flags.  If we successfully setup the
   signal frame and are going to run the handler then we must honour
   sa_mask.

Acked-by: default avatarOleg Nesterov <oleg@redhat.com>
Acked-by: default avatarMichal Simek <monstr@monstr.eu>
Signed-off-by: default avatarMatt Fleming <matt.fleming@intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent a12c3694
Loading
Loading
Loading
Loading
+18 −13
Original line number Diff line number Diff line
@@ -169,7 +169,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
	return (void __user *)((sp - frame_size) & -8UL);
}

static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
			sigset_t *set, struct pt_regs *regs)
{
	struct rt_sigframe __user *frame;
@@ -267,10 +267,11 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
		current->comm, current->pid, frame, regs->pc);
#endif

	return;
	return 0;

give_sigsegv:
	force_sigsegv(sig, current);
	return -EFAULT;
}

/* Handle restarting system calls */
@@ -314,21 +315,25 @@ static int
handle_signal(unsigned long sig, struct k_sigaction *ka,
		siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
{
	int ret;

	/* Set up the stack frame */
	if (ka->sa.sa_flags & SA_SIGINFO)
		setup_rt_frame(sig, ka, info, oldset, regs);
		ret = setup_rt_frame(sig, ka, info, oldset, regs);
	else
		setup_rt_frame(sig, ka, NULL, oldset, regs);
		ret = setup_rt_frame(sig, ka, NULL, oldset, regs);

	if (ret)
		return ret;

	if (!(ka->sa.sa_flags & SA_NODEFER)) {
	spin_lock_irq(&current->sighand->siglock);
		sigorsets(&current->blocked,
				&current->blocked, &ka->sa.sa_mask);
	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
	if (!(ka->sa.sa_flags & SA_NODEFER))
		sigaddset(&current->blocked, sig);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);
	}
	return 1;

	return 0;
}

/*
@@ -369,7 +374,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int in_syscall)
		/* Whee! Actually deliver the signal. */
		if (in_syscall)
			handle_restart(regs, &ka, 1);
		if (handle_signal(signr, &ka, &info, oldset, regs)) {
		if (!handle_signal(signr, &ka, &info, oldset, regs)) {
			/*
			 * A signal was successfully delivered; the saved
			 * sigmask will have been stored in the signal frame,