Отключить защиту от записи для страниц памяти в ARM
Я исследовал тему отключения защиты от записи для текста ядра в linux, и я могу найти только решения для x86 linux, который временно очищает бит 16 регистра cr0, записывает в память, а затем устанавливает бит 16 регистр cr0 снова. Однако это не работает для ARMv6 и выше. Пример этого находится на этой странице: Ядро Linux: Пример перехвата системных вызовов.
регистр cr0 отсутствует в архитектуре ARM, а некоторые функции, указанные в ответах по ссылке, такие как lookup_address, change_page_attr и т. д., также отсутствуют в ARM. Я попробовал решения, представленные в ARM, такие как set_memory_rw (который ничего не изменил, запись в текст ядра по-прежнему вызывает ошибки), mem_text_write_kernel_word (запись в текст ядра по-прежнему вызывает ошибки) и т. Д.
Пример журнала упс (отформатирован для презентации):
<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 вызывает ошибку ядра:
<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
Может кто-то опытный в этой области пролить свет на эту проблему?
1 ответ
вызовите set_kernel_text_rw() перед перехватом sys_call_table
путь к функции set_kernel_text_rw() в ядре linux arch\arm\mm\init.c