笔记-一推推

stack-buffer-overflow is easy to defend,so lets heap!

heap-related:*use-after-frees, double-frees,*and heap-overflows

Question is :

  • What is the heap, and what is it for?
  • how the internal implementation of the heap allocator?
  • how new heap chunks are created?
  • how chunks are freed and recycled?
  • how heap allocations work for C/C++ programs running on Linux  devices by default?(glibc heap allocator)

lets look at code like this

typedef struct 
{
    int field1;
    char* field2;
} SomeStruct;

int main()
{
    SomeStruct* myObject = (SomeStruct*)malloc(sizeof(SomeStruct));
    if(myObject != NULL)
    {
        myObject->field1 = 1234;
        myObject->field2 = “Hello World!”;
        do_stuff(myObject);
				free(myObject);
    }
    return 0;
}

or

class SomeClass
{
public:
    int field1;
    char* field2;
};

int main()
{
    SomeClass* myObject = new SomeClass();
    myObject->field1 = 1234;
    myObject->field2 = “Hello World!”;
    do_stuff(myObject);
    delete myObject;
    return 0;
}

To service this request like 10 bytes of memory via malloc,the heap manager needs to store metadata of allocation,this metadata is stored alongside the 10-byte region that the programmer can use.and 8-byte aligned on 32-bit systems, or 16-byte aligned on 64-bit systems.

The simplified chunk-allocation strategy for small chunks is this:

1.如果有刚free的chunk(存在bin里),且满足申请的大小,那么就用这个。

2.不行的话,如果heap顶有可用空间,就从中取之。

3.再不行的话,向kernel申请内存(using sbrk())到heap底(end of heap),在这块新空间中取之。

4.再不行就error返回NULL。

lets talking focus on 1 point:

memory被freed后,heap manager还是会记录这些freed块在一个链表‘bin’里,这样再申请时会在这里面找(this is how point 1 do),找到之后标记‘allocated’并返回指向‘user data’的块指针。

bins:fast bins, the unsorted bin, small bins, large bins, and the per-thread tcache

point 2 like the picture above.

the heap manager asks the kernel to allocate more memory at the end of the heap by calling sbrk . On most Linux-based systems this function internally uses a system call called “brk”.

Once the heap reaches this point, the heap manager will resort to attaching new non-contiguous memory to the initial program heap using calls to mmap.

If mmap also fails, then the process simply can’t allocate any more memory, and malloc returns NULL.

large chunk use mmap.By default this threshold is 128KB up to 512KB on 32-bit systems and 32MB on 64-bit systems, however this threshold can also dynamically increase if the heap manager detects that these large allocations are being used transiently.

Arenas:

堆管理器用全局互斥锁(mutex)来维护一个内部堆结构来避免程序崩溃,就是保证每次只有一个线程与堆互动。this is how arenas comes

每个arenas独立维护自己的chunk allocation和free bins.

当进程创建新线程时,堆管理器会为每个新线程分配secondary arenas,以减少线程在执行malloc和free操作时必须等待。

question is,How do these secondary arenas even work?

我们知道主堆区在程序加载进内存的后面且用brk system call扩展,但secondary arenas不能如此

The answer is that these secondary arenas emulate the behavior of the main heap using one or more “subheaps” created using mmap and mprotect。 .

subheaps:

初始化堆(main arena)用sbrk动态扩展,而子堆使用mmap定位到内存中,堆管理器用mprotect手动模拟子堆增长。

chunk metadata:chunk的结构

look at live allocations, which have a single*size_t** header that is positioned just behind the user data region given to the programmer. This field, which the source code calls*mchunk_size*, is written to during malloc, and later used by free to decide how to handle the release of the allocation.

  • A size_t value is an 4 byte integer on a 32-bit system and an 8 byte integer on on a 64-bit system.

mchunk_size 存储4样东西 :this chunk size +’A’’M’’P’,分别存储在同样的size_t里,因为这些chunk sizes一般是8byte对齐(16byte对齐on64bit),因此最后3bits的chunk size总是为0

“A”:用于告诉堆管理器该块是否属于secondary arena(subheap),而不是main arena。在 free时,堆管理器只得到一个指向程序员想要释放的分配的指针,堆管理器需要计算出该指针属于哪个领域。如果在块的元数据中设置了 A 标志,堆管理器必须搜索每个区域并查看指针是否位于该区域的任何子堆(subheap)中。如果未设置该标志,堆管理器可以缩短搜索,因为它知道块来自初始堆(initial arena/main arena)。

“M”:标志用于指示该块是通过 mmap 在堆外分配的巨大分配。当这个分配最终被传递回 free 时,堆管理器将立即通过 munmap 将整个块返回给操作系统,而不是尝试回收它。出于这个原因,释放的块永远不会设置这个标志。

“P”:它表示前一个块是空闲块。这意味着当这个块被释放时,它可以安全地连接到前一个块上以创建一个更大的空闲块。

Glibc heap:

  • how allocations passed back to free get saved and eventually recycled to service future malloc  requests?
  • HOW DOES FREE WORK?

free在操作指向chunk块的删减时候,会进行一系列检查来确保改块chunk是没在使用的:

  • 检查对齐:8byte on 32,16byte on 64
  • 检查该块的大小字段是否不可能--要么是太小,要么是太大,要么不是对齐的大小,要么是会与进程的地址空间的末端重叠
  • 检查大块位于arena的边界之内
  • 通过检查位于下一个块开始的元数据中的相应的 "P "位,检查该块是否已经被标记为free

FREE CHUNK METADATA:

free掉的块也会存储这些边界信息来保证空闲块也能很快的凝聚在一起

微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码 微信小程序毕业设计期末大作业项目源码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值