lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20100816143216.9826.15970.stgit@beardog.cce.hp.com>
Date:	Mon, 16 Aug 2010 09:32:16 -0500
From:	"Stephen M. Cameron" <scameron@...rdog.cce.hp.com>
To:	axboe@...nel.dk
Cc:	akpm@...ux-foundation.org, mikem@...rdog.cce.hp.com,
	linux-kernel@...r.kernel.org, brace@...rdog.cce.hp.com
Subject: [PATCH] cciss: fix botched tag masking for scsi tape commands

From: Stephen M. Cameron <scameron@...rdog.cce.hp.com>

In process_non_indexed_cmd() we were only masking off the
low two bits when comparing tags vs. busaddr, and not taking
into account the fact that in "performant" mode, three bits of
block fetch table indexes were stuffed into the tag, and
needed to be masked out for the comparison to work.  This
resulted in spurious "bad tag" messages, and command
completions getting ignored for any scsi tape i/o and any i/o
coming through CCISS_BIG_PASSTHRU which required more than
one scatter gather entry (fewer than two worked because in
such cases the 3 bits we failed to mask off happened to be
zero anyway.)

I also noticed we were repeatedly masking the bits off the tag
in a loop when doing it once at the top of the loop would have
sufficed, so I fixed that as well.

Signed-off-by: Stephen M. Cameron <scameron@...rdog.cce.hp.com>
---
 drivers/block/cciss.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index fdf1b79..39083e6 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -3179,10 +3179,13 @@ static inline u32 cciss_tag_to_index(u32 tag)
 	return tag >> DIRECT_LOOKUP_SHIFT;
 }
 
-static inline u32 cciss_tag_discard_error_bits(u32 tag)
+static inline u32 cciss_tag_discard_error_bits(ctlr_info_t *h, u32 tag)
 {
-#define CCISS_ERROR_BITS 0x03
-	return tag & ~CCISS_ERROR_BITS;
+#define CCISS_PERF_ERROR_BITS ((1 << DIRECT_LOOKUP_SHIFT) - 1)
+#define CCISS_SIMPLE_ERROR_BITS 0x03
+	if (likely(h->transMethod == CFGTBL_Trans_Performant))
+		return tag & ~CCISS_PERF_ERROR_BITS;
+	return tag & ~CCISS_SIMPLE_ERROR_BITS;
 }
 
 static inline void cciss_mark_tag_indexed(u32 *tag)
@@ -3443,15 +3446,13 @@ static inline u32 process_indexed_cmd(ctlr_info_t *h, u32 raw_tag)
 /* process completion of a non-indexed command */
 static inline u32 process_nonindexed_cmd(ctlr_info_t *h, u32 raw_tag)
 {
-	u32 tag;
 	CommandList_struct *c = NULL;
 	struct hlist_node *tmp;
 	__u32 busaddr_masked, tag_masked;
 
-	tag = cciss_tag_discard_error_bits(raw_tag);
+	tag_masked = cciss_tag_discard_error_bits(h, raw_tag);
 	hlist_for_each_entry(c, tmp, &h->cmpQ, list) {
-		busaddr_masked = cciss_tag_discard_error_bits(c->busaddr);
-		tag_masked = cciss_tag_discard_error_bits(tag);
+		busaddr_masked = cciss_tag_discard_error_bits(h, c->busaddr);
 		if (busaddr_masked == tag_masked) {
 			finish_cmd(h, c, raw_tag);
 			return next_command(h);

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ