From cfe8f3cfc190feac51169a86ed6c35bc7a286576 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 19 Jul 2018 18:00:42 +0000 Subject: [PATCH 1/2] scst: Introduce a backport of kmem_cache_create_usercopy() This patch does not change any functionality. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7427 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/include/backport.h | 24 ++++++++++++++++++++++++ scst/src/scst_main.c | 4 ---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/scst/include/backport.h b/scst/include/backport.h index 2f65a9061..02372f453 100644 --- a/scst/include/backport.h +++ b/scst/include/backport.h @@ -671,6 +671,30 @@ static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags) } #endif +/* + * See also commit 8eb8284b4129 ("usercopy: Prepare for usercopy + * whitelisting"). + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) +static inline struct kmem_cache *kmem_cache_create_usercopy(const char *name, + unsigned int size, unsigned int align, + slab_flags_t flags, + unsigned int useroffset, unsigned int usersize, + void (*ctor)(void *)) +{ + return kmem_cache_create(name, size, align, flags, ctor, NULL); +} +#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0) +static inline struct kmem_cache *kmem_cache_create_usercopy(const char *name, + unsigned int size, unsigned int align, + slab_flags_t flags, + unsigned int useroffset, unsigned int usersize, + void (*ctor)(void *)) +{ + return kmem_cache_create(name, size, align, flags, ctor); +} +#endif + /* */ #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 18, 0) diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index 2573759e7..0ef90e6ea 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -2583,7 +2583,6 @@ static int __init init_scst(void) * 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), \ @@ -2593,9 +2592,6 @@ static int __init init_scst(void) 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)) From b746591148aa8688b83bc73f9ea4c0bc962283eb Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 19 Jul 2018 18:04:08 +0000 Subject: [PATCH 2/2] scst/src/scst_mem: Enable userspace copying for sgv-*-*K This patch avoids that using the iSER target driver with usercopy harderning enabled triggers the following: usercopy: Kernel memory exposure attempt detected from SLUB object 'sgv-clust-64K' (offset 200, size 48)! kernel BUG at /build/linux-Sci2oS/linux-4.16.16/mm/usercopy.c:100! invalid opcode: 0000 [#1] SMP PTI CPU: 10 PID: 6283 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/0x300 [isert_scst] vfs_read+0x91/0x130 SyS_read+0x52/0xc0 do_syscall_64+0x6c/0x130 entry_SYSCALL_64_after_hwframe+0x3d/0xa2 Reported-by: Carsten Aulbert git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@7428 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_mem.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/scst/src/scst_mem.c b/scst/src/scst_mem.c index 7d827d861..9e9f989b8 100644 --- a/scst/src/scst_mem.c +++ b/scst/src/scst_mem.c @@ -1374,15 +1374,10 @@ static void sgv_pool_init_cache(struct sgv_pool *pool, int cache_num, scnprintf(pool->cache_names[cache_num], sizeof(pool->cache_names[cache_num]), "%s-%uK", pool->name, (pages << PAGE_SHIFT) >> 10); - pool->caches[cache_num] = kmem_cache_create( - pool->cache_names[cache_num], size, - 0, per_cpu ? SCST_SLAB_FLAGS : - (SCST_SLAB_FLAGS|SLAB_HWCACHE_ALIGN), NULL -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23)) - , NULL); -#else - ); -#endif + pool->caches[cache_num] = kmem_cache_create_usercopy( + pool->cache_names[cache_num], size, 0/*align*/, per_cpu ? + SCST_SLAB_FLAGS : SCST_SLAB_FLAGS | SLAB_HWCACHE_ALIGN, + 0/*useroffset*/, size/*usersize*/, NULL); return; }