diff options
author | Calvin Owens <calvinowens@fb.com> | 2016-03-18 15:45:42 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-03-23 16:33:09 -0400 |
commit | 5ec8a1753bc29efa7e4b1391d691c9c719b30257 (patch) | |
tree | 663b323667e1b920c28e7a1d6db67ec3505c206f | |
parent | 548f0e65a38f36976260a63ff4acfa9f3b17307d (diff) |
mpt3sas: Don't overreach ioc->reply_post[] during initialization
In _base_make_ioc_operational(), we walk ioc->reply_queue_list and pull
a pointer out of successive elements of ioc->reply_post[] for each entry
in that list if RDPQ is enabled.
Since the code pulls the pointer for the next iteration at the bottom of
the loop, it triggers the a KASAN dump on the final iteration:
BUG: KASAN: slab-out-of-bounds in _base_make_ioc_operational+0x47b7/0x47e0 [mpt3sas] at addr ffff880754816ab0
Read of size 8 by task modprobe/305
<snip>
Call Trace:
[<ffffffff81dfc591>] dump_stack+0x4d/0x6c
[<ffffffff814c9689>] print_trailer+0xf9/0x150
[<ffffffff814ceda4>] object_err+0x34/0x40
[<ffffffff814d1231>] kasan_report_error+0x221/0x530
[<ffffffff814d1673>] __asan_report_load8_noabort+0x43/0x50
[<ffffffffa0043637>] _base_make_ioc_operational+0x47b7/0x47e0 [mpt3sas]
[<ffffffffa0049a51>] mpt3sas_base_attach+0x1991/0x2120 [mpt3sas]
[<ffffffffa0053c93>] _scsih_probe+0xeb3/0x16b0 [mpt3sas]
[<ffffffff81ebd047>] local_pci_probe+0xc7/0x170
[<ffffffff81ebf2cf>] pci_device_probe+0x20f/0x290
[<ffffffff820d50cd>] really_probe+0x17d/0x600
[<ffffffff820d56a3>] __driver_attach+0x153/0x190
[<ffffffff820cffac>] bus_for_each_dev+0x11c/0x1a0
[<ffffffff820d421d>] driver_attach+0x3d/0x50
[<ffffffff820d378a>] bus_add_driver+0x44a/0x5f0
[<ffffffff820d666c>] driver_register+0x18c/0x3b0
[<ffffffff81ebcb76>] __pci_register_driver+0x156/0x200
[<ffffffffa00c8135>] _mpt3sas_init+0x135/0x1000 [mpt3sas]
[<ffffffff81000423>] do_one_initcall+0x113/0x2b0
[<ffffffff813caa5a>] do_init_module+0x1d0/0x4d8
[<ffffffff81273909>] load_module+0x6729/0x8dc0
[<ffffffff81276123>] SYSC_init_module+0x183/0x1a0
[<ffffffff8127625e>] SyS_init_module+0xe/0x10
[<ffffffff828fe7d7>] entry_SYSCALL_64_fastpath+0x12/0x6a
Fix this by pulling the value at the beginning of the loop.
Signed-off-by: Calvin Owens <calvinowens@fb.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Reviewed-by: Jens Axboe <axboe@fb.com>
Acked-by: Chaitra Basappa <chaitra.basappa@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/mpt3sas/mpt3sas_base.c | 33 |
1 files changed, 16 insertions, 17 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index e4db5fb3239a..8c44b9c424af 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c | |||
@@ -5030,7 +5030,7 @@ _base_make_ioc_ready(struct MPT3SAS_ADAPTER *ioc, int sleep_flag, | |||
5030 | static int | 5030 | static int |
5031 | _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) | 5031 | _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) |
5032 | { | 5032 | { |
5033 | int r, i; | 5033 | int r, i, index; |
5034 | unsigned long flags; | 5034 | unsigned long flags; |
5035 | u32 reply_address; | 5035 | u32 reply_address; |
5036 | u16 smid; | 5036 | u16 smid; |
@@ -5039,8 +5039,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) | |||
5039 | struct _event_ack_list *delayed_event_ack, *delayed_event_ack_next; | 5039 | struct _event_ack_list *delayed_event_ack, *delayed_event_ack_next; |
5040 | u8 hide_flag; | 5040 | u8 hide_flag; |
5041 | struct adapter_reply_queue *reply_q; | 5041 | struct adapter_reply_queue *reply_q; |
5042 | long reply_post_free; | 5042 | Mpi2ReplyDescriptorsUnion_t *reply_post_free_contig; |
5043 | u32 reply_post_free_sz, index = 0; | ||
5044 | 5043 | ||
5045 | dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, | 5044 | dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, |
5046 | __func__)); | 5045 | __func__)); |
@@ -5124,27 +5123,27 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) | |||
5124 | _base_assign_reply_queues(ioc); | 5123 | _base_assign_reply_queues(ioc); |
5125 | 5124 | ||
5126 | /* initialize Reply Post Free Queue */ | 5125 | /* initialize Reply Post Free Queue */ |
5127 | reply_post_free_sz = ioc->reply_post_queue_depth * | 5126 | index = 0; |
5128 | sizeof(Mpi2DefaultReplyDescriptor_t); | 5127 | reply_post_free_contig = ioc->reply_post[0].reply_post_free; |
5129 | reply_post_free = (long)ioc->reply_post[index].reply_post_free; | ||
5130 | list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { | 5128 | list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { |
5129 | /* | ||
5130 | * If RDPQ is enabled, switch to the next allocation. | ||
5131 | * Otherwise advance within the contiguous region. | ||
5132 | */ | ||
5133 | if (ioc->rdpq_array_enable) { | ||
5134 | reply_q->reply_post_free = | ||
5135 | ioc->reply_post[index++].reply_post_free; | ||
5136 | } else { | ||
5137 | reply_q->reply_post_free = reply_post_free_contig; | ||
5138 | reply_post_free_contig += ioc->reply_post_queue_depth; | ||
5139 | } | ||
5140 | |||
5131 | reply_q->reply_post_host_index = 0; | 5141 | reply_q->reply_post_host_index = 0; |
5132 | reply_q->reply_post_free = (Mpi2ReplyDescriptorsUnion_t *) | ||
5133 | reply_post_free; | ||
5134 | for (i = 0; i < ioc->reply_post_queue_depth; i++) | 5142 | for (i = 0; i < ioc->reply_post_queue_depth; i++) |
5135 | reply_q->reply_post_free[i].Words = | 5143 | reply_q->reply_post_free[i].Words = |
5136 | cpu_to_le64(ULLONG_MAX); | 5144 | cpu_to_le64(ULLONG_MAX); |
5137 | if (!_base_is_controller_msix_enabled(ioc)) | 5145 | if (!_base_is_controller_msix_enabled(ioc)) |
5138 | goto skip_init_reply_post_free_queue; | 5146 | goto skip_init_reply_post_free_queue; |
5139 | /* | ||
5140 | * If RDPQ is enabled, switch to the next allocation. | ||
5141 | * Otherwise advance within the contiguous region. | ||
5142 | */ | ||
5143 | if (ioc->rdpq_array_enable) | ||
5144 | reply_post_free = (long) | ||
5145 | ioc->reply_post[++index].reply_post_free; | ||
5146 | else | ||
5147 | reply_post_free += reply_post_free_sz; | ||
5148 | } | 5147 | } |
5149 | skip_init_reply_post_free_queue: | 5148 | skip_init_reply_post_free_queue: |
5150 | 5149 | ||