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.0-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.0 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 8239506e58d7cab4e2f3b983b20281552f924e6b 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.0/sparc32-fix-exit-flag-passed-from-traced-sys_sigreturn.patch queue-3.0/resubmit-bridge-fix-message_age_timer-calculation.patch queue-3.0/sparc64-fix-itlb-handler-of-null-page.patch queue-3.0/ll_temac-reset-dma-descriptors-indexes-on-ndo_open.patch queue-3.0/ip-generate-unique-ip-identificator-if-local-fragmentation-is-allowed.patch queue-3.0/ipv6-mcast-use-in6_dev_put-in-timer-handlers-instead-of-__in6_dev_put.patch queue-3.0/net-sctp-fix-ipv6-ipsec-encryption-bug-in-sctp_v6_xmit.patch queue-3.0/bonding-fix-broken-promiscuity-reference-counting-issue.patch queue-3.0/dm9601-fix-iff_allmulti-handling.patch queue-3.0/sparc64-fix-off-by-one-in-trampoline-tlb-mapping-installation-loop.patch queue-3.0/caif-add-missing-braces-to-multiline-if-in-cfctrl_linkup_request.patch queue-3.0/bridge-clamp-forward_delay-when-enabling-stp.patch queue-3.0/ipv6-udp-packets-following-an-ufo-enqueued-packet-need-also-be-handled-by-ufo.patch queue-3.0/esp_scsi-fix-tag-state-corruption-when-autosensing.patch queue-3.0/sparc64-remove-rwsem-export-leftovers.patch queue-3.0/sparc64-fix-not-sra-ed-o5-in-32-bit-traced-syscall.patch queue-3.0/ipv4-igmp-use-in_dev_put-in-timer-handlers-instead-of-__in_dev_put.patch queue-3.0/netpoll-fix-null-pointer-dereference-in-netpoll_cleanup.patch queue-3.0/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