* [PATCH v2 1/2] mm/slub, kunit: add SLAB_SKIP_KFENCE flag for cache creation
@ 2022-11-29 6:33 Feng Tang
2022-11-29 6:33 ` [PATCH v2 2/2] mm/slub, kunit: Add a test case for kmalloc redzone check Feng Tang
0 siblings, 1 reply; 9+ messages in thread
From: Feng Tang @ 2022-11-29 6:33 UTC (permalink / raw)
To: Vlastimil Babka, Andrew Morton, Oliver Glitta, Christoph Lameter,
Pekka Enberg, David Rientjes, Joonsoo Kim, Roman Gushchin,
Hyeonggon Yoo, Marco Elver
Cc: linux-mm, linux-kernel, Feng Tang
When kfence is enabled, the buffer allocated from the test case
could be from a kfence pool, and the operation could be also
caught and reported by kfence first, causing the case to fail.
With default kfence setting, this is very difficult to be triggered.
By changing CONFIG_KFENCE_NUM_OBJECTS from 255 to 16383, and
CONFIG_KFENCE_SAMPLE_INTERVAL from 100 to 5, the allocation from
kfence did hit 7 times in different slub_kunit cases out of 900
times of boot test.
To avoid this, initially we tried is_kfence_address() to check this
and repeated allocation till finding a non-kfence address. Vlastimil
Babka suggested SLAB_SKIP_KFENCE flag could be used to achieve this
more simply.
Signed-off-by: Feng Tang <feng.tang@intel.com>
---
lib/slub_kunit.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/lib/slub_kunit.c b/lib/slub_kunit.c
index 7a0564d7cb7a..a303adf8f11c 100644
--- a/lib/slub_kunit.c
+++ b/lib/slub_kunit.c
@@ -6,13 +6,15 @@
#include <linux/kernel.h>
#include "../mm/slab.h"
+#define DEFAULT_FLAGS (SLAB_SKIP_KFENCE | SLAB_NO_USER_FLAGS)
+
static struct kunit_resource resource;
static int slab_errors;
static void test_clobber_zone(struct kunit *test)
{
struct kmem_cache *s = kmem_cache_create("TestSlub_RZ_alloc", 64, 0,
- SLAB_RED_ZONE|SLAB_NO_USER_FLAGS, NULL);
+ SLAB_RED_ZONE|DEFAULT_FLAGS, NULL);
u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
kasan_disable_current();
@@ -30,7 +32,7 @@ static void test_clobber_zone(struct kunit *test)
static void test_next_pointer(struct kunit *test)
{
struct kmem_cache *s = kmem_cache_create("TestSlub_next_ptr_free", 64, 0,
- SLAB_POISON|SLAB_NO_USER_FLAGS, NULL);
+ SLAB_POISON|DEFAULT_FLAGS, NULL);
u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
unsigned long tmp;
unsigned long *ptr_addr;
@@ -75,7 +77,7 @@ static void test_next_pointer(struct kunit *test)
static void test_first_word(struct kunit *test)
{
struct kmem_cache *s = kmem_cache_create("TestSlub_1th_word_free", 64, 0,
- SLAB_POISON|SLAB_NO_USER_FLAGS, NULL);
+ SLAB_POISON|DEFAULT_FLAGS, NULL);
u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
kmem_cache_free(s, p);
@@ -90,7 +92,7 @@ static void test_first_word(struct kunit *test)
static void test_clobber_50th_byte(struct kunit *test)
{
struct kmem_cache *s = kmem_cache_create("TestSlub_50th_word_free", 64, 0,
- SLAB_POISON|SLAB_NO_USER_FLAGS, NULL);
+ SLAB_POISON|DEFAULT_FLAGS, NULL);
u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
kmem_cache_free(s, p);
@@ -106,7 +108,7 @@ static void test_clobber_50th_byte(struct kunit *test)
static void test_clobber_redzone_free(struct kunit *test)
{
struct kmem_cache *s = kmem_cache_create("TestSlub_RZ_free", 64, 0,
- SLAB_RED_ZONE|SLAB_NO_USER_FLAGS, NULL);
+ SLAB_RED_ZONE|DEFAULT_FLAGS, NULL);
u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
kasan_disable_current();
--
2.34.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 2/2] mm/slub, kunit: Add a test case for kmalloc redzone check
2022-11-29 6:33 [PATCH v2 1/2] mm/slub, kunit: add SLAB_SKIP_KFENCE flag for cache creation Feng Tang
@ 2022-11-29 6:33 ` Feng Tang
2022-11-29 9:31 ` Marco Elver
0 siblings, 1 reply; 9+ messages in thread
From: Feng Tang @ 2022-11-29 6:33 UTC (permalink / raw)
To: Vlastimil Babka, Andrew Morton, Oliver Glitta, Christoph Lameter,
Pekka Enberg, David Rientjes, Joonsoo Kim, Roman Gushchin,
Hyeonggon Yoo, Marco Elver
Cc: linux-mm, linux-kernel, Feng Tang
kmalloc redzone check for slub has been merged, and it's better to add
a kunit case for it, which is inspired by a real-world case as described
in commit 120ee599b5bf ("staging: octeon-usb: prevent memory corruption"):
"
octeon-hcd will crash the kernel when SLOB is used. This usually happens
after the 18-byte control transfer when a device descriptor is read.
The DMA engine is always transferring full 32-bit words and if the
transfer is shorter, some random garbage appears after the buffer.
The problem is not visible with SLUB since it rounds up the allocations
to word boundary, and the extra bytes will go undetected.
"
To avoid interrupting the normal functioning of kmalloc caches, a
kmem_cache mimicing kmalloc cache is created with similar and all
necessary flags to have kmalloc-redzone enabled, and kmalloc_trace()
is used to really test the orig_size and redzone setup.
Suggested-by: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Feng Tang <feng.tang@intel.com>
---
Changelog:
since v1:
* create a new cache mimicing kmalloc cache, reduce dependency
over global slub_debug setting (Vlastimil Babka)
lib/slub_kunit.c | 23 +++++++++++++++++++++++
mm/slab.h | 3 ++-
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/lib/slub_kunit.c b/lib/slub_kunit.c
index a303adf8f11c..dbdd656624d0 100644
--- a/lib/slub_kunit.c
+++ b/lib/slub_kunit.c
@@ -122,6 +122,28 @@ static void test_clobber_redzone_free(struct kunit *test)
kmem_cache_destroy(s);
}
+static void test_kmalloc_redzone_access(struct kunit *test)
+{
+ struct kmem_cache *s = kmem_cache_create("TestSlub_RZ_kmalloc", 32, 0,
+ SLAB_KMALLOC|SLAB_STORE_USER|SLAB_RED_ZONE|DEFAULT_FLAGS,
+ NULL);
+ u8 *p = kmalloc_trace(s, GFP_KERNEL, 18);
+
+ kasan_disable_current();
+
+ /* Suppress the -Warray-bounds warning */
+ OPTIMIZER_HIDE_VAR(p);
+ p[18] = 0xab;
+ p[19] = 0xab;
+
+ kmem_cache_free(s, p);
+ validate_slab_cache(s);
+ KUNIT_EXPECT_EQ(test, 2, slab_errors);
+
+ kasan_enable_current();
+ kmem_cache_destroy(s);
+}
+
static int test_init(struct kunit *test)
{
slab_errors = 0;
@@ -141,6 +163,7 @@ static struct kunit_case test_cases[] = {
#endif
KUNIT_CASE(test_clobber_redzone_free),
+ KUNIT_CASE(test_kmalloc_redzone_access),
{}
};
diff --git a/mm/slab.h b/mm/slab.h
index c71590f3a22b..b6cd98b16ba7 100644
--- a/mm/slab.h
+++ b/mm/slab.h
@@ -327,7 +327,8 @@ static inline slab_flags_t kmem_cache_flags(unsigned int object_size,
/* Legal flag mask for kmem_cache_create(), for various configurations */
#define SLAB_CORE_FLAGS (SLAB_HWCACHE_ALIGN | SLAB_CACHE_DMA | \
SLAB_CACHE_DMA32 | SLAB_PANIC | \
- SLAB_TYPESAFE_BY_RCU | SLAB_DEBUG_OBJECTS )
+ SLAB_KMALLOC | SLAB_SKIP_KFENCE | \
+ SLAB_TYPESAFE_BY_RCU | SLAB_DEBUG_OBJECTS)
#if defined(CONFIG_DEBUG_SLAB)
#define SLAB_DEBUG_FLAGS (SLAB_RED_ZONE | SLAB_POISON | SLAB_STORE_USER)
--
2.34.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] mm/slub, kunit: Add a test case for kmalloc redzone check
2022-11-29 6:33 ` [PATCH v2 2/2] mm/slub, kunit: Add a test case for kmalloc redzone check Feng Tang
@ 2022-11-29 9:31 ` Marco Elver
2022-11-29 11:01 ` Vlastimil Babka
0 siblings, 1 reply; 9+ messages in thread
From: Marco Elver @ 2022-11-29 9:31 UTC (permalink / raw)
To: Feng Tang
Cc: Vlastimil Babka, Andrew Morton, Oliver Glitta, Christoph Lameter,
Pekka Enberg, David Rientjes, Joonsoo Kim, Roman Gushchin,
Hyeonggon Yoo, linux-mm, linux-kernel
On Tue, 29 Nov 2022 at 07:37, Feng Tang <feng.tang@intel.com> wrote:
>
> kmalloc redzone check for slub has been merged, and it's better to add
> a kunit case for it, which is inspired by a real-world case as described
> in commit 120ee599b5bf ("staging: octeon-usb: prevent memory corruption"):
>
> "
> octeon-hcd will crash the kernel when SLOB is used. This usually happens
> after the 18-byte control transfer when a device descriptor is read.
> The DMA engine is always transferring full 32-bit words and if the
> transfer is shorter, some random garbage appears after the buffer.
> The problem is not visible with SLUB since it rounds up the allocations
> to word boundary, and the extra bytes will go undetected.
> "
>
> To avoid interrupting the normal functioning of kmalloc caches, a
> kmem_cache mimicing kmalloc cache is created with similar and all
> necessary flags to have kmalloc-redzone enabled, and kmalloc_trace()
> is used to really test the orig_size and redzone setup.
>
> Suggested-by: Vlastimil Babka <vbabka@suse.cz>
> Signed-off-by: Feng Tang <feng.tang@intel.com>
> ---
> Changelog:
>
> since v1:
> * create a new cache mimicing kmalloc cache, reduce dependency
> over global slub_debug setting (Vlastimil Babka)
>
> lib/slub_kunit.c | 23 +++++++++++++++++++++++
> mm/slab.h | 3 ++-
> 2 files changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/lib/slub_kunit.c b/lib/slub_kunit.c
> index a303adf8f11c..dbdd656624d0 100644
> --- a/lib/slub_kunit.c
> +++ b/lib/slub_kunit.c
> @@ -122,6 +122,28 @@ static void test_clobber_redzone_free(struct kunit *test)
> kmem_cache_destroy(s);
> }
>
> +static void test_kmalloc_redzone_access(struct kunit *test)
> +{
> + struct kmem_cache *s = kmem_cache_create("TestSlub_RZ_kmalloc", 32, 0,
> + SLAB_KMALLOC|SLAB_STORE_USER|SLAB_RED_ZONE|DEFAULT_FLAGS,
> + NULL);
> + u8 *p = kmalloc_trace(s, GFP_KERNEL, 18);
> +
> + kasan_disable_current();
> +
> + /* Suppress the -Warray-bounds warning */
> + OPTIMIZER_HIDE_VAR(p);
> + p[18] = 0xab;
> + p[19] = 0xab;
> +
> + kmem_cache_free(s, p);
> + validate_slab_cache(s);
> + KUNIT_EXPECT_EQ(test, 2, slab_errors);
> +
> + kasan_enable_current();
> + kmem_cache_destroy(s);
> +}
> +
> static int test_init(struct kunit *test)
> {
> slab_errors = 0;
> @@ -141,6 +163,7 @@ static struct kunit_case test_cases[] = {
> #endif
>
> KUNIT_CASE(test_clobber_redzone_free),
> + KUNIT_CASE(test_kmalloc_redzone_access),
> {}
> };
>
> diff --git a/mm/slab.h b/mm/slab.h
> index c71590f3a22b..b6cd98b16ba7 100644
> --- a/mm/slab.h
> +++ b/mm/slab.h
> @@ -327,7 +327,8 @@ static inline slab_flags_t kmem_cache_flags(unsigned int object_size,
> /* Legal flag mask for kmem_cache_create(), for various configurations */
> #define SLAB_CORE_FLAGS (SLAB_HWCACHE_ALIGN | SLAB_CACHE_DMA | \
> SLAB_CACHE_DMA32 | SLAB_PANIC | \
> - SLAB_TYPESAFE_BY_RCU | SLAB_DEBUG_OBJECTS )
> + SLAB_KMALLOC | SLAB_SKIP_KFENCE | \
> + SLAB_TYPESAFE_BY_RCU | SLAB_DEBUG_OBJECTS)
Shouldn't this hunk be in the previous patch, otherwise that patch
alone will fail?
This will also make SLAB_SKIP_KFENCE generally available to be used
for cache creation. This is a significant change, and before it wasn't
possible. Perhaps add a brief note to the commit message (or have a
separate patch). We were trying to avoid making this possible, as it
might be abused - however, given it's required for tests like these, I
suppose there's no way around it.
Thanks,
-- Marco
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] mm/slub, kunit: Add a test case for kmalloc redzone check
2022-11-29 9:31 ` Marco Elver
@ 2022-11-29 11:01 ` Vlastimil Babka
2022-11-29 11:48 ` Marco Elver
0 siblings, 1 reply; 9+ messages in thread
From: Vlastimil Babka @ 2022-11-29 11:01 UTC (permalink / raw)
To: Marco Elver, Feng Tang
Cc: Andrew Morton, Oliver Glitta, Christoph Lameter, Pekka Enberg,
David Rientjes, Joonsoo Kim, Roman Gushchin, Hyeonggon Yoo,
linux-mm, linux-kernel
On 11/29/22 10:31, Marco Elver wrote:
> On Tue, 29 Nov 2022 at 07:37, Feng Tang <feng.tang@intel.com> wrote:
>>
>> kmalloc redzone check for slub has been merged, and it's better to add
>> a kunit case for it, which is inspired by a real-world case as described
>> in commit 120ee599b5bf ("staging: octeon-usb: prevent memory corruption"):
>>
>> "
>> octeon-hcd will crash the kernel when SLOB is used. This usually happens
>> after the 18-byte control transfer when a device descriptor is read.
>> The DMA engine is always transferring full 32-bit words and if the
>> transfer is shorter, some random garbage appears after the buffer.
>> The problem is not visible with SLUB since it rounds up the allocations
>> to word boundary, and the extra bytes will go undetected.
>> "
>>
>> To avoid interrupting the normal functioning of kmalloc caches, a
>> kmem_cache mimicing kmalloc cache is created with similar and all
>> necessary flags to have kmalloc-redzone enabled, and kmalloc_trace()
>> is used to really test the orig_size and redzone setup.
>>
>> Suggested-by: Vlastimil Babka <vbabka@suse.cz>
>> Signed-off-by: Feng Tang <feng.tang@intel.com>
>> ---
>> Changelog:
>>
>> since v1:
>> * create a new cache mimicing kmalloc cache, reduce dependency
>> over global slub_debug setting (Vlastimil Babka)
>>
>> lib/slub_kunit.c | 23 +++++++++++++++++++++++
>> mm/slab.h | 3 ++-
>> 2 files changed, 25 insertions(+), 1 deletion(-)
>>
>> diff --git a/lib/slub_kunit.c b/lib/slub_kunit.c
>> index a303adf8f11c..dbdd656624d0 100644
>> --- a/lib/slub_kunit.c
>> +++ b/lib/slub_kunit.c
>> @@ -122,6 +122,28 @@ static void test_clobber_redzone_free(struct kunit *test)
>> kmem_cache_destroy(s);
>> }
>>
>> +static void test_kmalloc_redzone_access(struct kunit *test)
>> +{
>> + struct kmem_cache *s = kmem_cache_create("TestSlub_RZ_kmalloc", 32, 0,
>> + SLAB_KMALLOC|SLAB_STORE_USER|SLAB_RED_ZONE|DEFAULT_FLAGS,
>> + NULL);
>> + u8 *p = kmalloc_trace(s, GFP_KERNEL, 18);
>> +
>> + kasan_disable_current();
>> +
>> + /* Suppress the -Warray-bounds warning */
>> + OPTIMIZER_HIDE_VAR(p);
>> + p[18] = 0xab;
>> + p[19] = 0xab;
>> +
>> + kmem_cache_free(s, p);
>> + validate_slab_cache(s);
>> + KUNIT_EXPECT_EQ(test, 2, slab_errors);
>> +
>> + kasan_enable_current();
>> + kmem_cache_destroy(s);
>> +}
>> +
>> static int test_init(struct kunit *test)
>> {
>> slab_errors = 0;
>> @@ -141,6 +163,7 @@ static struct kunit_case test_cases[] = {
>> #endif
>>
>> KUNIT_CASE(test_clobber_redzone_free),
>> + KUNIT_CASE(test_kmalloc_redzone_access),
>> {}
>> };
>>
>> diff --git a/mm/slab.h b/mm/slab.h
>> index c71590f3a22b..b6cd98b16ba7 100644
>> --- a/mm/slab.h
>> +++ b/mm/slab.h
>> @@ -327,7 +327,8 @@ static inline slab_flags_t kmem_cache_flags(unsigned int object_size,
>> /* Legal flag mask for kmem_cache_create(), for various configurations */
>> #define SLAB_CORE_FLAGS (SLAB_HWCACHE_ALIGN | SLAB_CACHE_DMA | \
>> SLAB_CACHE_DMA32 | SLAB_PANIC | \
>> - SLAB_TYPESAFE_BY_RCU | SLAB_DEBUG_OBJECTS )
>> + SLAB_KMALLOC | SLAB_SKIP_KFENCE | \
>> + SLAB_TYPESAFE_BY_RCU | SLAB_DEBUG_OBJECTS)
>
> Shouldn't this hunk be in the previous patch, otherwise that patch
> alone will fail?
Good point.
> This will also make SLAB_SKIP_KFENCE generally available to be used
> for cache creation. This is a significant change, and before it wasn't
> possible. Perhaps add a brief note to the commit message (or have a
> separate patch). We were trying to avoid making this possible, as it
> might be abused - however, given it's required for tests like these, I
> suppose there's no way around it.
For SLAB_SKIP_KFENCE, we could also add the flag after creation to avoid
this trouble? After all there is a sysfs file to control it at runtime
anyway (via skip_kfence_store()).
In that case patch 1 would have to wrap kmem_cache_create() and the flag
addition with a new function to avoid repeating. That function could also be
adding SLAB_NO_USER_FLAGS to kmem_cache_create(), instead of the #define
DEFAULT_FLAGS.
For SLAB_KMALLOC there's probably no such way unless we abuse the internal
APIs even more and call e.g. create_boot_cache() instead of
kmem_cache_create(). But that one is __init, so probably not. If we do
instead allow the flag, I wouldn't add it to SLAB_CORE_FLAGS but rather
SLAB_CACHE_FLAGS and SLAB_FLAGS_PERMITTED.
> Thanks,
> -- Marco
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] mm/slub, kunit: Add a test case for kmalloc redzone check
2022-11-29 11:01 ` Vlastimil Babka
@ 2022-11-29 11:48 ` Marco Elver
2022-11-29 12:02 ` Vlastimil Babka
0 siblings, 1 reply; 9+ messages in thread
From: Marco Elver @ 2022-11-29 11:48 UTC (permalink / raw)
To: Vlastimil Babka
Cc: Feng Tang, Andrew Morton, Oliver Glitta, Christoph Lameter,
Pekka Enberg, David Rientjes, Joonsoo Kim, Roman Gushchin,
Hyeonggon Yoo, linux-mm, linux-kernel
On Tue, 29 Nov 2022 at 12:01, Vlastimil Babka <vbabka@suse.cz> wrote:
>
> On 11/29/22 10:31, Marco Elver wrote:
> > On Tue, 29 Nov 2022 at 07:37, Feng Tang <feng.tang@intel.com> wrote:
> >> diff --git a/mm/slab.h b/mm/slab.h
> >> index c71590f3a22b..b6cd98b16ba7 100644
> >> --- a/mm/slab.h
> >> +++ b/mm/slab.h
> >> @@ -327,7 +327,8 @@ static inline slab_flags_t kmem_cache_flags(unsigned int object_size,
> >> /* Legal flag mask for kmem_cache_create(), for various configurations */
> >> #define SLAB_CORE_FLAGS (SLAB_HWCACHE_ALIGN | SLAB_CACHE_DMA | \
> >> SLAB_CACHE_DMA32 | SLAB_PANIC | \
> >> - SLAB_TYPESAFE_BY_RCU | SLAB_DEBUG_OBJECTS )
> >> + SLAB_KMALLOC | SLAB_SKIP_KFENCE | \
> >> + SLAB_TYPESAFE_BY_RCU | SLAB_DEBUG_OBJECTS)
> >
> > Shouldn't this hunk be in the previous patch, otherwise that patch
> > alone will fail?
>
> Good point.
>
> > This will also make SLAB_SKIP_KFENCE generally available to be used
> > for cache creation. This is a significant change, and before it wasn't
> > possible. Perhaps add a brief note to the commit message (or have a
> > separate patch). We were trying to avoid making this possible, as it
> > might be abused - however, given it's required for tests like these, I
> > suppose there's no way around it.
>
> For SLAB_SKIP_KFENCE, we could also add the flag after creation to avoid
> this trouble? After all there is a sysfs file to control it at runtime
> anyway (via skip_kfence_store()).
> In that case patch 1 would have to wrap kmem_cache_create() and the flag
> addition with a new function to avoid repeating. That function could also be
> adding SLAB_NO_USER_FLAGS to kmem_cache_create(), instead of the #define
> DEFAULT_FLAGS.
I wouldn't overcomplicate it, all we need is a way to say "this flag
should not be used directly" - and only have it available via an
indirect step. Availability via sysfs is one such step.
And for tests, there are 2 options:
1. we could provide a function "kmem_cache_set_test_flags(cache,
gfp_flags)" and define SLAB_TEST_FLAGS (which would include
SLAB_SKIP_KFENCE). This still allows to set it generally, but should
make abuse less likely due to the "test" in the name of that function.
2. just set it directly, s->flags |= SLAB_SKIP_KFENCE.
If you're fine with #2, that seems simplest and would be my preference.
> For SLAB_KMALLOC there's probably no such way unless we abuse the internal
> APIs even more and call e.g. create_boot_cache() instead of
> kmem_cache_create(). But that one is __init, so probably not. If we do
> instead allow the flag, I wouldn't add it to SLAB_CORE_FLAGS but rather
> SLAB_CACHE_FLAGS and SLAB_FLAGS_PERMITTED.
I'd probably go with the simplest solution here.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] mm/slub, kunit: Add a test case for kmalloc redzone check
2022-11-29 11:48 ` Marco Elver
@ 2022-11-29 12:02 ` Vlastimil Babka
2022-11-29 12:50 ` Feng Tang
0 siblings, 1 reply; 9+ messages in thread
From: Vlastimil Babka @ 2022-11-29 12:02 UTC (permalink / raw)
To: Marco Elver
Cc: Feng Tang, Andrew Morton, Oliver Glitta, Christoph Lameter,
Pekka Enberg, David Rientjes, Joonsoo Kim, Roman Gushchin,
Hyeonggon Yoo, linux-mm, linux-kernel
On 11/29/22 12:48, Marco Elver wrote:
> On Tue, 29 Nov 2022 at 12:01, Vlastimil Babka <vbabka@suse.cz> wrote:
>>
>> On 11/29/22 10:31, Marco Elver wrote:
>> > On Tue, 29 Nov 2022 at 07:37, Feng Tang <feng.tang@intel.com> wrote:
>
>> For SLAB_SKIP_KFENCE, we could also add the flag after creation to avoid
>> this trouble? After all there is a sysfs file to control it at runtime
>> anyway (via skip_kfence_store()).
>> In that case patch 1 would have to wrap kmem_cache_create() and the flag
>> addition with a new function to avoid repeating. That function could also be
>> adding SLAB_NO_USER_FLAGS to kmem_cache_create(), instead of the #define
>> DEFAULT_FLAGS.
>
> I wouldn't overcomplicate it, all we need is a way to say "this flag
> should not be used directly" - and only have it available via an
> indirect step. Availability via sysfs is one such step.
>
> And for tests, there are 2 options:
>
> 1. we could provide a function "kmem_cache_set_test_flags(cache,
> gfp_flags)" and define SLAB_TEST_FLAGS (which would include
> SLAB_SKIP_KFENCE). This still allows to set it generally, but should
> make abuse less likely due to the "test" in the name of that function.
>
> 2. just set it directly, s->flags |= SLAB_SKIP_KFENCE.
>
> If you're fine with #2, that seems simplest and would be my preference.
Yeah, that's what I meant. But slub_kunit.c could still have own internal
cache creation function so the "|SLAB_NO_USER_FLAGS" and "s->flags |=
SLAB_SKIP_KFENCE" is not repeated X times.
>
>> For SLAB_KMALLOC there's probably no such way unless we abuse the internal
>> APIs even more and call e.g. create_boot_cache() instead of
>> kmem_cache_create(). But that one is __init, so probably not. If we do
>> instead allow the flag, I wouldn't add it to SLAB_CORE_FLAGS but rather
>> SLAB_CACHE_FLAGS and SLAB_FLAGS_PERMITTED.
>
> I'd probably go with the simplest solution here.
Agreed.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] mm/slub, kunit: Add a test case for kmalloc redzone check
2022-11-29 12:02 ` Vlastimil Babka
@ 2022-11-29 12:50 ` Feng Tang
2022-11-29 12:56 ` Marco Elver
0 siblings, 1 reply; 9+ messages in thread
From: Feng Tang @ 2022-11-29 12:50 UTC (permalink / raw)
To: Vlastimil Babka
Cc: Marco Elver, Andrew Morton, Oliver Glitta, Christoph Lameter,
Pekka Enberg, David Rientjes, Joonsoo Kim, Roman Gushchin,
Hyeonggon Yoo, linux-mm, linux-kernel
On Tue, Nov 29, 2022 at 08:02:51PM +0800, Vlastimil Babka wrote:
> On 11/29/22 12:48, Marco Elver wrote:
> > On Tue, 29 Nov 2022 at 12:01, Vlastimil Babka <vbabka@suse.cz> wrote:
> >>
> >> On 11/29/22 10:31, Marco Elver wrote:
> >> > On Tue, 29 Nov 2022 at 07:37, Feng Tang <feng.tang@intel.com> wrote:
> >
> >> For SLAB_SKIP_KFENCE, we could also add the flag after creation to avoid
> >> this trouble? After all there is a sysfs file to control it at runtime
> >> anyway (via skip_kfence_store()).
> >> In that case patch 1 would have to wrap kmem_cache_create() and the flag
> >> addition with a new function to avoid repeating. That function could also be
> >> adding SLAB_NO_USER_FLAGS to kmem_cache_create(), instead of the #define
> >> DEFAULT_FLAGS.
> >
> > I wouldn't overcomplicate it, all we need is a way to say "this flag
> > should not be used directly" - and only have it available via an
> > indirect step. Availability via sysfs is one such step.
> >
> > And for tests, there are 2 options:
> >
> > 1. we could provide a function "kmem_cache_set_test_flags(cache,
> > gfp_flags)" and define SLAB_TEST_FLAGS (which would include
> > SLAB_SKIP_KFENCE). This still allows to set it generally, but should
> > make abuse less likely due to the "test" in the name of that function.
> >
> > 2. just set it directly, s->flags |= SLAB_SKIP_KFENCE.
> >
> > If you're fine with #2, that seems simplest and would be my preference.
>
> Yeah, that's what I meant. But slub_kunit.c could still have own internal
> cache creation function so the "|SLAB_NO_USER_FLAGS" and "s->flags |=
> SLAB_SKIP_KFENCE" is not repeated X times.
I just quickly tried adding a new wrapper, like
struct kmem_cache *debug_kmem_cache_create(const char *name, unsigned int size,
unsigned int align, slab_flags_t flags,
void (*ctor)(void *), slab_flags_t debug_flags);
and found that, IIUC, both SLAB_KMALLOC and SLAB_NO_USER are creation
time flag, while SLAB_SKIP_KFENCE is an allocation runtime flag which
could be set after creation.
So how about use the initial suggestion from Vlastimil to set the
SKIP_KFENCE flag through an internal wrapper in slub_kunit.c?
/* Only for debug and test use, to skip kfence allocation */
static inline void kmem_cache_skip_kfence(struct kmem_cache *s)
{
s->flags |= SLAB_SKIP_KFENCE;
}
Thanks,
Feng
> >
> >> For SLAB_KMALLOC there's probably no such way unless we abuse the internal
> >> APIs even more and call e.g. create_boot_cache() instead of
> >> kmem_cache_create(). But that one is __init, so probably not. If we do
> >> instead allow the flag, I wouldn't add it to SLAB_CORE_FLAGS but rather
> >> SLAB_CACHE_FLAGS and SLAB_FLAGS_PERMITTED.
> >
> > I'd probably go with the simplest solution here.
>
> Agreed.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] mm/slub, kunit: Add a test case for kmalloc redzone check
2022-11-29 12:50 ` Feng Tang
@ 2022-11-29 12:56 ` Marco Elver
2022-11-29 17:48 ` Vlastimil Babka
0 siblings, 1 reply; 9+ messages in thread
From: Marco Elver @ 2022-11-29 12:56 UTC (permalink / raw)
To: Feng Tang
Cc: Vlastimil Babka, Andrew Morton, Oliver Glitta, Christoph Lameter,
Pekka Enberg, David Rientjes, Joonsoo Kim, Roman Gushchin,
Hyeonggon Yoo, linux-mm, linux-kernel
On Tue, 29 Nov 2022 at 13:53, Feng Tang <feng.tang@intel.com> wrote:
>
> On Tue, Nov 29, 2022 at 08:02:51PM +0800, Vlastimil Babka wrote:
> > On 11/29/22 12:48, Marco Elver wrote:
> > > On Tue, 29 Nov 2022 at 12:01, Vlastimil Babka <vbabka@suse.cz> wrote:
> > >>
> > >> On 11/29/22 10:31, Marco Elver wrote:
> > >> > On Tue, 29 Nov 2022 at 07:37, Feng Tang <feng.tang@intel.com> wrote:
> > >
> > >> For SLAB_SKIP_KFENCE, we could also add the flag after creation to avoid
> > >> this trouble? After all there is a sysfs file to control it at runtime
> > >> anyway (via skip_kfence_store()).
> > >> In that case patch 1 would have to wrap kmem_cache_create() and the flag
> > >> addition with a new function to avoid repeating. That function could also be
> > >> adding SLAB_NO_USER_FLAGS to kmem_cache_create(), instead of the #define
> > >> DEFAULT_FLAGS.
> > >
> > > I wouldn't overcomplicate it, all we need is a way to say "this flag
> > > should not be used directly" - and only have it available via an
> > > indirect step. Availability via sysfs is one such step.
> > >
> > > And for tests, there are 2 options:
> > >
> > > 1. we could provide a function "kmem_cache_set_test_flags(cache,
> > > gfp_flags)" and define SLAB_TEST_FLAGS (which would include
> > > SLAB_SKIP_KFENCE). This still allows to set it generally, but should
> > > make abuse less likely due to the "test" in the name of that function.
> > >
> > > 2. just set it directly, s->flags |= SLAB_SKIP_KFENCE.
> > >
> > > If you're fine with #2, that seems simplest and would be my preference.
> >
> > Yeah, that's what I meant. But slub_kunit.c could still have own internal
> > cache creation function so the "|SLAB_NO_USER_FLAGS" and "s->flags |=
> > SLAB_SKIP_KFENCE" is not repeated X times.
>
> I just quickly tried adding a new wrapper, like
>
> struct kmem_cache *debug_kmem_cache_create(const char *name, unsigned int size,
> unsigned int align, slab_flags_t flags,
> void (*ctor)(void *), slab_flags_t debug_flags);
>
> and found that, IIUC, both SLAB_KMALLOC and SLAB_NO_USER are creation
> time flag, while SLAB_SKIP_KFENCE is an allocation runtime flag which
> could be set after creation.
>
> So how about use the initial suggestion from Vlastimil to set the
> SKIP_KFENCE flag through an internal wrapper in slub_kunit.c?
>
> /* Only for debug and test use, to skip kfence allocation */
> static inline void kmem_cache_skip_kfence(struct kmem_cache *s)
> {
> s->flags |= SLAB_SKIP_KFENCE;
> }
Yes, that's fine - as long as it's local to slub_kunit.c, this seems
very reasonable.
Thanks,
-- Marco
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] mm/slub, kunit: Add a test case for kmalloc redzone check
2022-11-29 12:56 ` Marco Elver
@ 2022-11-29 17:48 ` Vlastimil Babka
0 siblings, 0 replies; 9+ messages in thread
From: Vlastimil Babka @ 2022-11-29 17:48 UTC (permalink / raw)
To: Marco Elver, Feng Tang
Cc: Andrew Morton, Oliver Glitta, Christoph Lameter, Pekka Enberg,
David Rientjes, Joonsoo Kim, Roman Gushchin, Hyeonggon Yoo,
linux-mm, linux-kernel
On 11/29/22 13:56, Marco Elver wrote:
> On Tue, 29 Nov 2022 at 13:53, Feng Tang <feng.tang@intel.com> wrote:
>>
>> On Tue, Nov 29, 2022 at 08:02:51PM +0800, Vlastimil Babka wrote:
>> > On 11/29/22 12:48, Marco Elver wrote:
>> > > On Tue, 29 Nov 2022 at 12:01, Vlastimil Babka <vbabka@suse.cz> wrote:
>> > >>
>> > >> On 11/29/22 10:31, Marco Elver wrote:
>> > >> > On Tue, 29 Nov 2022 at 07:37, Feng Tang <feng.tang@intel.com> wrote:
>> > >
>> > >> For SLAB_SKIP_KFENCE, we could also add the flag after creation to avoid
>> > >> this trouble? After all there is a sysfs file to control it at runtime
>> > >> anyway (via skip_kfence_store()).
>> > >> In that case patch 1 would have to wrap kmem_cache_create() and the flag
>> > >> addition with a new function to avoid repeating. That function could also be
>> > >> adding SLAB_NO_USER_FLAGS to kmem_cache_create(), instead of the #define
>> > >> DEFAULT_FLAGS.
>> > >
>> > > I wouldn't overcomplicate it, all we need is a way to say "this flag
>> > > should not be used directly" - and only have it available via an
>> > > indirect step. Availability via sysfs is one such step.
>> > >
>> > > And for tests, there are 2 options:
>> > >
>> > > 1. we could provide a function "kmem_cache_set_test_flags(cache,
>> > > gfp_flags)" and define SLAB_TEST_FLAGS (which would include
>> > > SLAB_SKIP_KFENCE). This still allows to set it generally, but should
>> > > make abuse less likely due to the "test" in the name of that function.
>> > >
>> > > 2. just set it directly, s->flags |= SLAB_SKIP_KFENCE.
>> > >
>> > > If you're fine with #2, that seems simplest and would be my preference.
>> >
>> > Yeah, that's what I meant. But slub_kunit.c could still have own internal
>> > cache creation function so the "|SLAB_NO_USER_FLAGS" and "s->flags |=
>> > SLAB_SKIP_KFENCE" is not repeated X times.
>>
>> I just quickly tried adding a new wrapper, like
>>
>> struct kmem_cache *debug_kmem_cache_create(const char *name, unsigned int size,
>> unsigned int align, slab_flags_t flags,
>> void (*ctor)(void *), slab_flags_t debug_flags);
>>
>> and found that, IIUC, both SLAB_KMALLOC and SLAB_NO_USER are creation
>> time flag, while SLAB_SKIP_KFENCE is an allocation runtime flag which
>> could be set after creation.
>>
>> So how about use the initial suggestion from Vlastimil to set the
>> SKIP_KFENCE flag through an internal wrapper in slub_kunit.c?
>>
>> /* Only for debug and test use, to skip kfence allocation */
>> static inline void kmem_cache_skip_kfence(struct kmem_cache *s)
>> {
>> s->flags |= SLAB_SKIP_KFENCE;
>> }
>
> Yes, that's fine - as long as it's local to slub_kunit.c, this seems
> very reasonable.
Wrapping just |= SLAB_SKIP_KFENCE won't help that much as you'd need to add
a call to kmem_cache_skip_kfence() after each kmem_cache_create() in
slub_kunit.c. That's why I propose a wrapper, *also internally defined in
slub_kunit.c*, that calls kmem_cache_create() with flags
|SLAB_NO_USER_FLAGS, then does s->flags |= SLAB_SKIP_KFENCE; then returns s.
At this point said wrapper wouldn't even need align and ctor parameters and
could pass 0 and NULL to kmem_cache_create() by itself, as no test uses
different values.
> Thanks,
> -- Marco
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2022-11-29 17:48 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-29 6:33 [PATCH v2 1/2] mm/slub, kunit: add SLAB_SKIP_KFENCE flag for cache creation Feng Tang
2022-11-29 6:33 ` [PATCH v2 2/2] mm/slub, kunit: Add a test case for kmalloc redzone check Feng Tang
2022-11-29 9:31 ` Marco Elver
2022-11-29 11:01 ` Vlastimil Babka
2022-11-29 11:48 ` Marco Elver
2022-11-29 12:02 ` Vlastimil Babka
2022-11-29 12:50 ` Feng Tang
2022-11-29 12:56 ` Marco Elver
2022-11-29 17:48 ` Vlastimil Babka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox