All of lore.kernel.org
 help / color / mirror / Atom feed
From: Al Viro <viro@ZenIV.linux.org.uk>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Oleg Nesterov <oleg@redhat.com>,
	linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org,
	Russell King <linux@arm.linux.org.uk>, Tejun Heo <tj@kernel.org>,
	Arnd Bergmann <arnd@arndb.de>
Subject: Re: [RFC] TIF_NOTIFY_RESUME, arch/*/*/*signal*.c and all such
Date: Wed, 25 Apr 2012 04:06:59 +0100	[thread overview]
Message-ID: <20120425030659.GE6871@ZenIV.linux.org.uk> (raw)
In-Reply-To: <20120424072617.GB6871@ZenIV.linux.org.uk>


> And then there's a lovely issue of what syscall restarts - both on multiple
> arriving signals (we want the restart to apply on the _first_ signal being
> processed, TYVM, since the rest of those signals are not interrupting
> a syscall - conceptually, they are interrupting the previous signal handlers
> at the point of entry) and on {rt_,}sigreturn(2) (where we might get a value
> in the register normally used to return sys_whatever() value that would look
> like one of restart-related special errors, except that it's simply what that
> register used to have when e.g. a timer interrupt had hit while we had a signal
> pending; hell to debug, since it looks e.g. like one register in userland
> process getting its value randomly replaced with -EINTR if it happened to
> contain -ERESTARTSYS when an interrupt had happened).  I'd fixed one like
> that on arm a couple of years ago, but AFAICS we still have several on
> other architectures ;-/

FWIW, there's an interesting question rmk has brought up.  Consider the
following scenario (on any architecture):
	sigsuspend(2) sees a signal and returns ERESTARTNOHAND.
	do_signal() is called and calls get_signal_to_deliver() and gets 0,
for whatever reason.
	We decide to restart, return address adjusted, syscall number
returned to the right register in pt_regs.  In the meanwhile, no matter what
state interrupts used to have before, get_signal_to_deliver() has enabled
them when returning, so we'll need to reload thread flags.  And we find that
another signal has arrived in the meanwhile.
	OK, do_signal() is called again, and this time we have a handler for
the arrived signal.  We form a stack frame and return to userland, into the
beginning of the handler.  We don't even look at the restart-related logics
this time around, due to the usual logics protecting us from double restarts.
	Handler is executed, up to rt_sigreturn(2).
	We decode the sigcontext, restore pt_regs and return to userland.
	Right into the beginning of interrupted sigsuspend()

So we have sigsuspend() hit by a signal we have a handler for.  Handler is
executed and we are stuck is sigsuspend() again, all because a signal without
a handler has arrived just before that one - close enough for our signal to
come right after get_signal_to_deliver() has returned zero to do_signal().

AFAICS, that's a clear bug.  Arrival of a signal that has userland handler
and that isn't blocked by the mask given to sigsuspend() should terminate
sigsuspend().  Sure, we can weasel around the wording in POSIX (it says
"sigsuspend() will return after the signal-catching function returns" without
explicitly saying that it shouldn't sit around waiting for another signals
to arrive), but it's obviously against the intent of standard (as well as
expectations of any programmer).  Note that if the handler-less signal had
arrived a bit earlier, we would've returned to userland and reenter the
kernel before the arrival of our signal.  Then it *would* terminate
sigsuspend() - handler would be executed and we would've returned to caller
of sigsuspend() with EINTR as return value.  If they came simultaneously,
the same thing would've happened - get_signal_to_deliver() would have
returned non-zero the first time around and that would be it.  It's just the
right timing for the second signal that triggers that race.

Solution proposed last summer when that had been noticed by arm folks was
more or less along the lines of
	* new thread flag, checked after we'd seen that no SIGPENDING et.al.
is there.  If it's set, we clear it, do syscall restart work as we would for
handlerless signal and recheck the flags if we had to do something like
__put_user() in process (arm might have to do that for ERESTART_RESTARTBLOCK)[1]
	* do_signal() would set that flag if
		+ anti double-restart logics would not have prevented
		  restarts
		+ error value was ERESTART_...
	* no restart work on "no signal" path in do_signal()
	* if we have a handler and the flag is set, clear it and do what
we normally do for restarts (including the "has ptrace mangled registers
in a way that would prevent restarts in the current code" logics for
architectures that have such logics - arm and sparc, at least).

I would've probably made that TS_... instead of TIF_... at least for something
like x86 - it's obviously thread-synchronous.

[1] it wasn't covered in that thread, but if a signal arrives during that
__put_user() we really won't care - the usual logics in sigreturn() will
make sure that when we return from handler into the resulting restart_syscall(2)
we'll have it immediately fail with -EINTR.

Comments?  AFAICS, the bug is arch-independent; it's not just arm and it's
worse than the example mentioned last year - sigsuspend() is a lot more
common than ppoll() and behaviour clearly goes against what sigsuspend()
exists for.

  reply	other threads:[~2012-04-25  3:07 UTC|newest]

Thread overview: 105+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-18 13:04 [PULL REQUEST] : ima-appraisal patches Mimi Zohar
2012-04-18 15:02 ` James Morris
2012-04-18 18:07   ` Mimi Zohar
2012-04-18 18:39     ` Al Viro
2012-04-18 20:56       ` Mimi Zohar
2012-04-19 19:57       ` Mimi Zohar
2012-04-20  0:43         ` [RFC] situation with fput() locking (was Re: [PULL REQUEST] : ima-appraisal patches) Al Viro
2012-04-20  2:31           ` Linus Torvalds
2012-04-20  2:31             ` Linus Torvalds
2012-04-20  2:54             ` Al Viro
2012-04-20  2:58               ` Linus Torvalds
2012-04-20  2:58                 ` Linus Torvalds
2012-04-20  8:09                 ` Al Viro
2012-04-20 15:56                   ` Linus Torvalds
2012-04-20 15:56                     ` Linus Torvalds
2012-04-20 16:08                     ` Al Viro
2012-04-20 16:42                       ` Al Viro
2012-04-20 17:21                         ` Linus Torvalds
2012-04-20 17:21                           ` Linus Torvalds
2012-04-20 18:07                           ` Al Viro
2012-04-23 18:01                             ` [RFC] TIF_NOTIFY_RESUME, arch/*/*/*signal*.c and all such Al Viro
2012-04-23 18:37                               ` Oleg Nesterov
2012-04-24  7:26                               ` Al Viro
2012-04-25  3:06                                 ` Al Viro [this message]
2012-04-25 12:37                                   ` Oleg Nesterov
2012-04-25 12:50                                     ` Al Viro
2012-04-25 13:03                                       ` Oleg Nesterov
2012-04-25 13:32                                         ` Oleg Nesterov
2012-04-25 13:32                                         ` Al Viro
2012-04-25 14:52                                           ` Oleg Nesterov
2012-04-25 15:46                                             ` Oleg Nesterov
2012-04-25 16:10                                               ` Al Viro
2012-04-25 17:02                                                 ` Oleg Nesterov
2012-04-25 17:51                                                   ` Al Viro
2012-04-26  7:15                                                     ` Martin Schwidefsky
2012-04-26  7:25                                                       ` David Miller
2012-04-26 13:52                                                       ` Oleg Nesterov
2012-04-26 14:31                                                         ` Martin Schwidefsky
2012-04-26 13:22                                                     ` Oleg Nesterov
2012-04-26 18:37                                 ` Oleg Nesterov
2012-04-26 23:19                                   ` Al Viro
2012-04-27 17:24                                     ` Oleg Nesterov
2012-04-27 17:54                                       ` Oleg Nesterov
2012-05-02 10:37                                         ` Matt Fleming
2012-05-02 14:14                                           ` Al Viro
2012-04-27 18:45                                       ` Al Viro
2012-04-27 19:14                                         ` Geert Uytterhoeven
2012-04-27 19:34                                           ` Al Viro
2012-04-29 22:51                                             ` Al Viro
2012-04-30  6:39                                               ` Greg Ungerer
2012-04-30  6:39                                                 ` Greg Ungerer
2012-04-27 19:42                                         ` Al Viro
2012-04-27 20:20                                         ` Roland McGrath
2012-04-27 21:12                                           ` Al Viro
2012-04-27 21:27                                             ` Roland McGrath
2012-04-27 23:15                                               ` Al Viro
2012-04-27 23:32                                                 ` Al Viro
2012-04-29  4:12                                                   ` Al Viro
2012-04-30  8:06                                                     ` Martin Schwidefsky
2012-04-27 23:50                                                 ` Al Viro
2012-04-28 18:51                                                   ` [PATCH] arch/tile: avoid calling do_signal() after fork from a kernel thread Chris Metcalf
2012-04-28 18:51                                                     ` Chris Metcalf
2012-04-28 20:55                                                     ` Al Viro
2012-04-28 21:46                                                       ` Chris Metcalf
2012-04-28 21:46                                                         ` Chris Metcalf
2012-04-29  0:55                                                         ` Al Viro
2012-04-28 18:51                                                           ` [PATCH v2] arch/tile: fix up some issues in calling do_work_pending() Chris Metcalf
2012-04-28 18:51                                                             ` Chris Metcalf
2012-04-29  3:49                                                           ` [PATCH] arch/tile: avoid calling do_signal() after fork from a kernel thread Chris Metcalf
2012-04-29  3:49                                                             ` Chris Metcalf
2012-04-28  2:42                                                 ` [RFC] TIF_NOTIFY_RESUME, arch/*/*/*signal*.c and all such Al Viro
2012-04-28  3:32                                                   ` Al Viro
2012-04-28  3:36                                                     ` Al Viro
2012-04-29 16:33                                                     ` Oleg Nesterov
2012-04-29 16:18                                                   ` Oleg Nesterov
2012-04-29 18:05                                                     ` Al Viro
2012-05-01  4:31                                                       ` Al Viro
2012-05-01  5:06                                                         ` Mike Frysinger
2012-05-01  5:52                                                           ` Al Viro
2012-05-02 17:24                                                             ` Al Viro
2012-05-02 18:30                                                       ` Oleg Nesterov
2012-04-29 16:41                                         ` Oleg Nesterov
2012-04-29 18:09                                           ` Al Viro
2012-04-29 18:25                                             ` Oleg Nesterov
2012-04-20  3:15               ` [RFC] situation with fput() locking (was Re: [PULL REQUEST] : ima-appraisal patches) Al Viro
2012-04-20 18:54           ` Hugh Dickins
2012-04-20 19:04             ` Al Viro
2012-04-20 19:18               ` Linus Torvalds
2012-04-20 19:32                 ` Hugh Dickins
2012-04-20 19:58                 ` Al Viro
2012-04-20 21:12                   ` Linus Torvalds
2012-04-20 21:12                     ` Linus Torvalds
2012-04-20 22:13                     ` Al Viro
2012-04-20 22:35                       ` Linus Torvalds
2012-04-20 22:35                         ` Linus Torvalds
2012-04-27  7:35                         ` Kasatkin, Dmitry
2012-04-27 17:34                           ` Al Viro
2012-04-27 18:52                             ` Kasatkin, Dmitry
2012-04-27 18:52                               ` Kasatkin, Dmitry
2012-04-27 19:15                               ` Kasatkin, Dmitry
2012-04-30 14:32                             ` Mimi Zohar
2012-04-30 14:32                               ` Mimi Zohar
2012-05-03  4:23                               ` James Morris
2012-05-03  4:23                                 ` James Morris
2012-04-20 19:37               ` Al Viro

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=20120425030659.GE6871@ZenIV.linux.org.uk \
    --to=viro@zeniv.linux.org.uk \
    --cc=arnd@arndb.de \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=oleg@redhat.com \
    --cc=tj@kernel.org \
    --cc=torvalds@linux-foundation.org \
    /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.