From: Ewan Milne <emilne@redhat.com>
To: Hannes Reinecke <hare@suse.de>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>,
James Bottomley <james.bottomley@hansenpartnership.com>,
Doug Gilbert <dgilbert@interlog.com>,
linux-scsi@vger.kernel.org, Jens Axboe <axboe@kernel.dk>,
linux-block@vger.kernel.org,
Johannes Thumshirn <jthumshirn@suse.de>,
stable@vger.kernel.org, #@suse.de, v.3.11+@suse.de
Subject: Re: [PATCH] bio: return EINTR if copying to user space got interrupted
Date: Fri, 12 Feb 2016 11:15:13 -0500 [thread overview]
Message-ID: <1455293713.22112.373.camel@localhost.localdomain> (raw)
In-Reply-To: <1455266355-44676-1-git-send-email-hare@suse.de>
On Fri, 2016-02-12 at 09:39 +0100, Hannes Reinecke wrote:
> Commit 35dc248383bbab0a7203fca4d722875bc81ef091 introduced a check for
> current->mm to see if we have a user space context and only copies data
> if we do. Now if an IO gets interrupted by a signal data isn't copied
> into user space any more (as we don't have a user space context) but
> user space isn't notified about it.
>
> This patch modifies the behaviour to return -EINTR from bio_uncopy_user()
> to notify userland that a signal has interrupted the syscall, otherwise
> it could lead to a situation where the caller may get a buffer with
> no data returned.
>
> This can be reproduced by issuing SG_IO ioctl()s in one thread while
> constantly sending signals to it.
Well, this is definitely an improvement, since it now indicates to
the user that there was a problem instead of silently returning with
no data and no error, but it doesn't completely fix the issue.
For one thing, if the SG_IO is performed to a sequential media device,
the I/O is actually performed, and the position changes, it is just the
data that is not copied back. So e.g. a user program making calls to
read from a tape device that gets signals and retrying on -EINTR will
skip blocks. There is a similar problem already with SG_IO and
-ERESTARTSYS. I believe that that only way around this is to mask the
signals. (This is also problem with non-idempotent commands, such as
COMPARE AND WRITE.)
I should mention that the patch "sg: Fix user memory corruption when
SG_IO is interrupted by a signal" broke a 3rd-party kernel module that
happened to use SG_IO to pass *kernel* addresses for I/O. Which worked
for them until the current->mm test was added. (I don't know why they
didn't just put I/O on the request queue like everyone else, though.)
This patch should go in, though.
Reviewed-by: Ewan D. Milne <emilne@redhat.com>
>
> Fixes: 35dc248 [SCSI] sg: Fix user memory corruption when SG_IO is interrupted by a signal
> Signed-off-by: Johannes Thumshirn <jthumshirn@suse.de>
> Signed-off-by: Hannes Reinecke <hare@suse.de>
> Cc: stable@vger.kernel.org # v.3.11+
> ---
> block/bio.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/block/bio.c b/block/bio.c
> index dbabd48..24e5b69 100644
> --- a/block/bio.c
> +++ b/block/bio.c
> @@ -1090,9 +1090,12 @@ int bio_uncopy_user(struct bio *bio)
> if (!bio_flagged(bio, BIO_NULL_MAPPED)) {
> /*
> * if we're in a workqueue, the request is orphaned, so
> - * don't copy into a random user address space, just free.
> + * don't copy into a random user address space, just free
> + * and return -EINTR so user space doesn't expect any data.
> */
> - if (current->mm && bio_data_dir(bio) == READ)
> + if (!current->mm)
> + ret = -EINTR;
> + else if (bio_data_dir(bio) == READ)
> ret = bio_copy_to_iter(bio, bmd->iter);
> if (bmd->is_our_pages)
> bio_free_pages(bio);
next prev parent reply other threads:[~2016-02-12 16:15 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-12 8:39 [PATCH] bio: return EINTR if copying to user space got interrupted Hannes Reinecke
2016-02-12 15:17 ` Jens Axboe
2016-02-12 16:05 ` Douglas Gilbert
2016-02-12 16:14 ` Hannes Reinecke
2016-02-12 16:14 ` Hannes Reinecke
2016-02-12 16:15 ` Ewan Milne [this message]
-- strict thread matches above, loose matches on Subject: below --
2016-03-02 10:20 Johannes Thumshirn
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=1455293713.22112.373.camel@localhost.localdomain \
--to=emilne@redhat.com \
--cc=#@suse.de \
--cc=axboe@kernel.dk \
--cc=dgilbert@interlog.com \
--cc=hare@suse.de \
--cc=james.bottomley@hansenpartnership.com \
--cc=jthumshirn@suse.de \
--cc=linux-block@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=stable@vger.kernel.org \
--cc=v.3.11+@suse.de \
/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.