History

Merge branch 'siginfo-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace

Pull kernel thread signal handling fix from Eric Biederman: "I overlooked the fact that kernel threads are created with all signals set to SIG_IGN, and accidentally caused a regression in cifs and drbd when replacing force_sig with send_sig. This is my fix for that regression. I add a new function allow_kernel_signal which allows kernel threads to receive signals sent from the kernel, but continues to ignore all signals sent from userspace. This ensures the user space interface for cifs and drbd remain the same. These kernel threads depend on blocking networking calls which block until something is received or a signal is pending. Making receiving of signals somewhat necessary for these kernel threads. Perhaps someday we can cleanup those interfaces and remove allow_kernel_signal. If not allow_kernel_signal is pretty trivial and clearly documents what is going on so I don't think we will mind carrying it" * 'siginfo-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: signal: Allow cifs and drbd to receive their terminating signals

Linus Torvalds committed 7 years ago

Commit 287c55e2 parents 0682150 33da8e74 files · +22 −2Browse files

Unified · Split

4 files
  1. drivers/block/drbd/drbd_main.c +2 −0
  2. fs/cifs/connect.c +1 −1
  3. include/linux/signal.h +14 −1
  4. kernel/signal.c +5 −0
drivers/block/drbd/drbd_main.c+2−0
@@ -322,6 +322,8 @@ static int drbd_thread_setup(void *arg) · 321 unmodified lines
322322 thi->name[0],
323323 resource->name);
324324
325+ allow_kernel_signal(DRBD_SIGKILL);
326+ allow_kernel_signal(SIGXCPU);
325327 restart:
326328 retval = thi->function(thi);
327329
fs/cifs/connect.c+1−1
@@ -1113,7 +1113,7 @@ cifs_demultiplex_thread(void *p) · 1112 unmodified lines
11131113 mempool_resize(cifs_req_poolp, length + cifs_min_rcv);
11141114
11151115 set_freezable();
1116− allow_signal(SIGKILL);
1116+ allow_kernel_signal(SIGKILL);
11171117 while (server->tcpStatus != CifsExiting) {
11181118 if (try_to_freeze())
11191119 continue;
include/linux/signal.h+14−1
@@ -282,6 +282,9 @@ extern void signal_setup_done(int failed, struct ksignal *ksig, int stepping); · 281 unmodified lines
282282 extern void exit_signals(struct task_struct *tsk);
283283 extern void kernel_sigaction(int, __sighandler_t);
284284
285+#define SIG_KTHREAD ((__force __sighandler_t)2)
286+#define SIG_KTHREAD_KERNEL ((__force __sighandler_t)3)
287+
285288 static inline void allow_signal(int sig)
286289 {
287290 /*
@@ -289,7 +292,17 @@ static inline void allow_signal(int sig) · 1 unmodified line
289292 * know it'll be handled, so that they don't get converted to
290293 * SIGKILL or just silently dropped.
291294 */
292− kernel_sigaction(sig, (__force __sighandler_t)2);
295+ kernel_sigaction(sig, SIG_KTHREAD);
296+}
297+
298+static inline void allow_kernel_signal(int sig)
299+{
300+ /*
301+ * Kernel threads handle their own signals. Let the signal code
302+ * know signals sent by the kernel will be handled, so that they
303+ * don't get silently dropped.
304+ */
305+ kernel_sigaction(sig, SIG_KTHREAD_KERNEL);
293306 }
294307
295308 static inline void disallow_signal(int sig)
kernel/signal.c+5−0
@@ -90,6 +90,11 @@ static bool sig_task_ignored(struct task_struct *t, int sig, bool force) · 89 unmodified lines
9090 handler == SIG_DFL && !(force && sig_kernel_only(sig)))
9191 return true;
9292
93+ /* Only allow kernel generated signals to this kthread */
94+ if (unlikely((t->flags & PF_KTHREAD) &&
95+ (handler == SIG_KTHREAD_KERNEL) && !force))
96+ return true;
97+
9398 return sig_handler_ignored(handler, sig);
9499 }
95100

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