kart 的博客 - 调查一个可能的 Linux 漏洞:尽管 RLIMIT_AS 值较低,但小型 sbrk 调用却意外成功

主要观点:通过自定义内存分配器的测试,发现sbrk函数在特定条件下会出现意外成功的情况,深入研究后发现是内核在brk需要分配新页面时检查RLIMIT_AS设置的限制,且RLIMIT_ASRLIMIT_DATA在处理方式上存在差异,作者提交了内核补丁说明此问题并收到了回复。
关键信息

  • 测试用例通过getrlimitsetrlimit限制地址空间增长,使用my_malloc分配内存并断言malloc返回NULL来测试内存耗尽情况,但测试用例中调用malloc错误,实际测试的是libc malloc的行为。
  • 正常情况下,sbrk调用因setrlimit限制而返回失败,libc malloc返回NULL;但当malloc转发到my_malloc时,sbrk会意外成功并分配新内存块,后续再次调用sbrk会在一定次数后失败。
  • setrlimit文档说明RLIMIT_AS限制进程总可用内存,sbrk等函数在超出限制时会失败,但实际情况中RLIMIT_AS限制在brk不跨越页面边界时可能被突破。
  • RLIMIT_DATARLIMIT_AS类似,但其在brk页面对齐前检查setrlimit违规情况,将RLIMIT_DATA代入测试用例可得到预期行为。
  • 作者提交内核补丁说明brk在检查请求内存量是否有效时应先检查RLIMIT_AS,但收到回复认为此补丁不正确,因为内核内存分配以页面为粒度,限制不会阻止现有资源的使用。
    重要细节
  • 测试用例代码及各函数的功能和调用关系,如my_mallocmallocgetrlimitsetrlimitsbrkbrk等。
  • 内核中brk函数的源代码及相关逻辑,如页面大小的处理、newbrkoldbrk的比较等。
  • 提交的内核补丁内容及回复内容的详细讨论。
阅读 13
0 条评论