DivestOS/Patches/Linux_CVEs/CVE-2017-7187/3.10/0004.patch

384 lines
10 KiB
Diff
Raw Normal View History

2017-11-07 22:03:58 -05:00
From 60ebd48061949405fe6a69aa921d47b40f474a41 Mon Sep 17 00:00:00 2001
From: Jens Axboe <axboe@fb.com>
Date: Fri, 06 Jun 2014 07:57:37 -0600
Subject: [PATCH] BACKPORT: block: add blk_rq_set_block_pc()
With the optimizations around not clearing the full request at alloc
time, we are leaving some of the needed init for REQ_TYPE_BLOCK_PC
up to the user allocating the request.
Add a blk_rq_set_block_pc() that sets the command type to
REQ_TYPE_BLOCK_PC, and properly initializes the members associated
with this type of request. Update callers to use this function instead
of manipulating rq->cmd_type directly.
Includes fixes from Christoph Hellwig <hch@lst.de> for my half-assed
attempt.
Change-Id: Ifc386dfb951c5d6adebf48ff38135dda28e4b1ce
Signed-off-by: Jens Axboe <axboe@fb.com>
---
diff --git a/block/blk-core.c b/block/blk-core.c
index bce8d73..7cb3157 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1189,6 +1189,8 @@
if (unlikely(!rq))
return ERR_PTR(-ENOMEM);
+ blk_rq_set_block_pc(rq);
+
for_each_bio(bio) {
struct bio *bounce_bio = bio;
int ret;
@@ -1206,6 +1208,22 @@
EXPORT_SYMBOL(blk_make_request);
/**
+ * blk_rq_set_block_pc - initialize a requeest to type BLOCK_PC
+ * @rq: request to be initialized
+ *
+ */
+void blk_rq_set_block_pc(struct request *rq)
+{
+ rq->cmd_type = REQ_TYPE_BLOCK_PC;
+ rq->__data_len = 0;
+ rq->__sector = (sector_t) -1;
+ rq->bio = rq->biotail = NULL;
+ memset(rq->__cmd, 0, sizeof(rq->__cmd));
+ rq->cmd = rq->__cmd;
+}
+EXPORT_SYMBOL(blk_rq_set_block_pc);
+
+/**
* blk_requeue_request - put a request back on queue
* @q: request queue where request should be inserted
* @rq: request to be inserted
diff --git a/block/bsg.c b/block/bsg.c
index 76801e5..0ed26bc 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -196,7 +196,6 @@
* fill in request structure
*/
rq->cmd_len = hdr->request_len;
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->timeout = msecs_to_jiffies(hdr->timeout);
if (!rq->timeout)
@@ -273,6 +272,8 @@
rq = blk_get_request(q, rw, GFP_KERNEL);
if (!rq)
return ERR_PTR(-ENOMEM);
+ blk_rq_set_block_pc(rq);
+
ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd, has_write_perm);
if (ret)
goto out;
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 1b4988b..ddbcae2 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -233,7 +233,6 @@
* fill in request structure
*/
rq->cmd_len = hdr->cmd_len;
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->timeout = msecs_to_jiffies(hdr->timeout);
if (!rq->timeout)
@@ -314,6 +313,7 @@
rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL);
if (!rq)
return -ENOMEM;
+ blk_rq_set_block_pc(rq);
if (blk_fill_sghdr_rq(q, rq, hdr, mode)) {
blk_put_request(rq);
@@ -512,7 +512,7 @@
memset(sense, 0, sizeof(sense));
rq->sense = sense;
rq->sense_len = 0;
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
+ blk_rq_set_block_pc(rq);
blk_execute_rq(q, disk, rq, 0);
@@ -544,7 +544,7 @@
int err;
rq = blk_get_request(q, WRITE, __GFP_WAIT);
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
+ blk_rq_set_block_pc(rq);
rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
rq->cmd[0] = cmd;
rq->cmd[4] = data;
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index f5d0ea1..caddb5d 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -712,6 +712,7 @@
rq = blk_get_request(q, (cgc->data_direction == CGC_DATA_WRITE) ?
WRITE : READ, __GFP_WAIT);
+ blk_rq_set_block_pc(rq);
if (cgc->buflen) {
if (blk_rq_map_kern(q, rq, cgc->buffer, cgc->buflen, __GFP_WAIT))
@@ -722,7 +723,6 @@
memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE);
rq->timeout = 60*HZ;
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
if (cgc->quiet)
rq->cmd_flags |= REQ_QUIET;
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 8a3aff7..1ca0772 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -2165,6 +2165,7 @@
ret = -ENOMEM;
break;
}
+ blk_rq_set_block_pc(rq);
ret = blk_rq_map_user(q, rq, NULL, ubuf, len, GFP_KERNEL);
if (ret) {
@@ -2184,7 +2185,6 @@
rq->cmd[9] = 0xf8;
rq->cmd_len = 12;
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->timeout = 60 * HZ;
bio = rq->bio;
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index 68adb89..28bf7fb 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -120,6 +120,7 @@
"%s: blk_get_request failed\n", __func__);
return NULL;
}
+ blk_rq_set_block_pc(rq);
if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) {
blk_put_request(rq);
@@ -128,7 +129,6 @@
return NULL;
}
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER;
rq->retries = ALUA_FAILOVER_RETRIES;
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c
index e1c8be0..6f07f7f 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -280,6 +280,7 @@
return NULL;
}
+ blk_rq_set_block_pc(rq);
rq->cmd_len = COMMAND_SIZE(cmd);
rq->cmd[0] = cmd;
@@ -304,7 +305,6 @@
break;
}
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER;
rq->timeout = CLARIION_TIMEOUT;
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
index 084062b..e9d9fea 100644
--- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c
+++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
@@ -120,7 +120,7 @@
if (!req)
return SCSI_DH_RES_TEMP_UNAVAIL;
- req->cmd_type = REQ_TYPE_BLOCK_PC;
+ blk_rq_set_block_pc(req);
req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER;
req->cmd_len = COMMAND_SIZE(TEST_UNIT_READY);
@@ -250,7 +250,7 @@
if (!req)
return SCSI_DH_RES_TEMP_UNAVAIL;
- req->cmd_type = REQ_TYPE_BLOCK_PC;
+ blk_rq_set_block_pc(req);
req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER;
req->cmd_len = COMMAND_SIZE(START_STOP);
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 69c915a..3916c31 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -279,6 +279,7 @@
"get_rdac_req: blk_get_request failed.\n");
return NULL;
}
+ blk_rq_set_block_pc(rq);
if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) {
blk_put_request(rq);
@@ -287,7 +288,6 @@
return NULL;
}
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER;
rq->retries = RDAC_RETRIES;
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index aa66361..11bd87e 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -1570,6 +1570,7 @@
if (unlikely(!req))
return ERR_PTR(-ENOMEM);
+ blk_rq_set_block_pc(req);
return req;
}
}
@@ -1590,7 +1591,6 @@
}
or->request = req;
- req->cmd_type = REQ_TYPE_BLOCK_PC;
req->cmd_flags |= REQ_QUIET;
req->timeout = or->timeout;
@@ -1608,7 +1608,7 @@
ret = PTR_ERR(req);
goto out;
}
- req->cmd_type = REQ_TYPE_BLOCK_PC;
+ blk_rq_set_block_pc(req);
or->in.req = or->request->next_rq = req;
}
} else if (has_in)
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 21883a2..0727ea7 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -365,7 +365,7 @@
if (!req)
return DRIVER_ERROR << 24;
- req->cmd_type = REQ_TYPE_BLOCK_PC;
+ blk_rq_set_block_pc(req);
req->cmd_flags |= REQ_QUIET;
SRpnt->bio = NULL;
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 3668b1b..c1e4a74 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1653,6 +1653,8 @@
*/
req = blk_get_request(sdev->request_queue, READ, GFP_KERNEL);
+ blk_rq_set_block_pc(req);
+
req->cmd[0] = ALLOW_MEDIUM_REMOVAL;
req->cmd[1] = 0;
req->cmd[2] = 0;
@@ -1662,7 +1664,6 @@
req->cmd_len = COMMAND_SIZE(req->cmd[0]);
- req->cmd_type = REQ_TYPE_BLOCK_PC;
req->cmd_flags |= REQ_QUIET;
req->timeout = 10 * HZ;
req->retries = 5;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 9f3168e..49076d1 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -238,6 +238,7 @@
req = blk_get_request(sdev->request_queue, write, __GFP_WAIT);
if (!req)
return ret;
+ blk_rq_set_block_pc(req);
if (bufflen && blk_rq_map_kern(sdev->request_queue, req,
buffer, bufflen, __GFP_WAIT))
@@ -249,7 +250,6 @@
req->sense_len = 0;
req->retries = retries;
req->timeout = timeout;
- req->cmd_type = REQ_TYPE_BLOCK_PC;
req->cmd_flags |= flags | REQ_QUIET | REQ_PREEMPT;
/*
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index e059ad4..5170506 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1656,10 +1656,9 @@
if (!rq)
return -ENOMEM;
+ blk_rq_set_block_pc(rq);
memcpy(rq->cmd, cmd, hp->cmd_len);
-
rq->cmd_len = hp->cmd_len;
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
srp->rq = rq;
rq->end_io_data = srp;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 2a32036..7d74f83 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -484,7 +484,7 @@
if (!req)
return DRIVER_ERROR << 24;
- req->cmd_type = REQ_TYPE_BLOCK_PC;
+ blk_rq_set_block_pc(req);
req->cmd_flags |= REQ_QUIET;
mdata->null_mapped = 1;
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index 244776b..dff91ee 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -1059,6 +1059,8 @@
ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
goto fail;
}
+
+ blk_rq_set_block_pc(req);
} else {
BUG_ON(!cmd->data_length);
@@ -1075,7 +1077,6 @@
}
}
- req->cmd_type = REQ_TYPE_BLOCK_PC;
req->end_io = pscsi_req_done;
req->end_io_data = cmd;
req->cmd_len = scsi_command_size(pt->pscsi_cdb);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index e9b04cd..cce84e5 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -742,6 +742,7 @@
extern struct request *blk_get_request(struct request_queue *, int, gfp_t);
extern struct request *blk_make_request(struct request_queue *, struct bio *,
gfp_t);
+extern void blk_rq_set_block_pc(struct request *);
extern void blk_requeue_request(struct request_queue *, struct request *);
extern int blk_reinsert_request(struct request_queue *q, struct request *rq);
extern bool blk_reinsert_req_sup(struct request_queue *q);