summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2013-12-19 14:36:11 +0100
committerNicholas Bellinger <nab@linux-iscsi.org>2014-01-10 06:48:38 +0100
commit38edd724577123c972f2264382005ac910ce747f (patch)
tree1fb950f227ff91001504c29bce32b3c9415d8352
parentdrivers: target: Mark functions and structures as static in tfc_conf.c (diff)
downloadlinux-38edd724577123c972f2264382005ac910ce747f.tar.xz
linux-38edd724577123c972f2264382005ac910ce747f.zip
target_core_alua: check for buffer overflow
When a writing to a command-provided buffer we need to ensure that we're not writing past the end of it. At the same time we need to continue processing as typically the final data length (ie the required size of the buffer) need to be returned. Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/target/target_core_alua.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c
index e73edcad7930..12da9b386169 100644
--- a/drivers/target/target_core_alua.c
+++ b/drivers/target/target_core_alua.c
@@ -96,22 +96,33 @@ target_emulate_report_referrals(struct se_cmd *cmd)
int pg_num;
off += 4;
- put_unaligned_be64(map->lba_map_first_lba, &buf[off]);
+ if (cmd->data_length > off)
+ put_unaligned_be64(map->lba_map_first_lba, &buf[off]);
off += 8;
- put_unaligned_be64(map->lba_map_last_lba, &buf[off]);
+ if (cmd->data_length > off)
+ put_unaligned_be64(map->lba_map_last_lba, &buf[off]);
off += 8;
rd_len += 20;
pg_num = 0;
list_for_each_entry(map_mem, &map->lba_map_mem_list,
lba_map_mem_list) {
- buf[off++] = map_mem->lba_map_mem_alua_state & 0x0f;
+ int alua_state = map_mem->lba_map_mem_alua_state;
+ int alua_pg_id = map_mem->lba_map_mem_alua_pg_id;
+
+ if (cmd->data_length > off)
+ buf[off] = alua_state & 0x0f;
+ off += 2;
+ if (cmd->data_length > off)
+ buf[off] = (alua_pg_id >> 8) & 0xff;
+ off++;
+ if (cmd->data_length > off)
+ buf[off] = (alua_pg_id & 0xff);
off++;
- buf[off++] = (map_mem->lba_map_mem_alua_pg_id >> 8) & 0xff;
- buf[off++] = (map_mem->lba_map_mem_alua_pg_id & 0xff);
rd_len += 4;
pg_num++;
}
- buf[desc_num] = pg_num;
+ if (cmd->data_length > desc_num)
+ buf[desc_num] = pg_num;
}
spin_unlock(&dev->t10_alua.lba_map_lock);