]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
target_core_alua: check for buffer overflow
authorHannes Reinecke <hare@suse.de>
Thu, 19 Dec 2013 13:36:11 +0000 (14:36 +0100)
committerNicholas Bellinger <nab@linux-iscsi.org>
Thu, 19 Dec 2013 21:40:48 +0000 (13:40 -0800)
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>
drivers/target/target_core_alua.c

index 104847eefa6e3918edc7fb662678d85a8c8e5a8a..9b1856d09f21beb6581de669f6f0c16d48fe4a15 100644 (file)
@@ -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);