glibc2.27(小版本变动没记)

  • 增加了tcache
  • 再malloc_consolidate中
1
2
/*新增:检查从fastbin中取出的chunk的大小是否满足fastbin的索引,house-of-rabbit无法使用  */
unsigned int idx = fastbin_index (chunksize (p));
  • 在unlink中
1
2
3
/*新增:检查其下一个chunk的prev_size是否和size相等,即使用house-of-einherjar时第一个chunk应该被放入到unsortedbin中*/
if (__builtin_expect (chunksize(P) != prev_size (next_chunk(P)), 0))
malloc_printerr ("corrupted size vs. prev_size");
  • 在2.27小版本1.4以后增加了key

glibc2.29

  • tcache_entry结构体中增加了key,防止doublefree
1
2
3
4
5
6
typedef struct tcache_entry
{
struct tcache_entry *next;
/* This field exists to detect double frees. */
struct tcache_perthread_struct *key;
} tcache_entry;
  • 对在unsortedbin中即将取出的chunk和其nextchunk做检查(unsorted_attack报废)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*新增:unsortedbin attack失效,house-of-storm无法使用*/
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)");
  • 在unlink前增加了对prev_size和size的判断
1
2
/*新增:检查了prev_size和上一个chunk的size是否相等,house-of-einherjar不能使用*/
if (__glibc_unlikely (chunksize(p) != prevsize))

glibc-2.30&glibc-2.31

  • tcache_perthread_struct中的counts类型变为uint16_t类型
1
2
3
4
5
typedef struct tcache_perthread_struct
{
uint16_t counts[TCACHE_MAX_BINS];
tcache_entry *entries[TCACHE_MAX_BINS];
} tcache_perthread_struct;
  • 如果tcache->counts[tc_idx]<=0则不会从tcache中取chunk
1
2
3
4
5
6
if (tc_idx < mp_.tcache_bins
&& tcache
&& tcache->counts[tc_idx] > 0)
{
return tcache_get (tc_idx);
}
  • 将chunk从unsortedbin中取出放入到largebin时做了检查,增大了largebin attack的难度。
1
2
3
4
if (__glibc_unlikely (fwd->bk_nextsize->fd_nextsize != fwd))
malloc_printerr ("malloc(): largebin double linked list corrupted (nextsize)");
if (bck->fd != fwd)
malloc_printerr ("malloc(): largebin double linked list corrupted (bk)");

glibc-2.32

  • tcache中对e->next也就是fd指针做了加密,(&e->next>>12)<<12即为heap_base
1
2
3
e->next = PROTECT_PTR (&e->next, tcache->entries[tc_idx]);
#define PROTECT_PTR(pos, ptr)
((__typeof (ptr)) ((((size_t) pos) >> 12) ^ ((size_t) ptr)))
  • 对fastbin的fd指针也做了相同的加密。
1
2
3
/*新增:fastbin的fd指针被加密*/
p->fd = PROTECT_PTR (&p->fd, old);

  • 增加了很多指针是否对齐的检查
  • 检测了申请的地址是否0x10对齐,错位构造不可行了

glibc-2.34

  • 移除了一些hook,最低版本的2.34,貌似exit_hook还是可用的,其他的就不可用了

glibc-2.35

  • 一些虚表不可以写了