scst_lib: Allow copying between userspace and scst_cmd data structures

This patch avoids that the following call trace is reported when using the
iSER target driver with CONFIG_HARDENED_USERCOPY=y in the kernel config:

usercopy: Kernel memory exposure attempt detected from SLUB object 'scst_cmd' (offset 200, size 48)!
 ------------[ cut here ]------------
kernel BUG at /build/linux-Sci2oS/linux-4.16.16/mm/usercopy.c:100!
invalid opcode: 0000 [#1] SMP PTI
CPU: 10 PID: 6684 Comm: iscsi-scstd Tainted: P           O     4.16.0-0.bpo.2-amd64 #1 Debian 4.16.16-2~bpo9+1
Hardware name: Supermicro Super Server/X10SRH-CF, BIOS 2.0b 04/14/2017
RIP: 0010:usercopy_abort+0x69/0x80
Call Trace:
 __check_heap_object+0xee/0x120
 __check_object_size+0xb8/0x1a0
 isert_read+0x82/0x2f0 [isert_scst]
 vfs_read+0x91/0x130
 SyS_read+0x52/0xc0
 ? SyS_fcntl+0x78/0xa0
 do_syscall_64+0x6c/0x130
 entry_SYSCALL_64_after_hwframe+0x3d/0xa2

Reported-by: Carsten Aulbert <carsten.aulbert@aei.mpg.de>


git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7426 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Bart Van Assche
2018-07-18 21:19:54 +00:00
parent 51ec31562d
commit 3682fd10a2

View File

@@ -2579,6 +2579,24 @@ static int __init init_scst(void)
(p); \
})
/*
* Used for structures with fast path write access accessed from user space.
* See also commit 8eb8284b4129 ("usercopy: Prepare for usercopy whitelisting").
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0)
#define INIT_CACHEP_ALIGN_USERCOPY(p, s) ({ \
(p) = kmem_cache_create_usercopy(#s, sizeof(struct s), \
__alignof__(struct s), \
SCST_SLAB_FLAGS | SLAB_HWCACHE_ALIGN, \
0, sizeof(struct s), NULL); \
TRACE_MEM("Slab create: %s at %p size %zd", #s, (p), \
sizeof(struct s)); \
(p); \
})
#else
#define INIT_CACHEP_ALIGN_USERCOPY(p, s) INIT_CACHEP_ALIGN(p, s)
#endif
res = -ENOMEM;
if (!INIT_CACHEP(scst_mgmt_cachep, scst_mgmt_cmd))
goto out_lib_exit;
@@ -2593,7 +2611,7 @@ static int __init init_scst(void)
}
if (!INIT_CACHEP(scst_aen_cachep, scst_aen)) /* read-mostly */
goto out_destroy_sense_cache;
if (!INIT_CACHEP_ALIGN(scst_cmd_cachep, scst_cmd))
if (!INIT_CACHEP_ALIGN_USERCOPY(scst_cmd_cachep, scst_cmd))
goto out_destroy_aen_cache;
#ifdef CONFIG_SCST_MEASURE_LATENCY
if (!INIT_CACHEP_ALIGN(scst_sess_cachep, scst_session))