Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+22 -2
+2
drivers/block/drbd/drbd_main.c
··· 322 322 thi->name[0], 323 323 resource->name); 324 324 325 + allow_kernel_signal(DRBD_SIGKILL); 326 + allow_kernel_signal(SIGXCPU); 325 327 restart: 326 328 retval = thi->function(thi); 327 329
+1 -1
fs/cifs/connect.c
··· 1113 1113 mempool_resize(cifs_req_poolp, length + cifs_min_rcv); 1114 1114 1115 1115 set_freezable(); 1116 - allow_signal(SIGKILL); 1116 + allow_kernel_signal(SIGKILL); 1117 1117 while (server->tcpStatus != CifsExiting) { 1118 1118 if (try_to_freeze()) 1119 1119 continue;
+14 -1
include/linux/signal.h
··· 282 282 extern void exit_signals(struct task_struct *tsk); 283 283 extern void kernel_sigaction(int, __sighandler_t); 284 284 285 + #define SIG_KTHREAD ((__force __sighandler_t)2) 286 + #define SIG_KTHREAD_KERNEL ((__force __sighandler_t)3) 287 + 285 288 static inline void allow_signal(int sig) 286 289 { 287 290 /* ··· 292 289 * know it'll be handled, so that they don't get converted to 293 290 * SIGKILL or just silently dropped. 294 291 */ 295 - kernel_sigaction(sig, (__force __sighandler_t)2); 292 + kernel_sigaction(sig, SIG_KTHREAD); 293 + } 294 + 295 + static inline void allow_kernel_signal(int sig) 296 + { 297 + /* 298 + * Kernel threads handle their own signals. Let the signal code 299 + * know signals sent by the kernel will be handled, so that they 300 + * don't get silently dropped. 301 + */ 302 + kernel_sigaction(sig, SIG_KTHREAD_KERNEL); 296 303 } 297 304 298 305 static inline void disallow_signal(int sig)
+5
kernel/signal.c
··· 90 90 handler == SIG_DFL && !(force && sig_kernel_only(sig))) 91 91 return true; 92 92 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 + 93 98 return sig_handler_ignored(handler, sig); 94 99 } 95 100