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: <20140702130149.25700.32590.stgit@skinsbursky-OptiPlex-9020>
Date:	Wed, 02 Jul 2014 15:02:01 +0200
From:	Stanislav Kinsbursky <stanislav.kinsbursky@...fitbricks.com>
To:	axboe@...nel.dk
Cc:	florian-ewald.mueller@...fitbricks.com,
	linux-kernel@...r.kernel.org, stanislav.kinsbursky@...fitbricks.com
Subject: [RFC PATCH] [blk]: fix NULL bdev dereference in driver's merge
 callbacks

Function __bio_map_kern() allocates new fresh bio with bi_bdev field undefined
and set to NULL. Than it calls bio_add_pc_page() which in turn calls
merge_bvec_fn() callback if defined, passing bvec_megre_data structure
pointer, with bi_bdev filesd initialized to "bio::bi_bdev" (equal to NULL).
There are 9 of them so far. At least some of them (like "rbd_merge_bvec",
"linear_mergeable_bvec") then dereference undefined "bvec_megre_data::bi_bdev"
to get start sector of the device, resulting in NULL pointer dereference.
This patch adds check for non-NULL bio->bi_bdev pointer to make sure, that the
device is defined, otherwise there is no sense to call this callback at all.

Signed-of-by: Stanislav Kinsbursky <stanislav.kinsbursky@...fitbricks.com>
---
 block/bio.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 0ec61c9..cb45186 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -725,7 +725,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
 			unsigned int prev_bv_len = prev->bv_len;
 			prev->bv_len += len;
 
-			if (q->merge_bvec_fn) {
+			if (q->merge_bvec_fn && bio->bi_bdev) {
 				struct bvec_merge_data bvm = {
 					/* prev_bvec is already charged in
 					   bi_size, discharge it in order to
@@ -787,7 +787,7 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
 	 * depending on offset), it can specify a merge_bvec_fn in the
 	 * queue to get further control
 	 */
-	if (q->merge_bvec_fn) {
+	if (q->merge_bvec_fn && bio->bi_bdev) {
 		struct bvec_merge_data bvm = {
 			.bi_bdev = bio->bi_bdev,
 			.bi_sector = bio->bi_iter.bi_sector,

--
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