linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] block: T10/DIF Fixes and cleanups
@ 2017-03-30 13:49 Dmitry Monakhov
  2017-03-30 13:49 ` [PATCH 1/8] Guard bvec iteration logic Dmitry Monakhov
                   ` (7 more replies)
  0 siblings, 8 replies; 12+ messages in thread
From: Dmitry Monakhov @ 2017-03-30 13:49 UTC (permalink / raw)
  To: linux-kernel, linux-block, martin.petersen; +Cc: Dmitry Monakhov

This patch set fix various problems spotted during T10/DIF integrity machinery testing.

TOC:
## General bulletproof protection for block layer
0001 Guard bvec iteration logic
## Fix various bugs in T10/DIF/DIX infrastructure
0002 bio integrity: Do not allocate integrity context for 
0003 bio integrity: save original iterator for verify stag
0004 bio integrity: bio_trim should truncate integrity vec
0005 bio integrity: fix interface for bio_integrity_trim
## Cleanup T10/DIF/DIX infrastructure
0006 bio integrity add bio_integrity_setup helper
0007 T10 Move opencoded contants to common header
## Fix tcm_fileio info leak
0008 tcm_fileio: Prevent information leak for short reads

Testcase: http://marc.info/?l=linux-scsi&m=149087997013452&w=2

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/8] Guard bvec iteration logic
  2017-03-30 13:49 [PATCH 0/8] block: T10/DIF Fixes and cleanups Dmitry Monakhov
@ 2017-03-30 13:49 ` Dmitry Monakhov
  2017-03-31  8:21   ` Ming Lei
  2017-03-30 13:49 ` [PATCH 2/8] bio-integrity: Do not allocate integrity context for bio w/o data Dmitry Monakhov
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 12+ messages in thread
From: Dmitry Monakhov @ 2017-03-30 13:49 UTC (permalink / raw)
  To: linux-kernel, linux-block, martin.petersen; +Cc: Dmitry Monakhov

If some one try to attempt advance bvec beyond it's size we simply
dump WARN_ONCE and continue to iterate beyond bvec array boundaries.
This simply means that we endup dereferencing/corrupting random memory
region.

Code was added long time ago here 4550dd6c, luckily no one hit it
in real life :)

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 include/linux/bvec.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/linux/bvec.h b/include/linux/bvec.h
index 89b65b8..86b914f 100644
--- a/include/linux/bvec.h
+++ b/include/linux/bvec.h
@@ -70,8 +70,7 @@ static inline void bvec_iter_advance(const struct bio_vec *bv,
 				     struct bvec_iter *iter,
 				     unsigned bytes)
 {
-	WARN_ONCE(bytes > iter->bi_size,
-		  "Attempted to advance past end of bvec iter\n");
+	BUG_ON(bytes > iter->bi_size);
 
 	while (bytes) {
 		unsigned iter_len = bvec_iter_len(bv, *iter);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/8] bio-integrity: Do not allocate integrity context for bio w/o data
  2017-03-30 13:49 [PATCH 0/8] block: T10/DIF Fixes and cleanups Dmitry Monakhov
  2017-03-30 13:49 ` [PATCH 1/8] Guard bvec iteration logic Dmitry Monakhov
@ 2017-03-30 13:49 ` Dmitry Monakhov
  2017-03-30 13:49 ` [PATCH 3/8] bio-integrity: save original iterator for verify stage Dmitry Monakhov
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Dmitry Monakhov @ 2017-03-30 13:49 UTC (permalink / raw)
  To: linux-kernel, linux-block, martin.petersen; +Cc: Dmitry Monakhov

If bio has no data, such as ones from blkdev_issue_flush(),
then we have nothing to protect.

This patch prevent bugon like follows:

kfree_debugcheck: out of range ptr ac1fa1d106742a5ah
kernel BUG at mm/slab.c:2773!
invalid opcode: 0000 [#1] SMP
Modules linked in: bcache
CPU: 0 PID: 4428 Comm: xfs_io Tainted: G        W       4.11.0-rc4-ext4-00041-g2ef0043-dirty #43
Hardware name: Virtuozzo KVM, BIOS seabios-1.7.5-11.vz7.4 04/01/2014
task: ffff880137786440 task.stack: ffffc90000ba8000
RIP: 0010:kfree_debugcheck+0x25/0x2a
RSP: 0018:ffffc90000babde0 EFLAGS: 00010082
RAX: 0000000000000034 RBX: ac1fa1d106742a5a RCX: 0000000000000007
RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88013f3ccb40
RBP: ffffc90000babde8 R08: 0000000000000000 R09: 0000000000000000
R10: 00000000fcb76420 R11: 00000000725172ed R12: 0000000000000282
R13: ffffffff8150e766 R14: ffff88013a145e00 R15: 0000000000000001
FS:  00007fb09384bf40(0000) GS:ffff88013f200000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fd0172f9e40 CR3: 0000000137fa9000 CR4: 00000000000006f0
Call Trace:
 kfree+0xc8/0x1b3
 bio_integrity_free+0xc3/0x16b
 bio_free+0x25/0x66
 bio_put+0x14/0x26
 blkdev_issue_flush+0x7a/0x85
 blkdev_fsync+0x35/0x42
 vfs_fsync_range+0x8e/0x9f
 vfs_fsync+0x1c/0x1e
 do_fsync+0x31/0x4a
 SyS_fsync+0x10/0x14
 entry_SYSCALL_64_fastpath+0x1f/0xc2

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 block/bio-integrity.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index 5384713..b5009a8 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -175,6 +175,9 @@ bool bio_integrity_enabled(struct bio *bio)
 	if (bio_op(bio) != REQ_OP_READ && bio_op(bio) != REQ_OP_WRITE)
 		return false;
 
+	if (!bio_sectors(bio))
+		return false;
+
 	/* Already protected? */
 	if (bio_integrity(bio))
 		return false;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/8] bio-integrity: save original iterator for verify stage
  2017-03-30 13:49 [PATCH 0/8] block: T10/DIF Fixes and cleanups Dmitry Monakhov
  2017-03-30 13:49 ` [PATCH 1/8] Guard bvec iteration logic Dmitry Monakhov
  2017-03-30 13:49 ` [PATCH 2/8] bio-integrity: Do not allocate integrity context for bio w/o data Dmitry Monakhov
@ 2017-03-30 13:49 ` Dmitry Monakhov
  2017-03-30 13:49 ` [PATCH 4/8] bio-integrity: bio_trim should truncate integrity vector accordingly Dmitry Monakhov
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Dmitry Monakhov @ 2017-03-30 13:49 UTC (permalink / raw)
  To: linux-kernel, linux-block, martin.petersen; +Cc: Dmitry Monakhov

In order to perform verification we need to know original data vector
But, after bio traverse io-stack it may be advanced, splited and relocated
many times so it is hard to guess original data vector.

In fact currently ->verify_fn not woks at all because at the moment
it is called bio->bi_iter.bi_size == 0

The simplest way to fix that is to save original data vector and treat is
as immutable.

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 block/bio-integrity.c | 6 ++++--
 include/linux/bio.h   | 1 +
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index b5009a8..43a4476 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -238,10 +238,10 @@ static int bio_integrity_process(struct bio *bio,
 
 	iter.disk_name = bio->bi_bdev->bd_disk->disk_name;
 	iter.interval = 1 << bi->interval_exp;
-	iter.seed = bip_get_seed(bip);
+	iter.seed = bip->bip_verify_iter.bi_sector;
 	iter.prot_buf = prot_buf;
 
-	bio_for_each_segment(bv, bio, bviter) {
+	__bio_for_each_segment(bv, bio, bviter, bip->bip_verify_iter) {
 		void *kaddr = kmap_atomic(bv.bv_page);
 
 		iter.data_buf = kaddr + bv.bv_offset;
@@ -310,6 +310,7 @@ int bio_integrity_prep(struct bio *bio)
 	bip->bip_flags |= BIP_BLOCK_INTEGRITY;
 	bip->bip_iter.bi_size = len;
 	bip_set_seed(bip, bio->bi_iter.bi_sector);
+	bip->bip_verify_iter = bio->bi_iter;
 
 	if (bi->flags & BLK_INTEGRITY_IP_CHECKSUM)
 		bip->bip_flags |= BIP_IP_CHECKSUM;
@@ -476,6 +477,7 @@ int bio_integrity_clone(struct bio *bio, struct bio *bio_src,
 
 	bip->bip_vcnt = bip_src->bip_vcnt;
 	bip->bip_iter = bip_src->bip_iter;
+	bip->bip_verify_iter = bip_src->bip_verify_iter;
 
 	return 0;
 }
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 8e52119..00b086a 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -308,6 +308,7 @@ struct bio_integrity_payload {
 	struct bio		*bip_bio;	/* parent bio */
 
 	struct bvec_iter	bip_iter;
+	struct bvec_iter	bip_verify_iter;/* saved orig data iterator */
 
 	bio_end_io_t		*bip_end_io;	/* saved I/O completion fn */
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/8] bio-integrity: bio_trim should truncate integrity vector accordingly
  2017-03-30 13:49 [PATCH 0/8] block: T10/DIF Fixes and cleanups Dmitry Monakhov
                   ` (2 preceding siblings ...)
  2017-03-30 13:49 ` [PATCH 3/8] bio-integrity: save original iterator for verify stage Dmitry Monakhov
@ 2017-03-30 13:49 ` Dmitry Monakhov
  2017-03-30 13:49 ` [PATCH 5/8] bio-integrity: fix interface for bio_integrity_trim Dmitry Monakhov
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Dmitry Monakhov @ 2017-03-30 13:49 UTC (permalink / raw)
  To: linux-kernel, linux-block, martin.petersen; +Cc: Dmitry Monakhov

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 block/bio.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/block/bio.c b/block/bio.c
index e75878f..fa84323 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1907,6 +1907,10 @@ void bio_trim(struct bio *bio, int offset, int size)
 	bio_advance(bio, offset << 9);
 
 	bio->bi_iter.bi_size = size;
+
+	if (bio_integrity(bio))
+		bio_integrity_trim(bio, 0, size);
+
 }
 EXPORT_SYMBOL_GPL(bio_trim);
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/8] bio-integrity: fix interface for bio_integrity_trim
  2017-03-30 13:49 [PATCH 0/8] block: T10/DIF Fixes and cleanups Dmitry Monakhov
                   ` (3 preceding siblings ...)
  2017-03-30 13:49 ` [PATCH 4/8] bio-integrity: bio_trim should truncate integrity vector accordingly Dmitry Monakhov
@ 2017-03-30 13:49 ` Dmitry Monakhov
  2017-03-30 13:49 ` [PATCH 6/8] bio-integrity: add bio_integrity_setup helper Dmitry Monakhov
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Dmitry Monakhov @ 2017-03-30 13:49 UTC (permalink / raw)
  To: linux-kernel, linux-block, martin.petersen; +Cc: Dmitry Monakhov

bio_integrity_trim inherent it's interface from bio_trim and accept
offset and size, but this API is error prone because data offset
must always be in sync with bio's data offset. That is why we have
integrity update hook in bio_advance()

So the only meaningful offset is 0. Let's just remove it completely.

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 block/bio-integrity.c | 8 +-------
 block/bio.c           | 4 ++--
 drivers/md/dm.c       | 2 +-
 include/linux/bio.h   | 5 ++---
 4 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/block/bio-integrity.c b/block/bio-integrity.c
index 43a4476..43895a0 100644
--- a/block/bio-integrity.c
+++ b/block/bio-integrity.c
@@ -433,21 +433,15 @@ EXPORT_SYMBOL(bio_integrity_advance);
 /**
  * bio_integrity_trim - Trim integrity vector
  * @bio:	bio whose integrity vector to update
- * @offset:	offset to first data sector
  * @sectors:	number of data sectors
  *
  * Description: Used to trim the integrity vector in a cloned bio.
- * The ivec will be advanced corresponding to 'offset' data sectors
- * and the length will be truncated corresponding to 'len' data
- * sectors.
  */
-void bio_integrity_trim(struct bio *bio, unsigned int offset,
-			unsigned int sectors)
+void bio_integrity_trim(struct bio *bio, unsigned int sectors)
 {
 	struct bio_integrity_payload *bip = bio_integrity(bio);
 	struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
 
-	bio_integrity_advance(bio, offset << 9);
 	bip->bip_iter.bi_size = bio_integrity_bytes(bi, sectors);
 }
 EXPORT_SYMBOL(bio_integrity_trim);
diff --git a/block/bio.c b/block/bio.c
index fa84323..6895986 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1878,7 +1878,7 @@ struct bio *bio_split(struct bio *bio, int sectors,
 	split->bi_iter.bi_size = sectors << 9;
 
 	if (bio_integrity(split))
-		bio_integrity_trim(split, 0, sectors);
+		bio_integrity_trim(split, sectors);
 
 	bio_advance(bio, split->bi_iter.bi_size);
 
@@ -1909,7 +1909,7 @@ void bio_trim(struct bio *bio, int offset, int size)
 	bio->bi_iter.bi_size = size;
 
 	if (bio_integrity(bio))
-		bio_integrity_trim(bio, 0, size);
+		bio_integrity_trim(bio, size);
 
 }
 EXPORT_SYMBOL_GPL(bio_trim);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index dfb7597..e54ecdd 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1102,7 +1102,7 @@ static int clone_bio(struct dm_target_io *tio, struct bio *bio,
 	clone->bi_iter.bi_size = to_bytes(len);
 
 	if (bio_integrity(bio))
-		bio_integrity_trim(clone, 0, len);
+		bio_integrity_trim(clone, len);
 
 	return 0;
 }
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 00b086a..350f71d 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -732,7 +732,7 @@ extern bool bio_integrity_enabled(struct bio *bio);
 extern int bio_integrity_prep(struct bio *);
 extern void bio_integrity_endio(struct bio *);
 extern void bio_integrity_advance(struct bio *, unsigned int);
-extern void bio_integrity_trim(struct bio *, unsigned int, unsigned int);
+extern void bio_integrity_trim(struct bio *, unsigned int);
 extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t);
 extern int bioset_integrity_create(struct bio_set *, int);
 extern void bioset_integrity_free(struct bio_set *);
@@ -782,8 +782,7 @@ static inline void bio_integrity_advance(struct bio *bio,
 	return;
 }
 
-static inline void bio_integrity_trim(struct bio *bio, unsigned int offset,
-				      unsigned int sectors)
+static inline void bio_integrity_trim(struct bio *bio, unsigned int sectors)
 {
 	return;
 }
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 6/8] bio-integrity: add bio_integrity_setup helper
  2017-03-30 13:49 [PATCH 0/8] block: T10/DIF Fixes and cleanups Dmitry Monakhov
                   ` (4 preceding siblings ...)
  2017-03-30 13:49 ` [PATCH 5/8] bio-integrity: fix interface for bio_integrity_trim Dmitry Monakhov
@ 2017-03-30 13:49 ` Dmitry Monakhov
  2017-03-31 22:15   ` kbuild test robot
  2017-03-30 13:49 ` [PATCH 7/8] T10: Move opencoded contants to common header Dmitry Monakhov
  2017-03-30 13:49 ` [PATCH 8/8] tcm_fileio: Prevent information leak for short reads Dmitry Monakhov
  7 siblings, 1 reply; 12+ messages in thread
From: Dmitry Monakhov @ 2017-03-30 13:49 UTC (permalink / raw)
  To: linux-kernel, linux-block, martin.petersen; +Cc: Dmitry Monakhov

Currently all integrity prep hooks are open-coded, and if prepare fails
we ignore it's code and fail bio with EIO. Let's return real error to
upper layer, so later caller may react accordingly. For example retry in
case of ENOMEM.

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 block/blk-core.c     |  5 +----
 block/blk-mq.c       |  8 ++------
 drivers/nvdimm/blk.c | 13 ++-----------
 drivers/nvdimm/btt.c | 13 ++-----------
 include/linux/bio.h  | 25 +++++++++++++++++++++++++
 5 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index d772c22..071a998 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1637,11 +1637,8 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)
 
 	blk_queue_split(q, &bio, q->bio_split);
 
-	if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
-		bio->bi_error = -EIO;
-		bio_endio(bio);
+	if (bio_integrity_setup(bio))
 		return BLK_QC_T_NONE;
-	}
 
 	if (op_is_flush(bio->bi_opf)) {
 		spin_lock_irq(q->queue_lock);
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 08a49c6..a9931ec 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1489,10 +1489,8 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
 
 	blk_queue_bounce(q, &bio);
 
-	if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
-		bio_io_error(bio);
+	if (bio_integrity_setup(bio))
 		return BLK_QC_T_NONE;
-	}
 
 	blk_queue_split(q, &bio, q->bio_split);
 
@@ -1611,10 +1609,8 @@ static blk_qc_t blk_sq_make_request(struct request_queue *q, struct bio *bio)
 
 	blk_queue_bounce(q, &bio);
 
-	if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
-		bio_io_error(bio);
+	if (bio_integrity_setup(bio))
 		return BLK_QC_T_NONE;
-	}
 
 	blk_queue_split(q, &bio, q->bio_split);
 
diff --git a/drivers/nvdimm/blk.c b/drivers/nvdimm/blk.c
index 9faaa96..1edb3f3 100644
--- a/drivers/nvdimm/blk.c
+++ b/drivers/nvdimm/blk.c
@@ -179,16 +179,8 @@ static blk_qc_t nd_blk_make_request(struct request_queue *q, struct bio *bio)
 	int err = 0, rw;
 	bool do_acct;
 
-	/*
-	 * bio_integrity_enabled also checks if the bio already has an
-	 * integrity payload attached. If it does, we *don't* do a
-	 * bio_integrity_prep here - the payload has been generated by
-	 * another kernel subsystem, and we just pass it through.
-	 */
-	if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
-		bio->bi_error = -EIO;
-		goto out;
-	}
+	if (bio_integrity_setup(bio))
+		return BLK_QC_T_NONE;
 
 	bip = bio_integrity(bio);
 	nsblk = q->queuedata;
@@ -212,7 +204,6 @@ static blk_qc_t nd_blk_make_request(struct request_queue *q, struct bio *bio)
 	if (do_acct)
 		nd_iostat_end(bio, start);
 
- out:
 	bio_endio(bio);
 	return BLK_QC_T_NONE;
 }
diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c
index 368795a..03ded8d 100644
--- a/drivers/nvdimm/btt.c
+++ b/drivers/nvdimm/btt.c
@@ -1158,16 +1158,8 @@ static blk_qc_t btt_make_request(struct request_queue *q, struct bio *bio)
 	int err = 0;
 	bool do_acct;
 
-	/*
-	 * bio_integrity_enabled also checks if the bio already has an
-	 * integrity payload attached. If it does, we *don't* do a
-	 * bio_integrity_prep here - the payload has been generated by
-	 * another kernel subsystem, and we just pass it through.
-	 */
-	if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
-		bio->bi_error = -EIO;
-		goto out;
-	}
+	if (bio_integrity_setup(bio))
+		return BLK_QC_T_NONE;
 
 	do_acct = nd_iostat_start(bio, &start);
 	bio_for_each_segment(bvec, bio, iter) {
@@ -1194,7 +1186,6 @@ static blk_qc_t btt_make_request(struct request_queue *q, struct bio *bio)
 	if (do_acct)
 		nd_iostat_end(bio, start);
 
-out:
 	bio_endio(bio);
 	return BLK_QC_T_NONE;
 }
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 350f71d..f477327 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -738,6 +738,26 @@ extern int bioset_integrity_create(struct bio_set *, int);
 extern void bioset_integrity_free(struct bio_set *);
 extern void bio_integrity_init(void);
 
+static inline int bio_integrity_setup(struct bio *bio)
+{
+	int err = 0;
+
+	/*
+	 * bio_integrity_enabled also checks if the bio already has an
+	 * integrity payload attached. If it does, we *don't* do a
+	 * bio_integrity_prep here - the payload has been generated by
+	 * another kernel subsystem, and we just pass it through.
+	 */
+	if (bio_integrity_enabled(bio)) {
+		err = bio_integrity_prep(bio);
+		if (err) {
+			bio->bi_error = err;
+			bio_endio(bio);
+		}
+	}
+	return err;
+}
+
 #else /* CONFIG_BLK_DEV_INTEGRITY */
 
 static inline void *bio_integrity(struct bio *bio)
@@ -765,6 +785,11 @@ static inline int bio_integrity_prep(struct bio *bio)
 	return 0;
 }
 
+static int bio_integrity_setup(struct bio *bio)
+{
+	return 0;
+}
+
 static inline void bio_integrity_free(struct bio *bio)
 {
 	return;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 7/8] T10: Move opencoded contants to common header
  2017-03-30 13:49 [PATCH 0/8] block: T10/DIF Fixes and cleanups Dmitry Monakhov
                   ` (5 preceding siblings ...)
  2017-03-30 13:49 ` [PATCH 6/8] bio-integrity: add bio_integrity_setup helper Dmitry Monakhov
@ 2017-03-30 13:49 ` Dmitry Monakhov
  2017-03-31 22:09   ` kbuild test robot
  2017-03-30 13:49 ` [PATCH 8/8] tcm_fileio: Prevent information leak for short reads Dmitry Monakhov
  7 siblings, 1 reply; 12+ messages in thread
From: Dmitry Monakhov @ 2017-03-30 13:49 UTC (permalink / raw)
  To: linux-kernel, linux-block, martin.petersen; +Cc: Dmitry Monakhov

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 block/t10-pi.c                   | 9 +++------
 drivers/scsi/lpfc/lpfc_scsi.c    | 4 ++--
 drivers/scsi/qla2xxx/qla_isr.c   | 8 ++++----
 drivers/target/target_core_sbc.c | 2 +-
 include/linux/t10-pi.h           | 3 +++
 5 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/block/t10-pi.c b/block/t10-pi.c
index 2c97912..485cecd 100644
--- a/block/t10-pi.c
+++ b/block/t10-pi.c
@@ -28,9 +28,6 @@
 
 typedef __be16 (csum_fn) (void *, unsigned int);
 
-static const __be16 APP_ESCAPE = (__force __be16) 0xffff;
-static const __be32 REF_ESCAPE = (__force __be32) 0xffffffff;
-
 static __be16 t10_pi_crc_fn(void *data, unsigned int len)
 {
 	return cpu_to_be16(crc_t10dif(data, len));
@@ -82,7 +79,7 @@ static int t10_pi_verify(struct blk_integrity_iter *iter, csum_fn *fn,
 		switch (type) {
 		case 1:
 		case 2:
-			if (pi->app_tag == APP_ESCAPE)
+			if (pi->app_tag == T10_APP_ESCAPE)
 				goto next;
 
 			if (be32_to_cpu(pi->ref_tag) !=
@@ -95,8 +92,8 @@ static int t10_pi_verify(struct blk_integrity_iter *iter, csum_fn *fn,
 			}
 			break;
 		case 3:
-			if (pi->app_tag == APP_ESCAPE &&
-			    pi->ref_tag == REF_ESCAPE)
+			if (pi->app_tag == T10_APP_ESCAPE &&
+			    pi->ref_tag == T10_REF_ESCAPE)
 				goto next;
 			break;
 		}
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 54fd0c8..6703512 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -2934,8 +2934,8 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
 				 * First check to see if a protection data
 				 * check is valid
 				 */
-				if ((src->ref_tag == 0xffffffff) ||
-				    (src->app_tag == 0xffff)) {
+				if ((src->ref_tag == T10_REF_ESCAPE) ||
+				    (src->app_tag == T10_APP_ESCAPE)) {
 					start_ref_tag++;
 					goto skipit;
 				}
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 3203367..dfab093 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1950,9 +1950,9 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24)
 	 * For type     3: ref & app tag is all 'f's
 	 * For type 0,1,2: app tag is all 'f's
 	 */
-	if ((a_app_tag == 0xffff) &&
+	if ((a_app_tag == T10_APP_TAG) &&
 	    ((scsi_get_prot_type(cmd) != SCSI_PROT_DIF_TYPE3) ||
-	     (a_ref_tag == 0xffffffff))) {
+	     (a_ref_tag == T10_REF_TAG))) {
 		uint32_t blocks_done, resid;
 		sector_t lba_s = scsi_get_lba(cmd);
 
@@ -1994,9 +1994,9 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24)
 			spt = page_address(sg_page(sg)) + sg->offset;
 			spt += j;
 
-			spt->app_tag = 0xffff;
+			spt->app_tag = T10_APP_TAG;
 			if (scsi_get_prot_type(cmd) == SCSI_PROT_DIF_TYPE3)
-				spt->ref_tag = 0xffffffff;
+				spt->ref_tag = T10_REF_TAG;
 		}
 
 		return 0;
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index c194063..927ef44 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -1446,7 +1446,7 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
 				 (unsigned long long)sector, sdt->guard_tag,
 				 sdt->app_tag, be32_to_cpu(sdt->ref_tag));
 
-			if (sdt->app_tag == cpu_to_be16(0xffff)) {
+			if (sdt->app_tag == T10_APP_ESCAPE) {
 				dsg_off += block_size;
 				goto next;
 			}
diff --git a/include/linux/t10-pi.h b/include/linux/t10-pi.h
index 9fba9dd..c96845c 100644
--- a/include/linux/t10-pi.h
+++ b/include/linux/t10-pi.h
@@ -24,6 +24,9 @@ enum t10_dif_type {
 	T10_PI_TYPE3_PROTECTION = 0x3,
 };
 
+static const __be16 T10_APP_ESCAPE = (__force __be16) 0xffff;
+static const __be32 T10_REF_ESCAPE = (__force __be32) 0xffffffff;
+
 /*
  * T10 Protection Information tuple.
  */
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 8/8] tcm_fileio: Prevent information leak for short reads
  2017-03-30 13:49 [PATCH 0/8] block: T10/DIF Fixes and cleanups Dmitry Monakhov
                   ` (6 preceding siblings ...)
  2017-03-30 13:49 ` [PATCH 7/8] T10: Move opencoded contants to common header Dmitry Monakhov
@ 2017-03-30 13:49 ` Dmitry Monakhov
  7 siblings, 0 replies; 12+ messages in thread
From: Dmitry Monakhov @ 2017-03-30 13:49 UTC (permalink / raw)
  To: linux-kernel, linux-block, martin.petersen; +Cc: Dmitry Monakhov

If we failed to read data from backing file (probably because some one
truncate file under us), we must zerofill cmd's data, otherwise it will
be returned as is. Most likely cmd's data are unitialized pages from
page cache. This result in information leak.

xfstests: generic/420
http://marc.info/?l=linux-scsi&m=149087996913448&w=2

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 drivers/target/target_core_file.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index 87aa376..d69908d 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -277,12 +277,11 @@ static int fd_do_rw(struct se_cmd *cmd, struct file *fd,
 	else
 		ret = vfs_iter_read(fd, &iter, &pos);
 
-	kfree(bvec);
-
 	if (is_write) {
 		if (ret < 0 || ret != data_length) {
 			pr_err("%s() write returned %d\n", __func__, ret);
-			return (ret < 0 ? ret : -EINVAL);
+			if (ret >= 0)
+				ret = -EINVAL;
 		}
 	} else {
 		/*
@@ -295,17 +294,27 @@ static int fd_do_rw(struct se_cmd *cmd, struct file *fd,
 				pr_err("%s() returned %d, expecting %u for "
 						"S_ISBLK\n", __func__, ret,
 						data_length);
-				return (ret < 0 ? ret : -EINVAL);
+				if (ret >= 0)
+					ret = -EINVAL;
 			}
 		} else {
 			if (ret < 0) {
 				pr_err("%s() returned %d for non S_ISBLK\n",
 						__func__, ret);
-				return ret;
+			} else if (ret != data_length) {
+				/*
+				 * Short read case:
+				 * Probably some one truncate file under us.
+				 * We must explicitly zero sg-pages to prevent
+				 * expose uninizialized pages to userspace.
+				 */
+				BUG_ON(ret > data_length);
+				ret += iov_iter_zero(data_length - ret, &iter);
 			}
 		}
 	}
-	return 1;
+	kfree(bvec);
+	return ret;
 }
 
 static sense_reason_t
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/8] Guard bvec iteration logic
  2017-03-30 13:49 ` [PATCH 1/8] Guard bvec iteration logic Dmitry Monakhov
@ 2017-03-31  8:21   ` Ming Lei
  0 siblings, 0 replies; 12+ messages in thread
From: Ming Lei @ 2017-03-31  8:21 UTC (permalink / raw)
  To: Dmitry Monakhov
  Cc: Linux Kernel Mailing List, linux-block, Martin K. Petersen

On Thu, Mar 30, 2017 at 9:49 PM, Dmitry Monakhov <dmonakhov@openvz.org> wrote:
> If some one try to attempt advance bvec beyond it's size we simply
> dump WARN_ONCE and continue to iterate beyond bvec array boundaries.
> This simply means that we endup dereferencing/corrupting random memory
> region.
>
> Code was added long time ago here 4550dd6c, luckily no one hit it
> in real life :)
>
> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
> ---
>  include/linux/bvec.h | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/include/linux/bvec.h b/include/linux/bvec.h
> index 89b65b8..86b914f 100644
> --- a/include/linux/bvec.h
> +++ b/include/linux/bvec.h
> @@ -70,8 +70,7 @@ static inline void bvec_iter_advance(const struct bio_vec *bv,
>                                      struct bvec_iter *iter,
>                                      unsigned bytes)
>  {
> -       WARN_ONCE(bytes > iter->bi_size,
> -                 "Attempted to advance past end of bvec iter\n");
> +       BUG_ON(bytes > iter->bi_size);

This may not a good idea, especially Linus did not like BUG_ON(), please see the
following link:

https://lkml.org/lkml/2016/10/4/1



Thanks,
Ming Lei

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 7/8] T10: Move opencoded contants to common header
  2017-03-30 13:49 ` [PATCH 7/8] T10: Move opencoded contants to common header Dmitry Monakhov
@ 2017-03-31 22:09   ` kbuild test robot
  0 siblings, 0 replies; 12+ messages in thread
From: kbuild test robot @ 2017-03-31 22:09 UTC (permalink / raw)
  To: Dmitry Monakhov
  Cc: kbuild-all, linux-kernel, linux-block, martin.petersen, Dmitry Monakhov

[-- Attachment #1: Type: text/plain, Size: 2250 bytes --]

Hi Dmitry,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.11-rc4]
[cannot apply to block/for-next next-20170331]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Dmitry-Monakhov/block-T10-DIF-Fixes-and-cleanups/20170401-043532
config: x86_64-kexec (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All errors (new ones prefixed by >>):

   drivers/scsi//qla2xxx/qla_isr.c: In function 'qla2x00_handle_dif_error':
>> drivers/scsi//qla2xxx/qla_isr.c:1953:20: error: 'T10_APP_TAG' undeclared (first use in this function)
     if ((a_app_tag == T10_APP_TAG) &&
                       ^~~~~~~~~~~
   drivers/scsi//qla2xxx/qla_isr.c:1953:20: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/scsi//qla2xxx/qla_isr.c:1955:21: error: 'T10_REF_TAG' undeclared (first use in this function)
          (a_ref_tag == T10_REF_TAG))) {
                        ^~~~~~~~~~~
   In file included from include/linux/blkdev.h:20:0,
                    from include/linux/blk-mq.h:4,
                    from include/scsi/scsi_host.h:10,
                    from drivers/scsi//qla2xxx/qla_def.h:31,
                    from drivers/scsi//qla2xxx/qla_isr.c:7:
   At top level:
   include/linux/bio.h:788:12: warning: 'bio_integrity_setup' defined but not used [-Wunused-function]
    static int bio_integrity_setup(struct bio *bio)
               ^~~~~~~~~~~~~~~~~~~

vim +/T10_APP_TAG +1953 drivers/scsi//qla2xxx/qla_isr.c

  1947	
  1948		/*
  1949		 * Ignore sector if:
  1950		 * For type     3: ref & app tag is all 'f's
  1951		 * For type 0,1,2: app tag is all 'f's
  1952		 */
> 1953		if ((a_app_tag == T10_APP_TAG) &&
  1954		    ((scsi_get_prot_type(cmd) != SCSI_PROT_DIF_TYPE3) ||
> 1955		     (a_ref_tag == T10_REF_TAG))) {
  1956			uint32_t blocks_done, resid;
  1957			sector_t lba_s = scsi_get_lba(cmd);
  1958	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 25149 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 6/8] bio-integrity: add bio_integrity_setup helper
  2017-03-30 13:49 ` [PATCH 6/8] bio-integrity: add bio_integrity_setup helper Dmitry Monakhov
@ 2017-03-31 22:15   ` kbuild test robot
  0 siblings, 0 replies; 12+ messages in thread
From: kbuild test robot @ 2017-03-31 22:15 UTC (permalink / raw)
  To: Dmitry Monakhov
  Cc: kbuild-all, linux-kernel, linux-block, martin.petersen, Dmitry Monakhov

[-- Attachment #1: Type: text/plain, Size: 1677 bytes --]

Hi Dmitry,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.11-rc4]
[cannot apply to block/for-next next-20170331]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Dmitry-Monakhov/block-T10-DIF-Fixes-and-cleanups/20170401-043532
config: sparc64-defconfig (attached as .config)
compiler: sparc64-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
        wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=sparc64 

All errors (new ones prefixed by >>):

   In file included from include/linux/blkdev.h:20:0,
                    from include/linux/backing-dev.h:14,
                    from include/linux/nfs_fs_sb.h:5,
                    from include/linux/nfs_fs.h:37,
                    from arch/sparc/kernel/sys_sparc32.c:24:
>> include/linux/bio.h:788:12: error: 'bio_integrity_setup' defined but not used [-Werror=unused-function]
    static int bio_integrity_setup(struct bio *bio)
               ^~~~~~~~~~~~~~~~~~~
   cc1: all warnings being treated as errors

vim +/bio_integrity_setup +788 include/linux/bio.h

   782	
   783	static inline int bio_integrity_prep(struct bio *bio)
   784	{
   785		return 0;
   786	}
   787	
 > 788	static int bio_integrity_setup(struct bio *bio)
   789	{
   790		return 0;
   791	}

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 17530 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2017-03-31 22:16 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-30 13:49 [PATCH 0/8] block: T10/DIF Fixes and cleanups Dmitry Monakhov
2017-03-30 13:49 ` [PATCH 1/8] Guard bvec iteration logic Dmitry Monakhov
2017-03-31  8:21   ` Ming Lei
2017-03-30 13:49 ` [PATCH 2/8] bio-integrity: Do not allocate integrity context for bio w/o data Dmitry Monakhov
2017-03-30 13:49 ` [PATCH 3/8] bio-integrity: save original iterator for verify stage Dmitry Monakhov
2017-03-30 13:49 ` [PATCH 4/8] bio-integrity: bio_trim should truncate integrity vector accordingly Dmitry Monakhov
2017-03-30 13:49 ` [PATCH 5/8] bio-integrity: fix interface for bio_integrity_trim Dmitry Monakhov
2017-03-30 13:49 ` [PATCH 6/8] bio-integrity: add bio_integrity_setup helper Dmitry Monakhov
2017-03-31 22:15   ` kbuild test robot
2017-03-30 13:49 ` [PATCH 7/8] T10: Move opencoded contants to common header Dmitry Monakhov
2017-03-31 22:09   ` kbuild test robot
2017-03-30 13:49 ` [PATCH 8/8] tcm_fileio: Prevent information leak for short reads Dmitry Monakhov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).