aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2013-12-19 08:36:11 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2014-01-10 00:48:38 -0500
commit38edd724577123c972f2264382005ac910ce747f (patch)
tree1fb950f227ff91001504c29bce32b3c9415d8352 /drivers/target
parent594c42e9bd9f70a41bf79236db985ba940d28eb8 (diff)
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>
Diffstat (limited to 'drivers/target')
-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)
96 int pg_num; 96 int pg_num;
97 97
98 off += 4; 98 off += 4;
99 put_unaligned_be64(map->lba_map_first_lba, &buf[off]); 99 if (cmd->data_length > off)
100 put_unaligned_be64(map->lba_map_first_lba, &buf[off]);
100 off += 8; 101 off += 8;
101 put_unaligned_be64(map->lba_map_last_lba, &buf[off]); 102 if (cmd->data_length > off)
103 put_unaligned_be64(map->lba_map_last_lba, &buf[off]);
102 off += 8; 104 off += 8;
103 rd_len += 20; 105 rd_len += 20;
104 pg_num = 0; 106 pg_num = 0;
105 list_for_each_entry(map_mem, &map->lba_map_mem_list, 107 list_for_each_entry(map_mem, &map->lba_map_mem_list,
106 lba_map_mem_list) { 108 lba_map_mem_list) {
107 buf[off++] = map_mem->lba_map_mem_alua_state & 0x0f; 109 int alua_state = map_mem->lba_map_mem_alua_state;
110 int alua_pg_id = map_mem->lba_map_mem_alua_pg_id;
111
112 if (cmd->data_length > off)
113 buf[off] = alua_state & 0x0f;
114 off += 2;
115 if (cmd->data_length > off)
116 buf[off] = (alua_pg_id >> 8) & 0xff;
117 off++;
118 if (cmd->data_length > off)
119 buf[off] = (alua_pg_id & 0xff);
108 off++; 120 off++;
109 buf[off++] = (map_mem->lba_map_mem_alua_pg_id >> 8) & 0xff;
110 buf[off++] = (map_mem->lba_map_mem_alua_pg_id & 0xff);
111 rd_len += 4; 121 rd_len += 4;
112 pg_num++; 122 pg_num++;
113 } 123 }
114 buf[desc_num] = pg_num; 124 if (cmd->data_length > desc_num)
125 buf[desc_num] = pg_num;
115 } 126 }
116 spin_unlock(&dev->t10_alua.lba_map_lock); 127 spin_unlock(&dev->t10_alua.lba_map_lock);
117 128