mirror of
https://git.yoctoproject.org/meta-ti
synced 2026-07-27 14:28:05 +00:00
6203cbca5c
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net> Signed-off-by: Denys Dmytriyenko <denys@ti.com>
76 lines
2.5 KiB
Diff
76 lines
2.5 KiB
Diff
From 8d14ccd4bd5dab58984030c13a71953d396e792d Mon Sep 17 00:00:00 2001
|
|
From: Roland Dreier <roland@purestorage.com>
|
|
Date: Mon, 16 Jul 2012 15:34:24 -0700
|
|
Subject: [PATCH 43/73] target: Fix possible integer underflow in UNMAP
|
|
emulation
|
|
|
|
commit b7fc7f3777582dea85156a821d78a522a0c083aa upstream.
|
|
|
|
It's possible for an initiator to send us an UNMAP command with a
|
|
descriptor that is less than 8 bytes; in that case it's really bad for
|
|
us to set an unsigned int to that value, subtract 8 from it, and then
|
|
use that as a limit for our loop (since the value will wrap around to
|
|
a huge positive value).
|
|
|
|
Fix this by making size be signed and only looping if size >= 16 (ie
|
|
if we have at least a full descriptor available).
|
|
|
|
Also remove offset as an obfuscated name for the constant 8.
|
|
|
|
Signed-off-by: Roland Dreier <roland@purestorage.com>
|
|
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
|
|
[bwh: Backported to 3.2: adjust filename, context]
|
|
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
|
---
|
|
drivers/target/target_core_cdb.c | 20 ++++++++++----------
|
|
1 files changed, 10 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c
|
|
index b1f5cf0..00f0f7d 100644
|
|
--- a/drivers/target/target_core_cdb.c
|
|
+++ b/drivers/target/target_core_cdb.c
|
|
@@ -1115,9 +1115,10 @@ int target_emulate_unmap(struct se_task *task)
|
|
struct se_device *dev = cmd->se_dev;
|
|
unsigned char *buf, *ptr = NULL;
|
|
sector_t lba;
|
|
- unsigned int size = cmd->data_length, range;
|
|
- int ret = 0, offset;
|
|
- unsigned short dl, bd_dl;
|
|
+ int size = cmd->data_length;
|
|
+ u32 range;
|
|
+ int ret = 0;
|
|
+ int dl, bd_dl;
|
|
|
|
if (!dev->transport->do_discard) {
|
|
pr_err("UNMAP emulation not supported for: %s\n",
|
|
@@ -1126,20 +1127,19 @@ int target_emulate_unmap(struct se_task *task)
|
|
return -ENOSYS;
|
|
}
|
|
|
|
- /* First UNMAP block descriptor starts at 8 byte offset */
|
|
- offset = 8;
|
|
- size -= 8;
|
|
-
|
|
buf = transport_kmap_data_sg(cmd);
|
|
|
|
dl = get_unaligned_be16(&buf[0]);
|
|
bd_dl = get_unaligned_be16(&buf[2]);
|
|
|
|
- ptr = &buf[offset];
|
|
- pr_debug("UNMAP: Sub: %s Using dl: %hu bd_dl: %hu size: %hu"
|
|
+ size = min(size - 8, bd_dl);
|
|
+
|
|
+ /* First UNMAP block descriptor starts at 8 byte offset */
|
|
+ ptr = &buf[8];
|
|
+ pr_debug("UNMAP: Sub: %s Using dl: %u bd_dl: %u size: %u"
|
|
" ptr: %p\n", dev->transport->name, dl, bd_dl, size, ptr);
|
|
|
|
- while (size) {
|
|
+ while (size >= 16) {
|
|
lba = get_unaligned_be64(&ptr[0]);
|
|
range = get_unaligned_be32(&ptr[8]);
|
|
pr_debug("UNMAP: Using lba: %llu and range: %u\n",
|
|
--
|
|
1.7.7.6
|
|
|