【问题标题】:Disable write protection for memory pages in ARM禁用 ARM 中内存页的写保护
【发布时间】:2015-10-17 08:17:30
【问题描述】:

研究了linux上disabling of kernel text on kernel text的写保护的题目,只能找到x86 linux的解决方法,就是暂时清除cr0寄存器的第16位,写入内存,然后设置cr0 寄存器的第 16 位。但是,这不适用于 ARMv6 及更高版本。此页面中的一个示例是:Linux Kernel: System call hooking example

cr0 寄存器在 ARM 架构中不存在,并且链接的答案中所述的一些功能,如 lookup_address、change_page_attr 等也不存在于 ARM 中。我尝试了 ARM 中存在的解决方案,例如 set_memory_rw(它没有改变任何东西,写入内核文本仍然会导致 oops)、mem_text_write_kernel_word(写入内核文本仍然会导致 oops)等。

oops 日志示例(为演示而格式化):

<3>[  239.987689] RKP -> Inst bf3e0098 out of cpu_v7_set_pte_ext range\
 from c01159c4 to c0115a1c
<1>[  239.988079] Unable to handle kernel paging request at virtual\
 address c01c1d50
<1>[  239.988123] pgd = ea8e4000
<1>[  239.988280] [c01c1d50] *pgd=0da00011
<0>[  239.988377] Internal error: Oops: 80f [#1] PREEMPT SMP ARM
<4>[  239.988416] Modules linked in: my_mod(O+) wlan(PO) mhi(O)
<4>[  239.988469] CPU: 0 PID: 5443 Comm: insmod \
 Tainted: P        W  O 3.10.0-2413392 #1
<4>[  239.988521] task: e4af4ec0 ti: da95a000 task.ti: da95a000
<4>[  239.988565] PC is at my_mod_init+0x98/0x1000 [my_mod]
<4>[  239.988605] LR is at my_mod_init+0x8c/0x1000 [my_mod]

[snip]

<4>[  239.994032] [<bf3e0098>] (my_mod_init+0x98/0x1000 [my_mod]) from\
     [<c010065c>] (do_one_initcall+0xcc/0x180)
<4>[  239.994107] [<c010065c>] (do_one_initcall+0xcc/0x180) from\
     [<c01c524c>] (load_module+0x1c98/0x1fc0)
<4>[  239.994174] [<c01c524c>] (load_module+0x1c98/0x1fc0) from\
     [<c01c5670>] (SyS_init_module+0xfc/0x11c)
<4>[  239.994240] [<c01c5670>] (SyS_init_module+0xfc/0x11c) from\
     [<c0106328>] (__sys_trace_return+0x0/0x18)
<0>[  239.994303] Code: ebffebdc e59f202c e1a00004 e59f3028 (e5832d50) 
<4>[  239.994580] ---[ end trace dec6997083161644 ]---
<0>[  239.994618] Kernel panic - not syncing: Fatal exception

即使尝试注册 kprobe 也会导致内核 oops:

<3>[  184.769314] RKP -> Inst c0abe2a0 out of cpu_v7_set_pte_ext\
    range from c01159c4 to c0115a1c
<1>[  184.769369] Unable to handle kernel paging request at\
     virtual address c0170ce4
<1>[  184.769416] pgd = dc828000
<1>[  184.769439] [c0170ce4] *pgd=0da00011
<0>[  184.769535] Internal error: Oops: 80f [#1] PREEMPT SMP ARM
<4>[  184.769572] Modules linked in: kp_mod(O+) wlan(PO) mhi(O)
<4>[  184.769620] CPU: 0 PID: 5835 Comm: insmod \
    Tainted: P        W  O 3.10.0-2413392 #1
<4>[  184.769665] task: ea0cf8c0 ti: de9a0000 task.ti: de9a0000
<4>[  184.769706] PC is at __patch_text+0x24/0x3c
<4>[  184.769734] LR is at __patch_text+0x1c/0x3c

[snip]

<4>[  184.776127] [<c0abe2a0>] (__patch_text+0x24/0x3c) from\
    [<c0abf000>] (arm_kprobe+0x24/0x34)
<4>[  184.776188] [<c0abf000>] (arm_kprobe+0x24/0x34) from\
    [<c0ac03d8>] (register_kprobe+0x4f0/0x58c)
<4>[  184.776256] [<c0ac03d8>] (register_kprobe+0x4f0/0x58c) from\
    [<bf3e0010>] (kprobe_init+0x10/0x1000 [kp_mod])
<4>[  184.776325] [<bf3e0010>] (kprobe_init+0x10/0x1000 [kp_mod]) from\
    [<c010065c>] (do_one_initcall+0xcc/0x180)
<4>[  184.776391] [<c010065c>] (do_one_initcall+0xcc/0x180) from\
    [<c01c524c>] (load_module+0x1c98/0x1fc0)
<4>[  184.776450] [<c01c524c>] (load_module+0x1c98/0x1fc0) from\
    [<c01c5670>] (SyS_init_module+0xfc/0x11c)
<4>[  184.776508] [<c01c5670>] (SyS_init_module+0xfc/0x11c) from\
    [<c0106328>] (__sys_trace_return+0x0/0x18)
<0>[  184.776563] Code: e1a00004 ebd9561f e1a01004 e1a00004 (e4815004) 
<4>[  184.776608] ---[ end trace dec6997083161644 ]---
<0>[  184.776642] Kernel panic - not syncing: Fatal exception

有这方面经验的人能否解释一下这个问题?

【问题讨论】:

  • Corey Henderson noted set_memory_rw 在某些情况下失败,唯一的解决方案是查找页表条目并手动设置权限位。如果未提供 lookup_address 函数,virt_to_page 可能适用,但 this answer 也会为某人触发 Oopses。
  • @csharpnewbie 你是否在内核中禁用了CONFIG_DEBUG_RODATA?...
  • mem_text_write_kernel_word() 可能不是您想要的,但可以作为一个很好的起点。

标签: linux-kernel arm mmu


【解决方案1】:

在钩子 sys_call_table 之前调用 set_kernel_text_rw()

linux内核中set_kernel_text_rw()函数的路径 拱\臂\mm\init.c

【讨论】:

    猜你喜欢
    • 2017-12-26
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-07
    • 2010-11-17
    • 2017-03-04
    • 2011-05-14
    相关资源
    最近更新 更多