All of lore.kernel.org
 help / color / mirror / Atom feed
From: Douglas Gilbert <dgilbert@interlog.com>
To: Peter Chang <dpf@google.com>
Cc: "Roland Dreier" <roland@kernel.org>,
	"Jens Axboe" <axboe@kernel.dk>,
	"James Bottomley" <JBottomley@parallels.com>,
	"Costa Sapuntzakis" <costa@purestorage.com>,
	"Jörn Engel" <joern@purestorage.com>,
	linux-kernel@vger.kernel.org,
	"linux-scsi@vger.kernel.org" <linux-scsi@vger.kernel.org>
Subject: Re: [PATCH] [SCSI] sg: Fix user memory corruption when SG_IO is interrupted by a signal
Date: Tue, 06 Aug 2013 10:56:02 -0400	[thread overview]
Message-ID: <52010E82.9050801@interlog.com> (raw)
In-Reply-To: <CAF2xp_Fwav3ZZCiuQ5738r4p-TMVRBZzHdYgoNg4EfO3_0C+tg@mail.gmail.com>

On 13-08-05 11:54 PM, Peter Chang wrote:
> 2013/8/5 Roland Dreier <roland@kernel.org>:
>> From: Roland Dreier <roland@purestorage.com>
>>
>> There is a nasty bug in the SCSI SG_IO ioctl that in some circumstances
>> leads to one process writing data into the address space of some other
>> random unrelated process if the ioctl is interrupted by a signal.
>> What happens is the following:
>>
>>   - A process issues an SG_IO ioctl with direction DXFER_FROM_DEV (ie the
>>     underlying SCSI command will transfer data from the SCSI device to
>>     the buffer provided in the ioctl)
>>
>>   - Before the command finishes, a signal is sent to the process waiting
>>     in the ioctl.  This will end up waking up the sg_ioctl() code:
>>
>>                  result = wait_event_interruptible(sfp->read_wait,
>>                          (srp_done(sfp, srp) || sdp->detached));
>>
>>     but neither srp_done() nor sdp->detached is true, so we end up just
>>     setting srp->orphan and returning to userspace:
>>
>>                  srp->orphan = 1;
>>                  write_unlock_irq(&sfp->rq_list_lock);
>>                  return result;  /* -ERESTARTSYS because signal hit process */
>>
>>     At this point the original process is done with the ioctl and
>>     blithely goes ahead handling the signal, reissuing the ioctl, etc.
>
> i think that an additional issue here is that part of reissuing the
> ioctl is re-queueing the command. since the re-queue is at the front
> of the block queue there are issues if the command is non-idempotent.

Re-issuing a SG_IO ioctl is wrong. More and more SCSI commands (even
in SBC-3) are non-idempotent (e.g. COMPARE AND WRITE). And the st
driver gets to use the block layer as well and many of its important
SCSI commands (SSC) are non-idempotent.

> we have a local fix that gets rid of most of the orphan stuff and
> re-waiting if a non-fatal signal was waiting. simpler than unmapping
> but maybe we're missing some other interesting case?

Like to share that fix with us?

Also I'm interested in how you know from within a kernel driver
whether a signal sent to the controlling process is fatal or
not? For example SIGIO's default action is terminate but sg
assumes if the controlling process requests SIGIO generation
then it will at least override that default action and
handle it sensibly. Is there a way to check that assumption?

Looked at bsg in the situation where a signal interrupts a
SG_IO ioctl. It seems broken; anyone like to comment on this
snippet from bsg if a signal hits the first call:
     blk_execute_rq(bd->queue, NULL, rq, at_head);
     ret = blk_complete_sgv4_hdr_rq(rq, &hdr, bio, bidi_bio);
     if (copy_to_user(uarg, &hdr, sizeof(hdr)))
         return -EFAULT;


As an aside, I got tired of handling signals during SCSI commands
in the ddpt utility, especially after adding tape support. So
it now masks all the usual suspects during the IO then checks
for signals in a small window between IOs. Non maskable signals
will still terminate but of course the user gets no guarantees,
but it would be still reasonable in the termination case that
the interrupted SCSI command was _not_ resubmitted.

Doug Gilbert


      reply	other threads:[~2013-08-06 14:56 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-05 22:02 [PATCH] [SCSI] sg: Fix user memory corruption when SG_IO is interrupted by a signal Roland Dreier
2013-08-05 23:31 ` James Bottomley
2013-08-05 23:38   ` Roland Dreier
2013-08-05 23:43     ` James Bottomley
2013-08-06  0:55       ` [PATCH v2] " Roland Dreier
2013-08-07 14:38         ` David Milburn
2013-08-07 15:50           ` Roland Dreier
2013-08-07 16:17             ` David Milburn
2013-08-07 16:31             ` Douglas Gilbert
2013-08-08 18:27               ` Roland Dreier
2013-08-15 16:45           ` Roland Dreier
2013-08-15 17:01             ` Douglas Gilbert
2013-08-06  0:19 ` [PATCH] " Douglas Gilbert
2013-08-06  3:54 ` Peter Chang
2013-08-06 14:56   ` Douglas Gilbert [this message]

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=52010E82.9050801@interlog.com \
    --to=dgilbert@interlog.com \
    --cc=JBottomley@parallels.com \
    --cc=axboe@kernel.dk \
    --cc=costa@purestorage.com \
    --cc=dpf@google.com \
    --cc=joern@purestorage.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=roland@kernel.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.