--- /dev/null
+From 35dc248383bbab0a7203fca4d722875bc81ef091 Mon Sep 17 00:00:00 2001
+From: Roland Dreier <roland@purestorage.com>
+Date: Mon, 5 Aug 2013 17:55:01 -0700
+Subject: SCSI: sg: Fix user memory corruption when SG_IO is interrupted by a signal
+
+From: Roland Dreier <roland@purestorage.com>
+
+commit 35dc248383bbab0a7203fca4d722875bc81ef091 upstream.
+
+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.
+
+ - Eventually, the SCSI command issued by the first ioctl finishes and
+ ends up in sg_rq_end_io(). At the end of that function, we run through:
+
+ write_lock_irqsave(&sfp->rq_list_lock, iflags);
+ if (unlikely(srp->orphan)) {
+ if (sfp->keep_orphan)
+ srp->sg_io_owned = 0;
+ else
+ done = 0;
+ }
+ srp->done = done;
+ write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
+
+ if (likely(done)) {
+ /* Now wake up any sg_read() that is waiting for this
+ * packet.
+ */
+ wake_up_interruptible(&sfp->read_wait);
+ kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN);
+ kref_put(&sfp->f_ref, sg_remove_sfp);
+ } else {
+ INIT_WORK(&srp->ew.work, sg_rq_end_io_usercontext);
+ schedule_work(&srp->ew.work);
+ }
+
+ Since srp->orphan *is* set, we set done to 0 (assuming the
+ userspace app has not set keep_orphan via an SG_SET_KEEP_ORPHAN
+ ioctl), and therefore we end up scheduling sg_rq_end_io_usercontext()
+ to run in a workqueue.
+
+ - In workqueue context we go through sg_rq_end_io_usercontext() ->
+ sg_finish_rem_req() -> blk_rq_unmap_user() -> ... ->
+ bio_uncopy_user() -> __bio_copy_iov() -> copy_to_user().
+
+ The key point here is that we are doing copy_to_user() on a
+ workqueue -- that is, we're on a kernel thread with current->mm
+ equal to whatever random previous user process was scheduled before
+ this kernel thread. So we end up copying whatever data the SCSI
+ command returned to the virtual address of the buffer passed into
+ the original ioctl, but it's quite likely we do this copying into a
+ different address space!
+
+As suggested by James Bottomley <James.Bottomley@hansenpartnership.com>,
+add a check for current->mm (which is NULL if we're on a kernel thread
+without a real userspace address space) in bio_uncopy_user(), and skip
+the copy if we're on a kernel thread.
+
+There's no reason that I can think of for any caller of bio_uncopy_user()
+to want to do copying on a kernel thread with a random active userspace
+address space.
+
+Huge thanks to Costa Sapuntzakis <costa@purestorage.com> for the
+original pointer to this bug in the sg code.
+
+Signed-off-by: Roland Dreier <roland@purestorage.com>
+Tested-by: David Milburn <dmilburn@redhat.com>
+Cc: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: James Bottomley <JBottomley@Parallels.com>
+[lizf: backported to 3.4:
+ - Use __bio_for_each_segment() instead of bio_for_each_segment_all()]
+Signed-off-by: Li Zefan <lizefan@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ fs/bio.c | 20 +++++++++++++++-----
+ 1 file changed, 15 insertions(+), 5 deletions(-)
+
+--- a/fs/bio.c
++++ b/fs/bio.c
+@@ -787,12 +787,22 @@ static int __bio_copy_iov(struct bio *bi
+ int bio_uncopy_user(struct bio *bio)
+ {
+ struct bio_map_data *bmd = bio->bi_private;
+- int ret = 0;
++ struct bio_vec *bvec;
++ int ret = 0, i;
+
+- if (!bio_flagged(bio, BIO_NULL_MAPPED))
+- ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs,
+- bmd->nr_sgvecs, bio_data_dir(bio) == READ,
+- 0, bmd->is_our_pages);
++ 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.
++ */
++ if (current->mm)
++ ret = __bio_copy_iov(bio, bmd->iovecs, bmd->sgvecs,
++ bmd->nr_sgvecs, bio_data_dir(bio) == READ,
++ 0, bmd->is_our_pages);
++ else if (bmd->is_our_pages)
++ __bio_for_each_segment(bvec, bio, i, 0)
++ __free_page(bvec->bv_page);
++ }
+ bio_free_map_data(bmd);
+ bio_put(bio);
+ return ret;
--- /dev/null
+From ee60bddba5a5f23e39598195d944aa0eb2d455e5 Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Wed, 24 Jul 2013 16:15:08 -0700
+Subject: target: Fix trailing ASCII space usage in INQUIRY vendor+model
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit ee60bddba5a5f23e39598195d944aa0eb2d455e5 upstream.
+
+This patch fixes spc_emulate_inquiry_std() to add trailing ASCII
+spaces for INQUIRY vendor + model fields following SPC-4 text:
+
+ "ASCII data fields described as being left-aligned shall have any
+ unused bytes at the end of the field (i.e., highest offset) and
+ the unused bytes shall be filled with ASCII space characters (20h)."
+
+This addresses a problem with Falconstor NSS multipathing.
+
+Reported-by: Tomas Molota <tomas.molota@lightstorm.sk>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_cdb.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/target/target_core_cdb.c
++++ b/drivers/target/target_core_cdb.c
+@@ -97,9 +97,12 @@ target_emulate_inquiry_std(struct se_cmd
+
+ buf[7] = 0x2; /* CmdQue=1 */
+
+- snprintf(&buf[8], 8, "LIO-ORG");
+- snprintf(&buf[16], 16, "%s", dev->se_sub_dev->t10_wwn.model);
+- snprintf(&buf[32], 4, "%s", dev->se_sub_dev->t10_wwn.revision);
++ memcpy(&buf[8], "LIO-ORG ", 8);
++ memset(&buf[16], 0x20, 16);
++ memcpy(&buf[16], dev->se_sub_dev->t10_wwn.model,
++ min_t(size_t, strlen(dev->se_sub_dev->t10_wwn.model), 16));
++ memcpy(&buf[32], dev->se_sub_dev->t10_wwn.revision,
++ min_t(size_t, strlen(dev->se_sub_dev->t10_wwn.revision), 4));
+ buf[4] = 31; /* Set additional length to 31 */
+
+ return 0;