diff mbox

scsi: ses: Guard against page 10 descriptors changes while processing them

Message ID 7d6df5e8dc1cb4ea10c9e7b5e500ade076549bee.1530784862.git.sbrivio@redhat.com (mailing list archive)
State Deferred
Headers show

Commit Message

Stefano Brivio July 5, 2018, 10:09 a.m. UTC
SAS page 10 descriptors might change once we re-read them in
ses_enclosure_data_process(), causing out-of-bound reads such as
this one found by KASAN:

[  321.349000] sd 1:2:0:0: [sdb] tag#0 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[  321.357723] sd 1:2:0:0: [sdb] tag#0 CDB: Read(16) 88 00 00 00 00 04 8b 92 0f 80 00 00 00 08 00 00
[  321.366604] blk_update_request: I/O error, dev sdb, sector 19521474432
[  321.373346] sd 1:2:0:0: [sdb] tag#0 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK
[  321.382074] sd 1:2:0:0: [sdb] tag#0 CDB: Read(16) 88 00 00 00 00 04 8b 92 0f 80 00 00 00 08 00 00
[  321.390963] blk_update_request: I/O error, dev sdb, sector 19521474432
[  321.397505] Buffer I/O error on dev sdb, logical block 2440184304, async page read
[  321.736854] ==================================================================
[  321.744090] BUG: KASAN: slab-out-of-bounds in ses_enclosure_data_process+0xaa1/0xea0 [ses]
[  321.752352] Read of size 1 at addr ffff8807413710b9 by task systemd-udevd/708
[  321.759485]
[  321.760990] CPU: 0 PID: 708 Comm: systemd-udevd Tainted: G          I    ------------   3.10.0-916.el7.test.x86_64 #1
[  321.771590] Hardware name: IBM  -[7147I10]-/Node 1, System Card, BIOS -[MLE179BUS-1.79]- 07/28/2013
[  321.780630] Call Trace:
[  321.783093]  [<ffffffffba8b2fb9>] dump_stack+0x19/0x1b
[  321.788236]  [<ffffffffb968701c>] print_address_description+0xfc/0x290
[  321.802162]  [<ffffffffb96873f2>] kasan_report.part.3+0x242/0x330
[  321.808255]  [<ffffffffb9687514>] __asan_report_load1_noabort+0x34/0x40
[  321.814869]  [<ffffffffc0d84441>] ses_enclosure_data_process+0xaa1/0xea0 [ses]
[  321.822094]  [<ffffffffc0d852ed>] ses_intf_add+0x85d/0xdde [ses]
[  321.828108]  [<ffffffffb9ef2449>] class_interface_register+0x219/0x330
[  321.851979]  [<ffffffffb9f9de98>] scsi_register_interface+0x38/0x50
[  321.858247]  [<ffffffffc0538011>] ses_init+0x11/0x1000 [ses]
[  321.863911]  [<ffffffffb900217a>] do_one_initcall+0x12a/0x370
[  321.869665]  [<ffffffffb935cdcd>] load_module+0x5e3d/0x7550
[  321.928619]  [<ffffffffb935e733>] SyS_init_module+0x253/0x350
[  321.986411]  [<ffffffffba8e556f>] system_call_fastpath+0x1c/0x21
[  321.999029]
[  322.000527] Allocated by task 708:
[  322.003931]  [<ffffffffb9685f63>] save_stack+0x43/0xe0
[  322.009100]  [<ffffffffb968620a>] kasan_kmalloc+0xaa/0xe0
[  322.014524]  [<ffffffffb968287e>] __kmalloc+0xee/0x270
[  322.019683]  [<ffffffffc0d85520>] ses_intf_add+0xa90/0xdde [ses]
[  322.025710]  [<ffffffffb9ef2449>] class_interface_register+0x219/0x330
[  322.032259]  [<ffffffffb9f9de98>] scsi_register_interface+0x38/0x50
[  322.038552]  [<ffffffffc0538011>] ses_init+0x11/0x1000 [ses]
[  322.044234]  [<ffffffffb900217a>] do_one_initcall+0x12a/0x370
[  322.050002]  [<ffffffffb935cdcd>] load_module+0x5e3d/0x7550
[  322.055599]  [<ffffffffb935e733>] SyS_init_module+0x253/0x350
[  322.061371]  [<ffffffffba8e556f>] system_call_fastpath+0x1c/0x21
[  322.067399]
[  322.068897] Freed by task 0:
[  322.071782] (stack is not available)
[  322.075358]
[  322.076857] The buggy address belongs to the object at ffff880741370f00
[  322.076857]  which belongs to the cache kmalloc-512 of size 512
[  322.089365] The buggy address is located 441 bytes inside of
[  322.089365]  512-byte region [ffff880741370f00, ffff880741371100)
[  322.101089] The buggy address belongs to the page:
[  322.105885] page:ffffea001d04dc00 count:1 mapcount:1638426 mapping:          (null) index:0x0
[  322.114404] page flags: 0x2fffff00004080(slab|head)
[  322.119347] page dumped because: kasan: bad access detected
[  322.124917]
[  322.126416] Memory state around the buggy address:
[  322.131212]  ffff880741370f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  322.138431]  ffff880741371000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  322.145653] >ffff880741371080: 00 00 00 00 00 00 00 fc fc fc fc fc fc fc fc fc
[  322.152871]                                         ^
[  322.157925]  ffff880741371100: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  322.165144]  ffff880741371180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
[  322.172360] ==================================================================
[  322.179577] Disabling lock debugging due to kernel taint
[  322.184954] ==================================================================
[  322.192180] BUG: KASAN: slab-out-of-bounds in ses_enclosure_data_process+0xaa1/0xea0 [ses]
[  322.200443] Read of size 1 at addr ffff8807413710bb by task systemd-udevd/708

Stop processing additional descriptors if we are already at the
end of page 10 allocated buffer.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
---
 drivers/scsi/ses.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index 62f04c0511cf..d7fcda08a802 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -605,9 +605,15 @@  static void ses_enclosure_data_process(struct enclosure_device *edev,
 			     /* these elements are optional */
 			     type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT ||
 			     type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT ||
-			     type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS))
-				addl_desc_ptr += addl_desc_ptr[1] + 2;
-
+			     type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS)) {
+				/* page 10 descriptors might have changed after
+				 * page allocation, guard against that */
+				if (addl_desc_ptr - ses_dev->page10 + 1 <
+				    ses_dev->page10_len)
+					addl_desc_ptr += addl_desc_ptr[1] + 2;
+				else
+					addl_desc_ptr = NULL;
+			}
 		}
 	}
 	kfree(buf);