linux 堆块分配

linux 堆块分配

关于fastbin

我们一般熟悉的堆都是双链表的chunk,但是对于大小为(16 Bytes~ 64 Bytes)的堆块来说则是使用fastbin来进行管理的。
fastbin的堆块结构与常规的chunk是完全一样,除了使用的是单链表。
fastbin
![fastbin]

2.2 Bins
注意:Bin的翻译为箱子,chunk的翻译为块

  • Bin:freelist数据结构,用于保存free chunks。

  • 基于chunk size,bins被划分为以下几种类型:

List item

  • Fast bin(单链表,大小相同)

  • Unsorted bin(环形双链表,乱序状态,空闲 chunk 回归所属 bin 之前的缓冲区)

  • Small bin(环形双链表,大小相同)

  • Large bin(环形双链表,按大小降序排列)

2.2.1 Fast bin

  1. 大小为16 ~ 80 / 32 ~160字节的chunk称为fast chunk;

存储fast chunk的bins称为fast bins;

2.2.3 Small bin

  1. 小于512/1024字节的chunk称为small chunk。

存储small chunk的bins称为small bins;

2.2.4 Large bin

  1. 大小大于等于512字节的chunk称为large chunk;

堆管理

Top Chunk

当一个chunk处于一个arena的最顶部(即最高内存地址处)的时候,就称之为top chunk。该chunk并不属于任何bin,而是在系统当前的所有free chunk(无论那种bin)都无法满足用户请求的内存大小的时候,将此chunk当做一个应急消防员,分配给用户使用。如果top chunk的大小比用户请求的大小要大的话,就将该top chunk分作两部分:1)用户请求的chunk;2)剩余的部分成为新的top chunk。否则,就需要扩展heap或分配新的heap了——在main arena中通过sbrk扩展heap,而在thread arena中通过mmap分配新的heap。

Last Remainder Chunk

当用户请求的是一个small chunk,且该请求无法被small bin、unsorted bin满足的时候,就通过binmaps遍历bin查找最合适的chunk,如果该chunk有剩余部分的话,就将该剩余部分变成一个新的chunk加入到unsorted bin中,另外,再将该新的chunk变成新的last remainder chunk。

在这里插入图片描述

堆利用笔记
在这里插入图片描述

House Of Force

· 可覆写top chunk的size字段
· 存在一次malloc,攻击者控制malloc的size,前两项是为了新分配堆时可得到任意地址。
· 存在另一次malloc,攻击者可以向里面写入数据
· top chunk的地址

House of Spirit

当glibc被free时,glibc在想什么。
· glibc如何确定free是一个真正的chunk?
· 如果我们free(0xdeadbeef)呢?
如果我们需要fake chunk成功进入free list,需要哪些条件?
攻击的本质:
· 能够控制free的参数
· 能够满足free中对chunk的各项检查
· 触发free,使得fake chunk进入list
· 再次malloc得到chunk,相当于弱化版的任意地址写

House of Mind

如果我们能控制指针p以及对应的arena。
Advanced Heap Exp
fastbin attack
更改fastbin的后向指针,从而使堆分配到我们想要的地方,形成任意地址写。
检查——in free
· address < -size && address alignment
· size > MINSIZE(0x20) && multiple of 0x10
· next chunk size
o > MINSIZE
· < system_mem
· chunk size 是否和当前链表匹配
o 可以具有较小的偏移,但fastbin_index (chunksize (victim)) != idx, 0)
fastbin_index是通过移位做到的。
of by one
· 这一个字节将影响到下一个chunk的size字段
· off by one to extend allocated chunk
· off by NULL to shrink free chunk
· 堆溢出的利用可能会用到多个技巧
· 某些漏洞可被转化为堆溢出
· 整数溢出或竞态条件

堆喷
0x0c0c0c0c地址的优越性。
地址低
\x0c\x0c -> OR AL, 0C (NOP-like instruction

glibc malloc

main arena中的内存申请

内存回收

分配顺序

在这里插入图片描述
unsorted bin如果满足,可能会被分割。top_chunk分割采用向后移动top指针的方式。
走到unsorted bin ,fast bin 和small_bin会被合并整合到unsorted_bin
在这里插入图片描述
在这里插入图片描述

Unsorted Bin Attack

任意地址修改为一个较大的值,值不可控。利用unsorted bin链表覆盖实现,伪造的unsorted bin的bk位置在从链表中出来的时候会被修改,但此时链表被破坏了。

<think>好的,我现在需要回答用户关于Linux系统中内存最大分配限制的问题。首先,我需要回顾一下Linux内存管理的基本知识,并结合用户提供的引用内容来构建答案。 用户提到了内存,所以应该从进程的地址空间结构入手。在Linux中,每个进程的虚拟地址空间分为代码段、数据段、、栈等部分。内存的动态分配通常通过malloc等函数实现,而malloc背后使用的是glibc的内存管理机制,比如ptmalloc。根据引用[1],glibc将空闲内存分为top chunk和各种bin,这些结构影响内存分配的效率和策略。 接下来,用户想知道内存的最大分配限制。这里需要考虑几个因素:系统架构、内核参数、用户空间限制以及物理内存和交换空间的情况。比如,32位系统的地址空间限制是4GB,但用户空间通常只有3GB左右,而64位系统理论上可以支持更大的地址空间。不过,实际分配还受到资源限制(如ulimit)和物理内存加上交换空间的总量限制。 引用[3]中提到一个应用分配3.5GB内存的情况,这可能涉及到glibc的内存分配策略。例如,当请求大内存时,malloc可能会直接使用mmap来分配,而不是从区扩展。这需要解释mmap和brk/sbrk的区别,以及它们对最大分配的影响。此外,用户提到的alloca函数(引用[2])是在栈上分配内存,这与分配不同,但可能对进程整体内存布局有影响,需要注意区分。 还需要考虑内核参数,如overcommit的设置。在Linux中,内存的过度分配可能导致即使malloc返回成功,实际访问时却触发OOM Killer。这会影响实际可分配的内存大小。 最后,要总结影响最大分配限制的因素,并给出如何查看和调整这些限制的方法,如使用ulimit命令或修改/proc/sys/vm中的参数。同时,结合引用中的例子,说明实际应用中可能遇到的问题,比如处理大文件时的内存分配策略优化。 需要确保回答结构清晰,分点说明,并引用提供的资料来支持论点,同时生成相关问题供用户进一步学习。</think>### Linux内存最大分配限制 在Linux系统中,内存的最大分配限制受多个因素影响,包括系统架构、内核参数、用户空间限制以及物理内存和交换空间的可用性。以下是具体分析: #### 1. **系统架构的地址空间限制** - **32位系统**:进程的虚拟地址空间上限为$4\ \text{GB}$(理论上),但用户空间通常仅能使用约$3\ \text{GB}$,剩余部分保留给内核。 - **64位系统**:虚拟地址空间极大(如$2^{48}$或$2^{64}$字节),实际限制更多取决于物理资源和操作系统配置。 #### 2. **glibc的内存管理机制** - **内存分配**:通过`malloc`分配内存时,glibc默认使用`brk`或`sbrk`系统调用扩展区。对于大内存(如超过`MMAP_THRESHOLD`,默认$128\ \text{KB}$),glibc会改用`mmap`直接映射匿名内存页[^1]。 - **top chunk与bin**:如引用[1]所述,glibc通过`top chunk`处理大内存需求。当连续空间不足时,`top chunk`会扩展,但受限于进程地址空间剩余部分。 #### 3. **用户空间资源限制** - **`ulimit`配置**:通过`ulimit -v`可设置虚拟内存上限。例如,默认无限制时,单次分配理论上可达地址空间允许的最大值。 - 示例:若设置`ulimit -v 4096000`,则进程总虚拟内存限制为$4\ \text{GB}$。 #### 4. **物理内存与交换空间** - 实际分配受物理内存和交换空间总和限制。例如,系统有$8\ \text{GB}$物理内存和$8\ \text{GB}$交换空间,则最大可能分配约$16\ \text{GB}$(需考虑其他进程占用)。 - **过度提交(Overcommit)**:Linux允许分配超过物理内存+交换空间的内存(通过`/proc/sys/vm/overcommit_memory`控制),但访问时可能触发OOM Killer终止进程[^3]。 #### 5. **实际测试与工具** - **测试单次分配上限**:可通过以下代码尝试分配内存: ```c #include <stdlib.h> int main() { void *ptr = malloc(SIZE); // SIZE为尝试分配大小 if (!ptr) return 1; free(ptr); return 0; } ``` - **查看进程映射**:使用`/proc/<pid>/maps`文件观察和内存映射区域。 #### 6. **优化与规避策略** - 对于超大内存需求(如引用[3]中的$3.5\ \text{GB}$图像处理),建议改用`mmap`直接操作文件映射,或分处理数据。 - 调整`MMAP_THRESHOLD`:通过`mallopt(M_MMAP_THRESHOLD, size)`可修改glibc的分配策略。 ### 总结 Linux内存单次分配的理论上限在64位系统中通常由虚拟地址空间决定,但实际受限于`ulimit`、物理资源及内核策略。若需分配超大内存,应优先考虑`mmap`或优化内存使用模式。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值