mirror of
https://gitee.com/bianbu-linux/linux-6.6
synced 2025-04-24 14:07:52 -04:00
mm, slab: ignore hardened usercopy parameters when disabled
With CONFIG_HARDENED_USERCOPY not enabled, there are no __check_heap_object() checks happening that would use the struct kmem_cache useroffset and usersize fields. Yet the fields are still initialized, preventing merging of otherwise compatible caches. Also the fields contribute to struct kmem_cache size unnecessarily when unused. Thus #ifdef them out completely when CONFIG_HARDENED_USERCOPY is disabled. In kmem_dump_obj() print object_size instead of usersize, as that's actually the intention. In a quick virtme boot test, this has reduced the number of caches in /proc/slabinfo from 131 to 111. Cc: Kees Cook <keescook@chromium.org> Signed-off-by: Vlastimil Babka <vbabka@suse.cz> Acked-by: Roman Gushchin <roman.gushchin@linux.dev> Acked-by: Mike Rapoport <rppt@linux.ibm.com> Reviewed-by: Christoph Lameter <cl@linux.com>
This commit is contained in:
parent
c18c20f162
commit
346907ceb9
5 changed files with 18 additions and 5 deletions
|
@ -80,8 +80,10 @@ struct kmem_cache {
|
|||
unsigned int *random_seq;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDENED_USERCOPY
|
||||
unsigned int useroffset; /* Usercopy region offset */
|
||||
unsigned int usersize; /* Usercopy region size */
|
||||
#endif
|
||||
|
||||
struct kmem_cache_node *node[MAX_NUMNODES];
|
||||
};
|
||||
|
|
|
@ -136,8 +136,10 @@ struct kmem_cache {
|
|||
struct kasan_cache kasan_info;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDENED_USERCOPY
|
||||
unsigned int useroffset; /* Usercopy region offset */
|
||||
unsigned int usersize; /* Usercopy region size */
|
||||
#endif
|
||||
|
||||
struct kmem_cache_node *node[MAX_NUMNODES];
|
||||
};
|
||||
|
|
|
@ -207,8 +207,6 @@ struct kmem_cache {
|
|||
unsigned int size; /* The aligned/padded/added on size */
|
||||
unsigned int align; /* Alignment as calculated */
|
||||
slab_flags_t flags; /* Active flags on the slab */
|
||||
unsigned int useroffset;/* Usercopy region offset */
|
||||
unsigned int usersize; /* Usercopy region size */
|
||||
const char *name; /* Slab name for sysfs */
|
||||
int refcount; /* Use counter */
|
||||
void (*ctor)(void *); /* Called on object slot creation */
|
||||
|
|
|
@ -143,8 +143,10 @@ int slab_unmergeable(struct kmem_cache *s)
|
|||
if (s->ctor)
|
||||
return 1;
|
||||
|
||||
#ifdef CONFIG_HARDENED_USERCOPY
|
||||
if (s->usersize)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We may have set a slab to be unmergeable during bootstrap.
|
||||
|
@ -223,8 +225,10 @@ static struct kmem_cache *create_cache(const char *name,
|
|||
s->size = s->object_size = object_size;
|
||||
s->align = align;
|
||||
s->ctor = ctor;
|
||||
#ifdef CONFIG_HARDENED_USERCOPY
|
||||
s->useroffset = useroffset;
|
||||
s->usersize = usersize;
|
||||
#endif
|
||||
|
||||
err = __kmem_cache_create(s, flags);
|
||||
if (err)
|
||||
|
@ -317,7 +321,8 @@ kmem_cache_create_usercopy(const char *name,
|
|||
flags &= CACHE_CREATE_MASK;
|
||||
|
||||
/* Fail closed on bad usersize of useroffset values. */
|
||||
if (WARN_ON(!usersize && useroffset) ||
|
||||
if (!IS_ENABLED(CONFIG_HARDENED_USERCOPY) ||
|
||||
WARN_ON(!usersize && useroffset) ||
|
||||
WARN_ON(size < usersize || size - usersize < useroffset))
|
||||
usersize = useroffset = 0;
|
||||
|
||||
|
@ -595,8 +600,8 @@ void kmem_dump_obj(void *object)
|
|||
ptroffset = ((char *)object - (char *)kp.kp_objp) - kp.kp_data_offset;
|
||||
pr_cont(" pointer offset %lu", ptroffset);
|
||||
}
|
||||
if (kp.kp_slab_cache && kp.kp_slab_cache->usersize)
|
||||
pr_cont(" size %u", kp.kp_slab_cache->usersize);
|
||||
if (kp.kp_slab_cache && kp.kp_slab_cache->object_size)
|
||||
pr_cont(" size %u", kp.kp_slab_cache->object_size);
|
||||
if (kp.kp_ret)
|
||||
pr_cont(" allocated at %pS\n", kp.kp_ret);
|
||||
else
|
||||
|
@ -640,8 +645,10 @@ void __init create_boot_cache(struct kmem_cache *s, const char *name,
|
|||
align = max(align, size);
|
||||
s->align = calculate_alignment(flags, align, size);
|
||||
|
||||
#ifdef CONFIG_HARDENED_USERCOPY
|
||||
s->useroffset = useroffset;
|
||||
s->usersize = usersize;
|
||||
#endif
|
||||
|
||||
err = __kmem_cache_create(s, flags);
|
||||
|
||||
|
|
|
@ -5502,11 +5502,13 @@ static ssize_t cache_dma_show(struct kmem_cache *s, char *buf)
|
|||
SLAB_ATTR_RO(cache_dma);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HARDENED_USERCOPY
|
||||
static ssize_t usersize_show(struct kmem_cache *s, char *buf)
|
||||
{
|
||||
return sysfs_emit(buf, "%u\n", s->usersize);
|
||||
}
|
||||
SLAB_ATTR_RO(usersize);
|
||||
#endif
|
||||
|
||||
static ssize_t destroy_by_rcu_show(struct kmem_cache *s, char *buf)
|
||||
{
|
||||
|
@ -5803,7 +5805,9 @@ static struct attribute *slab_attrs[] = {
|
|||
#ifdef CONFIG_FAILSLAB
|
||||
&failslab_attr.attr,
|
||||
#endif
|
||||
#ifdef CONFIG_HARDENED_USERCOPY
|
||||
&usersize_attr.attr,
|
||||
#endif
|
||||
#ifdef CONFIG_KFENCE
|
||||
&skip_kfence_attr.attr,
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue