Glibc-2.29 新增的防护机制
TOC
1. free 1.1. tcache 1.2. chunk extend 2. malloc 2.1. unsorted bin 2.2. top chunk
下面我介绍几种在 glibc-2.29 中增加的防护机制,由于本人才疏学浅, 可能仅是冰山一角。
文章对照的是 glibc-2.27 和 glibc-2.29 。
free tcache 最明显的就是tcache
。
来自源码:glibc-2.29/malloc/malloc.c:4197
if (__glibc_unlikely (e->key == tcache)) { tcache_entry *tmp; LIBC_PROBE (memory_tcache_double_free, 2 , e, tc_idx); for (tmp = tcache->entries[tc_idx]; tmp; tmp = tmp->next) if (tmp == e) malloc_printerr ("free(): double free detected in tcache 2" ); }
这里会对tcache
链表上的所有chunk进行对比,检测是否有重复,这让原本在glibc-2.27
和glibc-2.28
肆虐的tcache double free
攻击很难实施,但是鉴于tcache
的特性,tcache
的利用还是要比其他的bins
方便很多。
chunk extend chunk extend
也是很好用的攻击方式之一,但是在glibc-2.29
中增加了新的检查,这将会增大chunk extend
的难度。
来自源码:glibc-2.29/malloc/malloc.c:4334
if (!prev_inuse (p)) { prevsize = prev_size (p); size += prevsize; p = chunk_at_offset (p, -((long ) prevsize)); if (__glibc_unlikely (chunksize (p) != prevsize)) malloc_printerr ("corrupted size vs. prev_size while consolidating" ); unlink_chunk (av, p); }
在glibc-2.29
中新增了prevsize
的检查机制,在合并的时候会判断prev_size
和要合并chunk
的size
是否相同。
malloc unsorted bin 原本这里仅仅有size检查。
来自源码:glibc-2.29/malloc/malloc.c:3742
bck = victim->bk; size = chunksize (victim); mchunkptr next = chunk_at_offset (victim, size); if (__glibc_unlikely (size <= 2 * SIZE_SZ) || __glibc_unlikely (size > av->system_mem)) malloc_printerr ("malloc(): invalid size (unsorted)" ); if (__glibc_unlikely (chunksize_nomask (next) < 2 * SIZE_SZ) || __glibc_unlikely (chunksize_nomask (next) > av->system_mem)) malloc_printerr ("malloc(): invalid next size (unsorted)" ); if (__glibc_unlikely ((prev_size (next) & ~(SIZE_BITS)) != size)) malloc_printerr ("malloc(): mismatching next->prev_size (unsorted)" ); if (__glibc_unlikely (bck->fd != victim) || __glibc_unlikely (victim->fd != unsorted_chunks (av))) malloc_printerr ("malloc(): unsorted double linked list corrupted" ); if (__glibc_unlikely (prev_inuse (next))) malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)" );
然后在glibc-2.29
中,增加了如下检查:
对下一个相邻chunk的size检查
对下一个相邻chunk的prev_size
进行检查
检查unsorted bin
双向链表的完整性,对unsorted bin attack
可以说是很致命的检查
对下一个chunk的prev_inuse
位进行检查
这么多的检查,将使得unsorted bin
更难利用。
下面这个检查早在glibc-2.28
就有了,这里提一下,主要是防护unsorted bin attack
。
来自源码:glibc-2.29/malloc/malloc.c:3976
if (__glibc_unlikely (bck->fd != victim)) malloc_printerr ("malloc(): corrupted unsorted chunks 3" ); unsorted_chunks (av)->bk = bck;bck->fd = unsorted_chunks (av);
top chunk 对于top chunk
增加了size
检查,遏制了House of Force
攻击。
来自源码:glibc-2.29/malloc/malloc.c:4111
victim = av->top; size = chunksize (victim); if (__glibc_unlikely (size > av->system_mem)) malloc_printerr ("malloc(): corrupted top size" );