2023-11-19 20:52:16

by Juntong Deng

[permalink] [raw]
Subject: [PATCH] kasan: Improve free meta storage in Generic KASAN

Currently free meta can only be stored in object if the object is
not smaller than free meta.

After the improvement, even when the object is smaller than free meta,
it is still possible to store part of the free meta in the object,
reducing the increased size of the redzone.

Example:

free meta size: 16 bytes
alloc meta size: 16 bytes
object size: 8 bytes
optimal redzone size (object_size <= 64): 16 bytes

Before improvement:
actual redzone size = alloc meta size + free meta size = 32 bytes

After improvement:
actual redzone size = alloc meta size + (free meta size - object size)
= 24 bytes

Suggested-by: Dmitry Vyukov <[email protected]>
Signed-off-by: Juntong Deng <[email protected]>
---
mm/kasan/generic.c | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c
index 4d837ab83f08..286b80661a80 100644
--- a/mm/kasan/generic.c
+++ b/mm/kasan/generic.c
@@ -361,6 +361,8 @@ void kasan_cache_create(struct kmem_cache *cache, unsigned int *size,
{
unsigned int ok_size;
unsigned int optimal_size;
+ unsigned int rem_free_meta_size;
+ unsigned int orig_alloc_meta_offset;

if (!kasan_requires_meta())
return;
@@ -394,6 +396,9 @@ void kasan_cache_create(struct kmem_cache *cache, unsigned int *size,
/* Continue, since free meta might still fit. */
}

+ ok_size = *size;
+ orig_alloc_meta_offset = cache->kasan_info.alloc_meta_offset;
+
/*
* Add free meta into redzone when it's not possible to store
* it in the object. This is the case when:
@@ -401,21 +406,26 @@ void kasan_cache_create(struct kmem_cache *cache, unsigned int *size,
* be touched after it was freed, or
* 2. Object has a constructor, which means it's expected to
* retain its content until the next allocation, or
- * 3. Object is too small.
* Otherwise cache->kasan_info.free_meta_offset = 0 is implied.
+ * Even if the object is smaller than free meta, it is still
+ * possible to store part of the free meta in the object.
*/
- if ((cache->flags & SLAB_TYPESAFE_BY_RCU) || cache->ctor ||
- cache->object_size < sizeof(struct kasan_free_meta)) {
- ok_size = *size;
-
+ if ((cache->flags & SLAB_TYPESAFE_BY_RCU) || cache->ctor) {
cache->kasan_info.free_meta_offset = *size;
*size += sizeof(struct kasan_free_meta);
+ } else if (cache->object_size < sizeof(struct kasan_free_meta)) {
+ rem_free_meta_size = sizeof(struct kasan_free_meta) -
+ cache->object_size;
+ *size += rem_free_meta_size;
+ if (cache->kasan_info.alloc_meta_offset != 0)
+ cache->kasan_info.alloc_meta_offset += rem_free_meta_size;
+ }

- /* If free meta doesn't fit, don't add it. */
- if (*size > KMALLOC_MAX_SIZE) {
- cache->kasan_info.free_meta_offset = KASAN_NO_FREE_META;
- *size = ok_size;
- }
+ /* If free meta doesn't fit, don't add it. */
+ if (*size > KMALLOC_MAX_SIZE) {
+ cache->kasan_info.free_meta_offset = KASAN_NO_FREE_META;
+ cache->kasan_info.alloc_meta_offset = orig_alloc_meta_offset;
+ *size = ok_size;
}

/* Calculate size with optimal redzone. */
--
2.39.2


2023-11-21 15:14:57

by Oliver Sang

[permalink] [raw]
Subject: Re: [PATCH] kasan: Improve free meta storage in Generic KASAN



Hello,

kernel test robot noticed "BUG_kmalloc-rnd-#-#(Not_tainted):Object_padding_overwritten" on:

commit: cb53c2a822df305ec84b291e4c4a348c7d394b89 ("[PATCH] kasan: Improve free meta storage in Generic KASAN")
url: https://github.com/intel-lab-lkp/linux/commits/Juntong-Deng/kasan-Improve-free-meta-storage-in-Generic-KASAN/20231120-044846
base: https://git.kernel.org/cgit/linux/kernel/git/akpm/mm.git mm-everything
patch link: https://lore.kernel.org/all/VI1P193MB0752DE2CCD9046B5FED0AA8E99B5A@VI1P193MB0752.EURP193.PROD.OUTLOOK.COM/
patch subject: [PATCH] kasan: Improve free meta storage in Generic KASAN

in testcase: boot

compiler: clang-16
test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 16G

(please refer to attached dmesg/kmsg for entire log/backtrace)


+-------------------------------------------------------------+------------+------------+
| | a350566908 | cb53c2a822 |
+-------------------------------------------------------------+------------+------------+
| BUG_kmalloc-rnd-#-#(Not_tainted):Object_padding_overwritten | 0 | 17 |
| BUG_kmalloc-rnd-#-#(Tainted:G_B):Object_padding_overwritten | 0 | 21 |
| BUG_kmalloc-#(Tainted:G_B):Object_padding_overwritten | 0 | 21 |
| BUG_kmalloc-#(Not_tainted):Object_padding_overwritten | 0 | 4 |
+-------------------------------------------------------------+------------+------------+


If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-lkp/[email protected]


[ 1.104299][ T0] ** administrator! **
[ 1.104884][ T0] ** **
[ 1.105469][ T0] ** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **
[ 1.106054][ T0] **********************************************************
[ 1.109891][ T0] =============================================================================
[ 1.110637][ T0] BUG kmalloc-rnd-09-8 (Not tainted): Object padding overwritten
[ 1.111258][ T0] -----------------------------------------------------------------------------
[ 1.111258][ T0]
[ 1.112154][ T0] 0xffff888100078074-0xffff88810007807b @offset=116. First byte 0x0 instead of 0x5a
[ 1.112904][ T0] Slab 0xffffea0004001e00 objects=30 used=1 fp=0xffff888100078090 flags=0x8000000000000800(slab|zone=2)
[ 1.113798][ T0] Object 0xffff888100078008 @offset=8 fp=0xffff888100078090
[ 1.113798][ T0]
[ 1.114555][ T0] Redzone ffff888100078000: bb bb bb bb bb bb bb bb ........
[ 1.115329][ T0] Object ffff888100078008: 6b 6b 6b 6b 6b 6b 6b a5 kkkkkkk.
[ 1.116098][ T0] Redzone ffff888100078010: bb bb bb bb bb bb bb bb ........
[ 1.116868][ T0] Padding ffff888100078074: 00 00 00 00 00 00 00 00 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ
[ 1.117691][ T0] Padding ffff888100078084: 5a 5a 5a 5a ZZZZ
[ 1.118432][ T0] CPU: 0 PID: 0 Comm: swapper Not tainted 6.7.0-rc1-00145-gcb53c2a822df #1
[ 1.119122][ T0] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[ 1.119953][ T0] Call Trace:
[ 1.120209][ T0] <TASK>
[ 1.120439][ T0] dump_stack_lvl+0xa2/0x100
[ 1.120808][ T0] check_bytes_and_report+0x113/0x160
[ 1.121240][ T0] check_object+0x1e1/0x380
[ 1.121599][ T0] alloc_debug_processing+0x10e/0x1f0
[ 1.122027][ T0] ___slab_alloc+0x81b/0xdd0
[ 1.122392][ T0] ? init_freelist_randomization+0x11/0x50
[ 1.122854][ T0] ? cache_random_seq_create+0x49/0x110
[ 1.123308][ T0] ? cache_random_seq_create+0x49/0x110
[ 1.123751][ T0] __kmem_cache_alloc_node+0x161/0x1f0
[ 1.124188][ T0] ? cache_random_seq_create+0x49/0x110
[ 1.124637][ T0] __kmalloc+0xb5/0x1b0
[ 1.124968][ T0] cache_random_seq_create+0x49/0x110
[ 1.125395][ T0] init_cache_random_seq+0x2c/0xc0
[ 1.125809][ T0] init_freelist_randomization+0x2d/0x50
[ 1.126259][ T0] kmem_cache_init+0xac/0x120
[ 1.126630][ T0] mm_core_init+0x2a/0x60
[ 1.126972][ T0] start_kernel+0x156/0x370
[ 1.127334][ T0] x86_64_start_reservations+0x20/0x20
[ 1.127770][ T0] x86_64_start_kernel+0x59/0x60
[ 1.128162][ T0] secondary_startup_64_no_verify+0x167/0x16b
[ 1.128652][ T0] </TASK>
[ 1.128887][ T0] Disabling lock debugging due to kernel taint
[ 1.129373][ T0] FIX kmalloc-rnd-09-8: Restoring Object padding 0xffff888100078074-0xffff88810007807b=0x5a
[ 1.130544][ T0] =============================================================================
[ 1.131270][ T0] BUG kmalloc-rnd-09-8 (Tainted: G B ): Object padding overwritten
[ 1.132002][ T0] -----------------------------------------------------------------------------
[ 1.132002][ T0]
[ 1.132893][ T0] 0xffff8881000780fc-0xffff888100078103 @offset=252. First byte 0x0 instead of 0x5a
[ 1.133638][ T0] Slab 0xffffea0004001e00 objects=30 used=2 fp=0xffff888100078118 flags=0x8000000000000800(slab|zone=2)
[ 1.134524][ T0] Object 0xffff888100078090 @offset=144 fp=0xffff888100078118
[ 1.134524][ T0]
[ 1.135292][ T0] Redzone ffff888100078088: bb bb bb bb bb bb bb bb ........
[ 1.136060][ T0] Object ffff888100078090: 6b 6b 6b 6b 6b 6b 6b a5 kkkkkkk.
[ 1.136827][ T0] Redzone ffff888100078098: bb bb bb bb bb bb bb bb ........
[ 1.137596][ T0] Padding ffff8881000780fc: 00 00 00 00 00 00 00 00 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ
[ 1.138418][ T0] Padding ffff88810007810c: 5a 5a 5a 5a ZZZZ
[ 1.139167][ T0] CPU: 0 PID: 0 Comm: swapper Tainted: G B 6.7.0-rc1-00145-gcb53c2a822df #1
[ 1.139971][ T0] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[ 1.140800][ T0] Call Trace:
[ 1.141054][ T0] <TASK>
[ 1.141281][ T0] dump_stack_lvl+0xa2/0x100
[ 1.141643][ T0] check_bytes_and_report+0x113/0x160
[ 1.142068][ T0] check_object+0x1e1/0x380
[ 1.142423][ T0] alloc_debug_processing+0x10e/0x1f0
[ 1.142848][ T0] ___slab_alloc+0x4fe/0xdd0
[ 1.143214][ T0] ? cache_random_seq_create+0x49/0x110
[ 1.143654][ T0] ? cache_random_seq_create+0x49/0x110
[ 1.144092][ T0] __kmem_cache_alloc_node+0x161/0x1f0
[ 1.144524][ T0] ? cache_random_seq_create+0x49/0x110
[ 1.144962][ T0] __kmalloc+0xb5/0x1b0
[ 1.145289][ T0] cache_random_seq_create+0x49/0x110
[ 1.145713][ T0] init_cache_random_seq+0x2c/0xc0
[ 1.146115][ T0] init_freelist_randomization+0x2d/0x50
[ 1.146561][ T0] kmem_cache_init+0xac/0x120
[ 1.146928][ T0] mm_core_init+0x2a/0x60
[ 1.147272][ T0] start_kernel+0x156/0x370
[ 1.147625][ T0] x86_64_start_reservations+0x20/0x20
[ 1.148057][ T0] x86_64_start_kernel+0x59/0x60
[ 1.148447][ T0] secondary_startup_64_no_verify+0x167/0x16b
[ 1.148929][ T0] </TASK>


The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20231121/[email protected]



--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

2023-11-21 16:04:07

by Juntong Deng

[permalink] [raw]
Subject: Re: [PATCH] kasan: Improve free meta storage in Generic KASAN

On 2023/11/21 23:06, kernel test robot wrote:
>
>
> Hello,
>
> kernel test robot noticed "BUG_kmalloc-rnd-#-#(Not_tainted):Object_padding_overwritten" on:
>
> commit: cb53c2a822df305ec84b291e4c4a348c7d394b89 ("[PATCH] kasan: Improve free meta storage in Generic KASAN")
> url: https://github.com/intel-lab-lkp/linux/commits/Juntong-Deng/kasan-Improve-free-meta-storage-in-Generic-KASAN/20231120-044846
> base: https://git.kernel.org/cgit/linux/kernel/git/akpm/mm.git mm-everything
> patch link: https://lore.kernel.org/all/VI1P193MB0752DE2CCD9046B5FED0AA8E99B5A@VI1P193MB0752.EURP193.PROD.OUTLOOK.COM/
> patch subject: [PATCH] kasan: Improve free meta storage in Generic KASAN
>
> in testcase: boot
>
> compiler: clang-16
> test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 16G
>
> (please refer to attached dmesg/kmsg for entire log/backtrace)
>
>
> +-------------------------------------------------------------+------------+------------+
> | | a350566908 | cb53c2a822 |
> +-------------------------------------------------------------+------------+------------+
> | BUG_kmalloc-rnd-#-#(Not_tainted):Object_padding_overwritten | 0 | 17 |
> | BUG_kmalloc-rnd-#-#(Tainted:G_B):Object_padding_overwritten | 0 | 21 |
> | BUG_kmalloc-#(Tainted:G_B):Object_padding_overwritten | 0 | 21 |
> | BUG_kmalloc-#(Not_tainted):Object_padding_overwritten | 0 | 4 |
> +-------------------------------------------------------------+------------+------------+
>
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <[email protected]>
> | Closes: https://lore.kernel.org/oe-lkp/[email protected]
>
>
> [ 1.104299][ T0] ** administrator! **
> [ 1.104884][ T0] ** **
> [ 1.105469][ T0] ** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **
> [ 1.106054][ T0] **********************************************************
> [ 1.109891][ T0] =============================================================================
> [ 1.110637][ T0] BUG kmalloc-rnd-09-8 (Not tainted): Object padding overwritten
> [ 1.111258][ T0] -----------------------------------------------------------------------------
> [ 1.111258][ T0]
> [ 1.112154][ T0] 0xffff888100078074-0xffff88810007807b @offset=116. First byte 0x0 instead of 0x5a
> [ 1.112904][ T0] Slab 0xffffea0004001e00 objects=30 used=1 fp=0xffff888100078090 flags=0x8000000000000800(slab|zone=2)
> [ 1.113798][ T0] Object 0xffff888100078008 @offset=8 fp=0xffff888100078090
> [ 1.113798][ T0]
> [ 1.114555][ T0] Redzone ffff888100078000: bb bb bb bb bb bb bb bb ........
> [ 1.115329][ T0] Object ffff888100078008: 6b 6b 6b 6b 6b 6b 6b a5 kkkkkkk.
> [ 1.116098][ T0] Redzone ffff888100078010: bb bb bb bb bb bb bb bb ........
> [ 1.116868][ T0] Padding ffff888100078074: 00 00 00 00 00 00 00 00 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ
> [ 1.117691][ T0] Padding ffff888100078084: 5a 5a 5a 5a ZZZZ
> [ 1.118432][ T0] CPU: 0 PID: 0 Comm: swapper Not tainted 6.7.0-rc1-00145-gcb53c2a822df #1
> [ 1.119122][ T0] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
> [ 1.119953][ T0] Call Trace:
> [ 1.120209][ T0] <TASK>
> [ 1.120439][ T0] dump_stack_lvl+0xa2/0x100
> [ 1.120808][ T0] check_bytes_and_report+0x113/0x160
> [ 1.121240][ T0] check_object+0x1e1/0x380
> [ 1.121599][ T0] alloc_debug_processing+0x10e/0x1f0
> [ 1.122027][ T0] ___slab_alloc+0x81b/0xdd0
> [ 1.122392][ T0] ? init_freelist_randomization+0x11/0x50
> [ 1.122854][ T0] ? cache_random_seq_create+0x49/0x110
> [ 1.123308][ T0] ? cache_random_seq_create+0x49/0x110
> [ 1.123751][ T0] __kmem_cache_alloc_node+0x161/0x1f0
> [ 1.124188][ T0] ? cache_random_seq_create+0x49/0x110
> [ 1.124637][ T0] __kmalloc+0xb5/0x1b0
> [ 1.124968][ T0] cache_random_seq_create+0x49/0x110
> [ 1.125395][ T0] init_cache_random_seq+0x2c/0xc0
> [ 1.125809][ T0] init_freelist_randomization+0x2d/0x50
> [ 1.126259][ T0] kmem_cache_init+0xac/0x120
> [ 1.126630][ T0] mm_core_init+0x2a/0x60
> [ 1.126972][ T0] start_kernel+0x156/0x370
> [ 1.127334][ T0] x86_64_start_reservations+0x20/0x20
> [ 1.127770][ T0] x86_64_start_kernel+0x59/0x60
> [ 1.128162][ T0] secondary_startup_64_no_verify+0x167/0x16b
> [ 1.128652][ T0] </TASK>
> [ 1.128887][ T0] Disabling lock debugging due to kernel taint
> [ 1.129373][ T0] FIX kmalloc-rnd-09-8: Restoring Object padding 0xffff888100078074-0xffff88810007807b=0x5a
> [ 1.130544][ T0] =============================================================================
> [ 1.131270][ T0] BUG kmalloc-rnd-09-8 (Tainted: G B ): Object padding overwritten
> [ 1.132002][ T0] -----------------------------------------------------------------------------
> [ 1.132002][ T0]
> [ 1.132893][ T0] 0xffff8881000780fc-0xffff888100078103 @offset=252. First byte 0x0 instead of 0x5a
> [ 1.133638][ T0] Slab 0xffffea0004001e00 objects=30 used=2 fp=0xffff888100078118 flags=0x8000000000000800(slab|zone=2)
> [ 1.134524][ T0] Object 0xffff888100078090 @offset=144 fp=0xffff888100078118
> [ 1.134524][ T0]
> [ 1.135292][ T0] Redzone ffff888100078088: bb bb bb bb bb bb bb bb ........
> [ 1.136060][ T0] Object ffff888100078090: 6b 6b 6b 6b 6b 6b 6b a5 kkkkkkk.
> [ 1.136827][ T0] Redzone ffff888100078098: bb bb bb bb bb bb bb bb ........
> [ 1.137596][ T0] Padding ffff8881000780fc: 00 00 00 00 00 00 00 00 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ
> [ 1.138418][ T0] Padding ffff88810007810c: 5a 5a 5a 5a ZZZZ
> [ 1.139167][ T0] CPU: 0 PID: 0 Comm: swapper Tainted: G B 6.7.0-rc1-00145-gcb53c2a822df #1
> [ 1.139971][ T0] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
> [ 1.140800][ T0] Call Trace:
> [ 1.141054][ T0] <TASK>
> [ 1.141281][ T0] dump_stack_lvl+0xa2/0x100
> [ 1.141643][ T0] check_bytes_and_report+0x113/0x160
> [ 1.142068][ T0] check_object+0x1e1/0x380
> [ 1.142423][ T0] alloc_debug_processing+0x10e/0x1f0
> [ 1.142848][ T0] ___slab_alloc+0x4fe/0xdd0
> [ 1.143214][ T0] ? cache_random_seq_create+0x49/0x110
> [ 1.143654][ T0] ? cache_random_seq_create+0x49/0x110
> [ 1.144092][ T0] __kmem_cache_alloc_node+0x161/0x1f0
> [ 1.144524][ T0] ? cache_random_seq_create+0x49/0x110
> [ 1.144962][ T0] __kmalloc+0xb5/0x1b0
> [ 1.145289][ T0] cache_random_seq_create+0x49/0x110
> [ 1.145713][ T0] init_cache_random_seq+0x2c/0xc0
> [ 1.146115][ T0] init_freelist_randomization+0x2d/0x50
> [ 1.146561][ T0] kmem_cache_init+0xac/0x120
> [ 1.146928][ T0] mm_core_init+0x2a/0x60
> [ 1.147272][ T0] start_kernel+0x156/0x370
> [ 1.147625][ T0] x86_64_start_reservations+0x20/0x20
> [ 1.148057][ T0] x86_64_start_kernel+0x59/0x60
> [ 1.148447][ T0] secondary_startup_64_no_verify+0x167/0x16b
> [ 1.148929][ T0] </TASK>
>
>
> The kernel config and materials to reproduce are available at:
> https://download.01.org/0day-ci/archive/20231121/[email protected]
>
>
>

This bug is caused by the fact that after improving the free meta
storage, kasan_metadata_size() continues to calculate the metadata
size according to the previous storage method.

I will fix this in a separate patch.

2023-11-21 16:10:08

by Andrey Konovalov

[permalink] [raw]
Subject: Re: [PATCH] kasan: Improve free meta storage in Generic KASAN

On Tue, Nov 21, 2023 at 5:03 PM Juntong Deng <[email protected]> wrote:
>
> This bug is caused by the fact that after improving the free meta
> storage, kasan_metadata_size() continues to calculate the metadata
> size according to the previous storage method.
>
> I will fix this in a separate patch.

Hi,

Please send a v2 with the fix folded in instead.

Thanks!

2023-11-21 16:17:52

by Juntong Deng

[permalink] [raw]
Subject: Re: [PATCH] kasan: Improve free meta storage in Generic KASAN

On 2023/11/22 0:05, Andrey Konovalov wrote:
> On Tue, Nov 21, 2023 at 5:03 PM Juntong Deng <[email protected]> wrote:
>>
>> This bug is caused by the fact that after improving the free meta
>> storage, kasan_metadata_size() continues to calculate the metadata
>> size according to the previous storage method.
>>
>> I will fix this in a separate patch.
>
> Hi,
>
> Please send a v2 with the fix folded in instead.
>
> Thanks!

OK, I will send patch V2.