为什么你的 Double Free 没崩却弄脏了别的数据?聊聊 glibc 的“静默别名”灾难

📅 2026/7/7 3:57:51
为什么你的 Double Free 没崩却弄脏了别的数据?聊聊 glibc 的“静默别名”灾难
引言你以为下面这段会停在free(): double free detected in tcache 2,进程当场 abort。在 glibc 2.27 上它不会。它安静地把同一块内存交给你两次,b和c两个malloc返回值彼此相等,也都等于早就free掉的a。glibc 那句广为人知的 double-free 断言,在 tcache 这条路上压根没有执行——分配快路径为了省掉锁和校验,把它连同另外几道检查整段删掉了,而省下的这几条指令,正好就是堆利用的入口。C// g++ -std=c++17 -O2 df.c ./a.out 运行环境:glibc 2.27 / Ubuntu 18.04 #include cstdlib #include cstdio int main() { void *a = malloc(0x20); free(a); free(a); // 同一个指针,连着 free 两次 void *b = malloc(0x20); void *c = malloc(0x20); // 同尺寸再要两块 printf("a=%p\n", a); printf("b=%p c=%p\n", b, c);