[glsdk/meta-ti-glsdk.git] / recipes-kernel / linux / linux-ti33x-psp-3.2 / 3.2.25 / 0043-target-Fix-possible-integer-underflow-in-UNMAP-emula.patch
1 From 8d14ccd4bd5dab58984030c13a71953d396e792d Mon Sep 17 00:00:00 2001
2 From: Roland Dreier <roland@purestorage.com>
3 Date: Mon, 16 Jul 2012 15:34:24 -0700
4 Subject: [PATCH 43/73] target: Fix possible integer underflow in UNMAP
5 emulation
7 commit b7fc7f3777582dea85156a821d78a522a0c083aa upstream.
9 It's possible for an initiator to send us an UNMAP command with a
10 descriptor that is less than 8 bytes; in that case it's really bad for
11 us to set an unsigned int to that value, subtract 8 from it, and then
12 use that as a limit for our loop (since the value will wrap around to
13 a huge positive value).
15 Fix this by making size be signed and only looping if size >= 16 (ie
16 if we have at least a full descriptor available).
18 Also remove offset as an obfuscated name for the constant 8.
20 Signed-off-by: Roland Dreier <roland@purestorage.com>
21 Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
22 [bwh: Backported to 3.2: adjust filename, context]
23 Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
24 ---
25 drivers/target/target_core_cdb.c | 20 ++++++++++----------
26 1 files changed, 10 insertions(+), 10 deletions(-)
28 diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c
29 index b1f5cf0..00f0f7d 100644
30 --- a/drivers/target/target_core_cdb.c
31 +++ b/drivers/target/target_core_cdb.c
32 @@ -1115,9 +1115,10 @@ int target_emulate_unmap(struct se_task *task)
33 struct se_device *dev = cmd->se_dev;
34 unsigned char *buf, *ptr = NULL;
35 sector_t lba;
36 - unsigned int size = cmd->data_length, range;
37 - int ret = 0, offset;
38 - unsigned short dl, bd_dl;
39 + int size = cmd->data_length;
40 + u32 range;
41 + int ret = 0;
42 + int dl, bd_dl;
44 if (!dev->transport->do_discard) {
45 pr_err("UNMAP emulation not supported for: %s\n",
46 @@ -1126,20 +1127,19 @@ int target_emulate_unmap(struct se_task *task)
47 return -ENOSYS;
48 }
50 - /* First UNMAP block descriptor starts at 8 byte offset */
51 - offset = 8;
52 - size -= 8;
53 -
54 buf = transport_kmap_data_sg(cmd);
56 dl = get_unaligned_be16(&buf[0]);
57 bd_dl = get_unaligned_be16(&buf[2]);
59 - ptr = &buf[offset];
60 - pr_debug("UNMAP: Sub: %s Using dl: %hu bd_dl: %hu size: %hu"
61 + size = min(size - 8, bd_dl);
62 +
63 + /* First UNMAP block descriptor starts at 8 byte offset */
64 + ptr = &buf[8];
65 + pr_debug("UNMAP: Sub: %s Using dl: %u bd_dl: %u size: %u"
66 " ptr: %p\n", dev->transport->name, dl, bd_dl, size, ptr);
68 - while (size) {
69 + while (size >= 16) {
70 lba = get_unaligned_be64(&ptr[0]);
71 range = get_unaligned_be32(&ptr[8]);
72 pr_debug("UNMAP: Using lba: %llu and range: %u\n",
73 --
74 1.7.7.6