【问题标题】:Why in mmap PROT_READ equals PROT_EXEC为什么在 mmap 中 PROT_READ 等于 PROT_EXEC
【发布时间】:2015-09-23 03:50:12
【问题描述】:

我尝试使用mmap 函数分配一些具有只读访问权限的内存页面。我打印了/proc/self/maps 来检查内存保护是否有效。即使mmap 的保护参数是PROT_READ,它也显示为这样

 7fec0c585000-7fec0c785000 r-xp 00000000 00:00 0

这意味着当我要求内核分配一些只读内存页面时,它也会将它们标记为可执行。

我做了一些其他的测试,我意识到当我要求一个只写页面时,PROT_WRITE没有PROT_READ,maps文件的输出是这样的:

7fec0c585000-7fec0c785000 -w-p 00000000 00:00 0 

这意味着除了前面的例子之外,PROT_READ 等同于 PROT_EXEC

同时调用mmap 和PROT_WRITE|PROT_READ,也可以执行。

我想知道有没有办法映射一个只读的、不可执行的内存页;还是一个可读写且不可执行的?


运行测试的计算机信息:

  1. Linux Arch 4.1.6-1-ARCH #1 SMP PREEMPT Mon Aug 17 08:52:28 CEST 2015 x86_64 GNU/Linux

  2. 英特尔酷睿 i5-2310、x86_64

【问题讨论】:

    标签: linux mmap memory-mapping


    【解决方案1】:

    在做了一些研究之后,我意识到 Linux 只有在 GNU_STACK 程序头包含在 ELF 程序头中时才会激活内存保护。 内存保护是指使用处理器的 NX 位,因此可以将内存页面标记为不可执行。

    据我了解,GNU_STACK 程序标头旨在告诉内核您需要堆栈的一些特定属性,其中一个属性是不可执行的堆栈。看来,如果您没有明确要求一个不可执行的堆栈,则所有标记为可读的ELF 部分也将是可执行的。并且所有与mmap 的内存映射同时具有相同的行为。

    遗憾的是,没有足够的文档说明 GNU_STACK 的作用,并且 mmap 的文档没有指定它与 GNU_STACK 的连接以启用执行保护。

    参考文献:

    https://wiki.gentoo.org/wiki/Hardened/GNU_stack_quickstart

    【讨论】:

    • 做一些更多的挖掘,这是因为个性上的 READ_IMPLIES_EXEC 标志。您可以通过获取角色(将 -1 传递给 sys_personality),然后屏蔽其值可以在 sys/personality.h 中找到的标志(角色和 ~0x0400000),然后重置角色,从而在没有 GNU_STACK 标头的情况下更改此设置。跨度>
    【解决方案2】:

    我在我的 Debian Jessie 中测试了这个问题。

    我在一个特殊地址映射一个匿名区域,并打印地图内容,对应的权限表:

    PROT_READ               r--p
    PROT_WRITE              -w-p
    PROT_EXEC               --xp
    PROT_READ|PROT_WRITE    rw-p
    PROT_READ|PROT_EXEC     r-xp
    

    我不测试 PROT_WRITE | PROT_EXEC ...,因为 pax/grsecurity 防止创建可写和可执行的映射。

    测试信息:
    Linux 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt17-1 (2015-09-26) x86_64 GNU/Linux
    英特尔 i7,x86_64

    【讨论】:

    • 检查你的精灵文件的节头。必须有一个 GNU_STACK 部分
    • GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 10 你说得对!
    • 我找到了诀窍:GUN_STACK(RW/RWX) -> load_elf_binary 验证此权限 -> 进程个性(READ_IMPLIES_EXEC) -> 如果设置了此位,则 PROT_READ 还将添加 PROT_EXEC 位 ->这样你就可以知道答案了。
    猜你喜欢
    • 2021-03-28
    • 2011-10-21
    • 1970-01-01
    • 2019-10-18
    • 2021-01-16
    • 1970-01-01
    • 2021-08-06
    • 2022-01-25
    • 2011-04-24
    相关资源
    最近更新 更多