From: Ingo Molnar <mingo@kernel.org>
To: Linus Torvalds <torvalds@linux-foundation.org>,
Neil Brown <neilb@suse.de>, Evgeniy Polyakov <zbr@ioremap.net>,
Stephen Smalley <sds@tycho.nsa.gov>
Cc: Alex Williamson <alex.williamson@redhat.com>,
Oleg Nesterov <oleg@redhat.com>,
linux-kernel <linux-kernel@vger.kernel.org>,
kvm <kvm@vger.kernel.org>
Subject: [PATCH] signals: Generate warning when flush_signals() is called from non-kthread context
Date: Fri, 1 May 2015 21:38:13 +0200 [thread overview]
Message-ID: <20150501193813.GA2812@gmail.com> (raw)
In-Reply-To: <CA+55aFziVpH1qyf8M+GdJxh3oJWd84pdJbo94kuMfSi1QscLew@mail.gmail.com>
* Linus Torvalds <torvalds@linux-foundation.org> wrote:
> On Fri, May 1, 2015 at 10:40 AM, Alex Williamson
> <alex.williamson@redhat.com> wrote:
> >
> > - Flush signals on interrupted wait to retain polling interval (Alex Williamson)
>
> This cannot *possibly* be right. If I read this patch right, you're
> randomly just getting rid of signals. No way in hell is that correct.
>
> "flush_signals()" is only for kernel threads, where it's a hacky
> alternative to actually handling them (since kernel threads never
> rreturn to user space and cannot really "handle" a signal). But you're
> doing it in the ->remove handler for the device, which can be called
> by arbitrary system processes. This is not a kernel thread thing, as
> far as I can see.
>
> If you cannot handle signals, you damn well shouldn't be using
> "wait_event_interruptible_timeout()" to begin with. Get rid of the
> "interruptible", since it apparently *isn't* interruptible.
>
> So I'm not pulling this.
>
> Now I'm worried that other drivers do insane things like this. I
> wonder if we should add some sanity test to flush_signals() to make
> sure that it can only ever get called from a kernel thread.
>
> Oleg?
So there are these uses:
triton:~/tip> git grep -lw flush_signals
arch/arm/common/bL_switcher.c
Looks safe: used within the bL_switcher_thread() kthread.
drivers/block/drbd/drbd_main.c
drivers/block/drbd/drbd_nl.c
drivers/block/drbd/drbd_receiver.c
drivers/block/drbd/drbd_worker.c
Couldn't convince myself it's safe, but it appears to be. (Call chains
are obfuscated in various ways that makes it hard to tell where a
given function execute.)
drivers/md/md.c
drivers/md/raid1.c
drivers/md/raid5.c
Hm, so I'm not super sure about the flush_signals() in
raid1.c:make_request() AFAICS we can do direct RAID1 writes in
raid1_unplug(). That looks unsafe ... I've Cc:-ed Neil.
raid5.c seems safe: raid5_unplug() doesn't create requests directly,
leaves it all for the mddev kthread.
drivers/scsi/bnx2fc/bnx2fc_fcoe.c
drivers/scsi/bnx2fc/bnx2fc_tgt.c
drivers/scsi/bnx2i/bnx2i_iscsi.c
drivers/scsi/libiscsi.c
drivers/target/iscsi/iscsi_target_login.c
drivers/target/iscsi/iscsi_target_nego.c
Couldn't fully check it due to excessive complexity, but seemed safe.
drivers/staging/rtl8188eu/core/rtw_cmd.c
drivers/staging/rtl8712/osdep_service.h
Looks safe: done in RTW_CMD_THREAD and 'padapter' kthreads.
drivers/w1/w1_family.c
drivers/w1/w1_int.c
Looks unsafe: called from various module exit handlers in:
drivers/w1/slaves/w1_bq27000.c
drivers/w1/slaves/w1_ds2406.c
drivers/w1/slaves/w1_ds2408.c
drivers/w1/slaves/w1_ds2413.c
drivers/w1/slaves/w1_ds2423.c
drivers/w1/slaves/w1_ds2431.c
drivers/w1/slaves/w1_ds2433.c
drivers/w1/slaves/w1_ds2760.c
drivers/w1/slaves/w1_ds2780.c
drivers/w1/slaves/w1_ds2781.c
drivers/w1/slaves/w1_ds28e04.c
drivers/w1/slaves/w1_smem.c
drivers/w1/slaves/w1_therm.c
which would be executed in rmmod context, losing signals.
Cc:-ed Evgeniy.
fs/lockd/svc.c
fs/nfs/callback.c
fs/nfsd/nfssvc.c
Looks safe: lockd, nfsd plus nfsv4.%u-svc kthreads.
kernel/locking/rtmutex-tester.c
Looks safe: used within a kthread.
include/linux/sched.h
kernel/signal.c
Both safe ;-)
I also found a __flush_signals() use in:
security/selinux/hooks.c
Now that's selinux_bprm_committed_creds(), apparently executed on
exec(). Also does stuff like:
memset(&itimer, 0, sizeof itimer);
for (i = 0; i < 3; i++)
do_setitimer(i, &itimer, NULL);
and unblocks signals as well:
sigemptyset(¤t->blocked);
but this appears to be kind of legit: the task failed to get the
required permissions, and guns go off.
In any case, it seems to me that the patch below would be justified?
Totally untested and so. __flush_signals() not affected.
Thanks,
Ingo
---
kernel/signal.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/kernel/signal.c b/kernel/signal.c
index d51c5ddd855c..100e30afe5d2 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -427,6 +427,10 @@ void flush_signals(struct task_struct *t)
{
unsigned long flags;
+ /* Only kthreads are allowed to destroy signals: */
+ if (WARN_ON_ONCE(!(current->flags & PF_KTHREAD)))
+ return;
+
spin_lock_irqsave(&t->sighand->siglock, flags);
__flush_signals(t);
spin_unlock_irqrestore(&t->sighand->siglock, flags);
next prev parent reply other threads:[~2015-05-01 19:38 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-01 17:40 [GIT PULL] VFIO fixes for v4.1-rc2 Alex Williamson
2015-05-01 18:37 ` Linus Torvalds
2015-05-01 18:48 ` Alex Williamson
2015-05-01 20:23 ` Linus Torvalds
2015-05-01 22:03 ` Alex Williamson
2015-05-01 19:38 ` Ingo Molnar [this message]
2015-05-02 8:30 ` [PATCH] signals: Generate warning when flush_signals() is called from non-kthread context NeilBrown
2015-05-02 16:27 ` Linus Torvalds
2015-05-07 12:54 ` Peter Zijlstra
2015-05-04 17:35 ` Oleg Nesterov
2015-05-07 13:33 ` Jiri Kosina
2015-05-07 22:37 ` NeilBrown
2015-05-02 11:56 ` Evgeniy Polyakov
2015-05-02 16:33 ` Richard Weinberger
2015-05-03 17:34 ` Oleg Nesterov
2015-05-04 16:45 ` [PATCH 0/1] signals: don't abuse __flush_signals() in selinux_bprm_committed_creds() Oleg Nesterov
2015-05-04 16:45 ` [PATCH 1/1] " Oleg Nesterov
2015-05-04 19:43 ` Paul Moore
2015-05-04 19:43 ` Paul Moore
2015-05-06 10:19 ` [PATCH] signals: Generate warning when flush_signals() is called from non-kthread context Ingo Molnar
2015-05-01 20:11 ` [GIT PULL] VFIO fixes for v4.1-rc2 Richard Weinberger
2015-05-01 21:09 ` Richard Weinberger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150501193813.GA2812@gmail.com \
--to=mingo@kernel.org \
--cc=alex.williamson@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=neilb@suse.de \
--cc=oleg@redhat.com \
--cc=sds@tycho.nsa.gov \
--cc=torvalds@linux-foundation.org \
--cc=zbr@ioremap.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.