History

signal: Implement force_fatal_sig

Add a simple helper force_fatal_sig that causes a signal to be delivered to a process as if the signal handler was set to SIG_DFL. Reimplement force_sigsegv based upon this new helper. This fixes force_sigsegv so that when it forces the default signal handler to be used the code now forces the signal to be unblocked as well. Reusing the tested logic in force_sig_info_to_task that was built for force_sig_seccomp this makes the implementation trivial. This is interesting both because it makes force_sigsegv simpler and because there are a couple of buggy places in the kernel that call do_exit(SIGILL) or do_exit(SIGSYS) because there is no straight forward way today for those places to simply force the exit of a process with the chosen signal. Creating force_fatal_sig allows those places to be implemented with normal signal exits.

Eric W. Biederman committed 5 years ago

Commit 26d5bad1 parent 111e7042 files · +18 −9Browse files

Showing the changes to kernel (1 of 2 files). Show all

Unified · Split

kernel/signal.c+17−9
@@ -1662,6 +1662,19 @@ void force_sig(int sig) · 1661 unmodified lines
16621662 }
16631663 EXPORT_SYMBOL(force_sig);
16641664
1665+void force_fatal_sig(int sig)
1666+{
1667+ struct kernel_siginfo info;
1668+
1669+ clear_siginfo(&info);
1670+ info.si_signo = sig;
1671+ info.si_errno = 0;
1672+ info.si_code = SI_KERNEL;
1673+ info.si_pid = 0;
1674+ info.si_uid = 0;
1675+ force_sig_info_to_task(&info, current, true);
1676+}
1677+
16651678 /*
16661679 * When things go south during signal handling, we
16671680 * will force a SIGSEGV. And if the signal that caused
@@ -1670,15 +1683,10 @@ EXPORT_SYMBOL(force_sig); · 2 unmodified lines
16701683 */
16711684 void force_sigsegv(int sig)
16721685 {
1673− struct task_struct *p = current;
1674−
1675− if (sig == SIGSEGV) {
1676− unsigned long flags;
1677− spin_lock_irqsave(&p->sighand->siglock, flags);
1678− p->sighand->action[sig - 1].sa.sa_handler = SIG_DFL;
1679− spin_unlock_irqrestore(&p->sighand->siglock, flags);
1680− }
1681− force_sig(SIGSEGV);
1686+ if (sig == SIGSEGV)
1687+ force_fatal_sig(SIGSEGV);
1688+ else
1689+ force_sig(SIGSEGV);
16821690 }
16831691
16841692 int force_sig_fault_to_task(int sig, int code, void __user *addr

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t