Glibc堆块的向前向后合并与unlink原理机制探究

本文深入探讨了Glibc中堆块的向前、向后合并以及unlink操作的原理,包括向后合并、向前合并和unlink的安全检查。通过示例代码和调试验证,解释了如何利用这些机制进行内存管理,特别是如何触发和理解unlink过程。
摘要由CSDN通过智能技术生成

i春秋作家:Bug制造机

原文来自:Glibc堆块的向前向后合并与unlink原理机制探究

 

玩pwn有一段时间了,最近有点生疏了,调起来都不顺手了,所以读读malloc源码回炉一点一点总结反思下。

Unlink是把free掉的chunk从所属的bins链中,卸下来的操作(当然还包括一系列的检测机制),它是在free掉一块chunk(除fastbin大小的chunk外)之后,glibc检查这块chunk相邻的上下两块chunk的free状态之后,做出的向后合并或者向前合并引起的。

向前、向后合并

p是指向free掉的chunk的指针(注意不是指向data的指针,是chunk),size是这块chunk的size。

 /* consolidate backward */
4277            if (!prev_inuse(p)) {
4278              prevsize = prev_size (p);
4279              size += prevsize;
4280              p = chunk_at_offset(p, -((long) prevsize));
4281              unlink(av, p, bck, fwd);
4282            }
4283        
4284            if (nextchunk != av->top) {
4285              /* get and clear inuse bit */
4286              nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
4287        
4288              /* consolidate forward */
4289              if (!nextinuse) {
4290                unlink(av, nextchunk, bck, fwd);
4291                size += nextsize;
4292              } else
4293                clear_inuse_bit_at_offset(nextchunk, 0);
4294
4295              /*
4296                Place the chunk in unsorted chunk list. Chunks are
4297                not placed into regular bins until after they have
4298                been given one chance to be used in malloc.
4299              */
4300        
4301              bck = unsorted_chunks(av);
4302              fwd = bck->fd;
4303              if (__glibc_unlikely (fwd->bk != bck))
4304                malloc_printerr ("free(): corrupted unsorted chunks");
4305              p->fd = fwd;
4306              p->bk = bck;
4307              if (!in_smallbin_range(size))
4308                {
4309                  p->fd_nextsize = NULL;
4310                  p->bk_nextsize = NULL;
4311                }
4312              bck->fd = p;
4313              fwd->bk = p;
4314        
4315              set_head(p, size | PREV_INUSE);
4316              set_foot(p, size);
4317        
4318              check_free_chunk(av, p);
4319            }
4320        
4321            /*
4322              If the chunk borders the current high end of memory,
4323              consolidate into top
4324            */
4325        
4326            else {
4327              size += nextsize;
4328              set_head(p, size | PREV_INUSE);
4329              av->top = p;
4330              check_chunk(av, p);
4331            }

向后合并

向后合并部分的代码在4277-4282行

向后合并流程:

  • 检查p指向chunk的size字段的pre_inuse位,是否为0(也就是检查当前chunk的前一块chunk是否是free的,如果是则进入向前合并的流程)

  • 获取前一块chunk的size,并加到size中

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值