mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-21 04:31:26 +00:00
scst: Avoid that excessive data lengths cause COMPARE AND WRITE to crash
Avoid that running the libiscsi conformance tests triggers the following crash: ================================================================== BUG: KASAN: wild-memory-access in sg_cmp_elem+0x1b6/0x490 [scst] Read of size 8 at addr 0002000100000000 by task disk021_5/1231 CPU: 0 PID: 1231 Comm: disk021_5 Tainted: G O 5.0.0-rc6-dbg+ #2 Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 Call Trace: dump_stack+0x86/0xca kasan_report.cold.3+0x5/0x3b __asan_load8+0x54/0x90 sg_cmp_elem+0x1b6/0x490 [scst] sg_cmp.constprop.41+0x185/0x380 [scst] scst_cwr_read_cmd_finished+0x214/0x6d0 [scst] scst_finish_internal_cmd+0x109/0x1d0 [scst] scst_process_active_cmd+0x193/0x570 [scst] scst_process_redirect_cmd+0x214/0x300 [scst] scst_cmd_done_local+0xec/0x1f0 [scst] fileio_async_complete+0x98/0x1b0 [scst_vdisk] fileio_exec_async+0x3ac/0x430 [scst_vdisk] fileio_exec_read+0x34f/0x560 [scst_vdisk] vdev_do_job+0xf5/0x260 [scst_vdisk] fileio_exec+0x66/0x70 [scst_vdisk] scst_do_real_exec+0x11f/0x540 [scst] scst_exec_check_blocking+0x14c/0x270 [scst] scst_exec_check_sn+0x2ef/0x650 [scst] scst_process_active_cmd+0x2d2/0x570 [scst] scst_cmd_thread+0x1e3/0x6b0 [scst] kthread+0x1d2/0x1f0 ret_from_fork+0x3a/0x50 ================================================================== git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7992 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -868,6 +868,10 @@ static inline void sg_mark_end(struct scatterlist *sg)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void sg_unmark_end(struct scatterlist *sg)
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef __BACKPORT_LINUX_SCATTERLIST_H_TO_2_6_23__
|
||||
|
||||
static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
|
||||
@@ -895,6 +899,15 @@ static inline void sg_set_page(struct scatterlist *sg, struct page *page,
|
||||
#endif /* for_each_sg */
|
||||
|
||||
#endif /* __BACKPORT_LINUX_SCATTERLIST_H_TO_2_6_23__ */
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)
|
||||
/*
|
||||
* See also commit c8164d8931fd ("scatterlist: introduce sg_unmark_end";
|
||||
* v3.10).
|
||||
*/
|
||||
static inline void sg_unmark_end(struct scatterlist *sg)
|
||||
{
|
||||
sg->page_link &= ~0x02;
|
||||
}
|
||||
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) */
|
||||
|
||||
/* <linux/slab.h> */
|
||||
|
||||
@@ -1099,6 +1099,7 @@ success:
|
||||
*sgv = obj;
|
||||
|
||||
obj->sg_entries[cnt-1].length -= PAGE_ALIGN(size) - size;
|
||||
sg_mark_end(&obj->sg_entries[cnt-1]);
|
||||
|
||||
TRACE_MEM("obj=%p, sg_entries %p (size=%d, pages=%d, sg_count=%d, "
|
||||
"count=%d, last_len=%d)", obj, obj->sg_entries, size, pages,
|
||||
@@ -1224,6 +1225,7 @@ void sgv_pool_free(struct sgv_pool_obj *obj, struct scst_mem_lim *mem_lim)
|
||||
|
||||
if (obj->cache_num >= 0) {
|
||||
obj->sg_entries[obj->orig_sg].length = obj->orig_length;
|
||||
sg_unmark_end(&obj->sg_entries[obj->orig_sg]);
|
||||
sgv_put_obj(obj);
|
||||
} else {
|
||||
obj->owner_pool->alloc_fns.free_pages_fn(obj->sg_entries,
|
||||
|
||||
Reference in New Issue
Block a user