Patch "esp_scsi: Fix tag state corruption when autosensing." has been added to the 3.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    esp_scsi: Fix tag state corruption when autosensing.

to the 3.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     esp_scsi-fix-tag-state-corruption-when-autosensing.patch
and it can be found in the queue-3.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.


>From 5d9a6dc6ed2d7fd962e592e85a0ece02b6285b38 Mon Sep 17 00:00:00 2001
From: "David S. Miller" <davem@xxxxxxxxxxxxx>
Date: Thu, 1 Aug 2013 18:08:34 -0700
Subject: esp_scsi: Fix tag state corruption when autosensing.

From: "David S. Miller" <davem@xxxxxxxxxxxxx>

[ Upstream commit 21af8107f27878813d0364733c0b08813c2c192a ]

Meelis Roos reports a crash in esp_free_lun_tag() in the presense
of a disk which has died.

The issue is that when we issue an autosense command, we do so by
hijacking the original command that caused the check-condition.

When we do so we clear out the ent->tag[] array when we issue it via
find_and_prep_issuable_command().  This is so that the autosense
command is forced to be issued non-tagged.

That is problematic, because it is the value of ent->tag[] which
determines whether we issued the original scsi command as tagged
vs. non-tagged (see esp_alloc_lun_tag()).

And that, in turn, is what trips up the sanity checks in
esp_free_lun_tag().  That function needs the original ->tag[] values
in order to free up the tag slot properly.

Fix this by remembering the original command's tag values, and
having esp_alloc_lun_tag() and esp_free_lun_tag() use them.

Reported-by: Meelis Roos <mroos@xxxxxxxx>
Tested-by: Meelis Roos <mroos@xxxxxxxx>
Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
 drivers/scsi/esp_scsi.c |   14 ++++++++------
 drivers/scsi/esp_scsi.h |    1 +
 2 files changed, 9 insertions(+), 6 deletions(-)

--- a/drivers/scsi/esp_scsi.c
+++ b/drivers/scsi/esp_scsi.c
@@ -530,7 +530,7 @@ static int esp_need_to_nego_sync(struct
 static int esp_alloc_lun_tag(struct esp_cmd_entry *ent,
 			     struct esp_lun_data *lp)
 {
-	if (!ent->tag[0]) {
+	if (!ent->orig_tag[0]) {
 		/* Non-tagged, slot already taken?  */
 		if (lp->non_tagged_cmd)
 			return -EBUSY;
@@ -564,9 +564,9 @@ static int esp_alloc_lun_tag(struct esp_
 			return -EBUSY;
 	}
 
-	BUG_ON(lp->tagged_cmds[ent->tag[1]]);
+	BUG_ON(lp->tagged_cmds[ent->orig_tag[1]]);
 
-	lp->tagged_cmds[ent->tag[1]] = ent;
+	lp->tagged_cmds[ent->orig_tag[1]] = ent;
 	lp->num_tagged++;
 
 	return 0;
@@ -575,9 +575,9 @@ static int esp_alloc_lun_tag(struct esp_
 static void esp_free_lun_tag(struct esp_cmd_entry *ent,
 			     struct esp_lun_data *lp)
 {
-	if (ent->tag[0]) {
-		BUG_ON(lp->tagged_cmds[ent->tag[1]] != ent);
-		lp->tagged_cmds[ent->tag[1]] = NULL;
+	if (ent->orig_tag[0]) {
+		BUG_ON(lp->tagged_cmds[ent->orig_tag[1]] != ent);
+		lp->tagged_cmds[ent->orig_tag[1]] = NULL;
 		lp->num_tagged--;
 	} else {
 		BUG_ON(lp->non_tagged_cmd != ent);
@@ -667,6 +667,8 @@ static struct esp_cmd_entry *find_and_pr
 			ent->tag[0] = 0;
 			ent->tag[1] = 0;
 		}
+		ent->orig_tag[0] = ent->tag[0];
+		ent->orig_tag[1] = ent->tag[1];
 
 		if (esp_alloc_lun_tag(ent, lp) < 0)
 			continue;
--- a/drivers/scsi/esp_scsi.h
+++ b/drivers/scsi/esp_scsi.h
@@ -271,6 +271,7 @@ struct esp_cmd_entry {
 #define ESP_CMD_FLAG_AUTOSENSE	0x04 /* Doing automatic REQUEST_SENSE */
 
 	u8			tag[2];
+	u8			orig_tag[2];
 
 	u8			status;
 	u8			message;


Patches currently in stable-queue which might be from davem@xxxxxxxxxxxxx are

queue-3.4/sparc32-fix-exit-flag-passed-from-traced-sys_sigreturn.patch
queue-3.4/resubmit-bridge-fix-message_age_timer-calculation.patch
queue-3.4/sparc64-fix-itlb-handler-of-null-page.patch
queue-3.4/ll_temac-reset-dma-descriptors-indexes-on-ndo_open.patch
queue-3.4/ip-generate-unique-ip-identificator-if-local-fragmentation-is-allowed.patch
queue-3.4/ipv6-mcast-use-in6_dev_put-in-timer-handlers-instead-of-__in6_dev_put.patch
queue-3.4/ip-use-ip_hdr-in-__ip_make_skb-to-retrieve-ip-header.patch
queue-3.4/net-sctp-fix-ipv6-ipsec-encryption-bug-in-sctp_v6_xmit.patch
queue-3.4/gianfar-change-default-hw-tx-queue-scheduling-mode.patch
queue-3.4/bonding-fix-broken-promiscuity-reference-counting-issue.patch
queue-3.4/dm9601-fix-iff_allmulti-handling.patch
queue-3.4/caif-add-missing-braces-to-multiline-if-in-cfctrl_linkup_request.patch
queue-3.4/bridge-clamp-forward_delay-when-enabling-stp.patch
queue-3.4/ipv6-udp-packets-following-an-ufo-enqueued-packet-need-also-be-handled-by-ufo.patch
queue-3.4/esp_scsi-fix-tag-state-corruption-when-autosensing.patch
queue-3.4/sparc64-remove-rwsem-export-leftovers.patch
queue-3.4/sparc64-fix-not-sra-ed-o5-in-32-bit-traced-syscall.patch
queue-3.4/ipv4-igmp-use-in_dev_put-in-timer-handlers-instead-of-__in_dev_put.patch
queue-3.4/netpoll-fix-null-pointer-dereference-in-netpoll_cleanup.patch
queue-3.4/net-flow_dissector-fix-thoff-for-ipproto_ah.patch
queue-3.4/sparc64-fix-off-by-one-in-trampoline-tlb-mapping.patch
queue-3.4/net-sctp-fix-smatch-warning-in-sctp_send_asconf_del_ip.patch
queue-3.4/via-rhine-fix-vlan-priority-field-pcp-ieee-802.1p.patch
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]