-
-
未解决
[求助][已解决] linux kernel CONFIG_SLAB_FREELIST_HARDENED 加固后 cookie 泄漏问题
-
-
未解决 [求助][已解决] linux kernel CONFIG_SLAB_FREELIST_HARDENED 加固后 cookie 泄漏问题
环境配置:
- 内核版本
v5.14.16
- 设置
CONFIG_SLAB_FREELIST_HARDENED
、CONFIG_SLAB_FREELIST_RANDOM
编译选项
问题描述:
目前存在 kmalloc-128
空闲链表:
freelist -> A -> B -> C -> D -> ......
next
指针存放在 object + 0x40
处,即 offset = 0x40
A
的地址和部分内容如下:
1 2 3 4 5 | 0xffff888005ede200: 0x0000000000000000 0x0000000000000000
0xffff888005ede210: 0x0000000000000000 0x0000000000000000
0xffff888005ede220: 0x0000000000000000 0x0000000000000000
0xffff888005ede230: 0x0000000000000000 0x0000000000000000
0xffff888005ede240: 0x1d947f537ffab314 0x0000000000000000
|
B
的地址和部分内容如下:
1 2 3 4 5 | 0xffff888005edee00: 0x0000000000000000 0x0000000000000000
0xffff888005edee10: 0x0000000000000000 0x0000000000000000
0xffff888005edee20: 0x0000000000000000 0x0000000000000000
0xffff888005edee30: 0x0000000000000000 0x0000000000000000
0xffff888005edee40: 0x1d987f537ffaba14 0x0000000000000000
|
C
的地址和部分内容如下:
1 2 3 4 5 | 0xffff888005ede700: 0x0000000000000000 0x0000000000000000
0xffff888005ede710: 0x0000000000000000 0x0000000000000000
0xffff888005ede720: 0x0000000000000000 0x0000000000000000
0xffff888005ede730: 0x0000000000000000 0x0000000000000000
0xffff888005ede740: 0x1d917f537ffabb14 0x0000000000000000
|
D
的地址和部分内容如下:
1 2 3 4 5 | 0xffff888005ede600: 0x0000000000000000 0x0000000000000000
0xffff888005ede610: 0x0000000000000000 0x0000000000000000
0xffff888005ede620: 0x0000000000000000 0x0000000000000000
0xffff888005ede630: 0x0000000000000000 0x0000000000000000
0xffff888005ede640: 0x1d907f537ffab294 0x0000000000000000
|
next
指针的加密方式为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | static inline void *freelist_ptr( const struct kmem_cache *s, void *ptr,
unsigned long ptr_addr)
{
#ifdef CONFIG_SLAB_FREELIST_HARDENED
return ( void *)((unsigned long )ptr ^ s->random ^
swab((unsigned long )kasan_reset_tag(( void *)ptr_addr)));
#else
return ptr;
#endif
}
|
但是这里调试发现一个问题:ptr
和 ptr_addr
的高两字节都是 0xffff
,所以最后异或出来 ptr ^ ptr_addr ^ cookie
的高两字节应该就是 cookie
的高两字节,也就是说每个 next
指针的高两字节都是相同的,但是这里 A
的 next = 0x1d947f537ffab314
高两字节为 0x1d94
,B
的 next = 0x1d987f537ffaba14
高两字节为 0x1d98
,这两者并不相同
不仅如此,对于 kmalloc-128
,在我的环境下,其同一个 slab cache
中高 52 bit
是相同的,所以加密后的指针高 52 bit
应该也是相同的,其就是 cookie
的高 52 bit
,但是这里异或出来发现高 52 bit
并非完全相同(大部分是相同的)
自己的探索:
我按照 ptr ^ ptr_addr ^ cookie
的方式去恢复 cookie
,发现同一个 slab cache
利用不同堆块恢复出来的居然不同?按照源码来看,这个 random(cookie)
是针对 slab cache
的,所以这里选择不同堆块恢复出来的应该是一样的才对
笔者的问题:
请问在设置了 CONFIG_SLAB_FREELIST_HARDENED
编译选项下 next
指针的加密方式到底是什么?为什么按照源码中的加密逻辑去推理调试却得到不同的 cookie
并且高两字节居然不相同
========================= 后续 ===========================
自己解决了
又审计了一下源码,发现源码中对 ptr_addr
进行了一个 swab
操作很奇怪(之前眼睛瞎了,自动忽视了),跟进去发现其定义如下:主要看 64
位的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#ifdef __HAVE_BUILTIN_BSWAP64__
#define __swab64(x) (__u64)__builtin_bswap64((__u64)(x))
#else
#define __swab64(x) \
(__builtin_constant_p((__u64)(x)) ? \
___constant_swab64(x) : \
__fswab64(x))
#endif
static __always_inline unsigned long __swab( const unsigned long y)
{
#if __BITS_PER_LONG == 64
return __swab64(y);
#else /* __BITS_PER_LONG == 32 */
return __swab32(y);
#endif
}
|
可以看到会进行字节上的交换....感觉这里应该就是防止堆块地址大量字节相同导致泄漏 cookie
而加的保护,也就是上面说的异或出来的值高 52 bit
就是 cookie
值
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2024-5-9 13:08
被XiaozaYa编辑
,原因: