ARM64-Linux内存写保护不会禁用 [英] ARM64 - Linux Memory Write protection won't disable

查看:527
本文介绍了ARM64-Linux内存写保护不会禁用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从LKM内禁用ARM64系统上的Memory Write保护. (Xen虚拟机管理程序的DOM0中的Startet)

i'm trying to disable the Memory Write protection on an ARM64 system from within an LKM. (Startet in the DOM0 of the Xen hypervisor)

我使用Linux内核功能找到了对应于虚拟地址的PTE.

I found the corresponding PTE to an virtual address by using the Linux Kernel Functions.

pgd_t *pgd;
pte_t *ptep, pte;
pud_t *pud;
pmd_t *pmd;
pgd = pgd_offset(init_mm, (addr));


if (pgd_none(*pgd) || pgd_bad(*pgd))
    goto out;
printk(KERN_NOTICE "Valid pgd 0x%lx\n",pgd);

pud = pud_offset(pgd, addr);
if (pud_none(*pud) || pud_bad(*pud))
    goto out;
printk(KERN_NOTICE "Valid pud 0x%lx\n",pud);

pmd = pmd_offset(pud, addr);
if (pmd_none(*pmd) || pmd_bad(*pmd))
    goto out;
printk(KERN_NOTICE "Valid pmd 0x%lx\n",pmd);

ptep = pte_offset_map(pmd, addr);
if (!ptep)
    goto out;
pte = *ptep;

此后,我清除了PTE的第7位,根据ARM-ARM(第2066页-第1阶段VMSAv8-64块和页面描述符中的属性字段),它应禁用写保护,因为它允许从EL1(AP [2:1] == 00) 尽管此位(第51位)用于阶段2的翻译(我的工作是在阶段1中),但仍使用Linux内核功能使使pte可写",这是我的工作

After this I'm clearing the 7th Bit of the PTE which should, according to the ARM-ARM (Page 2066 - Attribute fields in stage 1 VMSAv8-64 Block and Page descriptors) disable the write protection as it allows write from EL1 (AP[2:1]==00) Additioanlly im using the Linux Kernel function wo "make the pte writable" eventhough this Bit (Bit 51) is used for stage 2 translation (my work is with Stage 1)

printk(KERN_INFO "PTE before 0x%lx\n", pte);
printk(KERN_INFO "Setting PTE write\n");

pte = pte_mkwrite(pte);
pte = clear_pte_bit(pte, __pgprot((_AT(pteval_t, 1) << 7)));


printk(KERN_INFO "PTE after         0x%lx\n", pte);
flush_tlb_all();
printk(KERN_INFO "PTE nach flush    0x%lx\n", pte);

由于使用memcpy写入内存时仍然出现内核错误,因此我调用了两次禁用写保护的功能以检查我的设置.这些是两个函数调用的输出:

Because i still get a Kernel Panic when writting to the memory with memcpy, i call the function to disable write protection twice in order to check my settings. These are the outputs for two function calls:

[ 1804.078382] Valid pgd 0xffff000008e7d000
[ 1804.082397] Valid pud 0xffff800017ffe000
[ 1804.086374] Valid pmd 0xffff800017ffd200
[ 1804.090367] PTE before                       0xc0000040081793
[ 1804.094529] Setting PTE write
[ 1804.097562] PTE after                        0xc8000040081713
[ 1804.101637] PTE after flush                  0xc8000040081713
[...More outputs...]
[ 1804.117395] ROUND 2########################
[ 1804.149190] Valid pgd 0xffff000008e7d000
[ 1804.153207] Valid pud 0xffff800017ffe000
[ 1804.157178] Valid pmd 0xffff800017ffd200
[ 1804.161172] PTE before                       0xc0000040081793
[ 1804.165329] Setting PTE write
[ 1804.168366] PTE after                        0xc8000040081713
[ 1804.172443] PTE after flush                  0xc8000040081713

(差异是从左数第二个点是8而不是0,在从右数第二个点是1而不是9)

(difference is the 8 instead of an 0 on the second spot from left, and the 1 instead of a 9 on the second one from right)

如您所见,在第二次调用该函数之后,我们希望第一轮的最后一个PTE值与第二轮的最后一个PTE值相同(输出NR:1804.101637!= 1804.161172),在这里不是这种情况.

As you can see, after call the function the second time, we would expect that the last PTE Value of the first round, is the same as the first one of the second round (Output NR: 1804.101637 != 1804.161172), which is not the case here.

我正在使用以下命令写入内存:

I'm writing into the memory with this command:

static unsigned char replace_blr[4] = {0xD6,0x3F, 0x03,0xA0}; (global defined)
memcpy(el1_sync,replace_blr,4);

其中el1_sync包含我用于pte查找的虚拟地址.

where el1_sync containts the virtuall address that I'm using for the pte finding.

有人看到为什么我的PTE配置未更新/重置吗? 如果有人可以选择让我直接写入内核内存,我也将不胜感激.我的目标只是启用写入给定虚拟地址的页面的功能. (就像许多x86 rootkit一样,但在ARM64上)

Does anybody see, why my PTE configuration is not updated/is reset? If somebody got an alternative to let me write directly into the kernel memory, i would also appreciate any other input. My goal is just to enable writing into the Page of the given virtual address. (Just like many of the x86 rootkits, but on ARM64)

写入时内核OOPS :(虚拟地址:0xffff000008081a00)

KERNEL OOPS when writing: (Virtuall Address: 0xffff000008081a00)

  [   49.776343] Unable to handle kernel paging request at virtual address ffff000008081a00
[   49.784313] pgd = ffff800013d91000
[   49.787777] [ffff000008081a00] *pgd=0000000000000000[   49.792542] 
[   49.794094] Internal error: Oops: 9600004f [#1] PREEMPT SMP
[   49.799721] Modules linked in: mod_init(O+) adv7511 kirin_drm drm_kms_helper dw_drm_dsi drm asix 
usbnet ipv6
[   49.809610] CPU: 1 PID: 2328 Comm: insmod Tainted: G           O    4.9.0-hikey-139764-g3e36302a0
621-dirty #1
[   49.819580] Hardware name: HiKey Development Board (DT)
[   49.824876] task: ffff80001580b200 task.stack: ffff800015af8000
[   49.830864] PC is at init_module+0xf8/0x1f0 [mod_init]
[   49.836061] LR is at init_module+0xe8/0x1f0 [mod_init]
[   49.841259] pc : [<ffff000000b71568>] lr : [<ffff000000b71558>] pstate: 00000145
[   49.848716] sp : ffff800015afbc40
[   49.852099] x29: ffff800015afbc40 x28: 00000000024000c0 
[   49.857474] x27: 0000000000000124 x26: ffff000008129f68 
[   49.862851] x25: 0000000000000001 x24: ffff800014f5abc8 
[   49.868227] x23: ffff000000b730d0 x22: ffff800014f5ad80 
[   49.873604] x21: 0000000000000000 x20: ffff000000b72370 
[   49.878981] x19: ffff000000b73380 x18: 0000000000000010 
[   49.884357] x17: 0000aaaadb4f02b0 x16: 0000000000000012 
[   49.889734] x15: 0000000000000006 x14: ffff000088e40a27 
[   49.895110] x13: ffff000008e40a35 x12: 0000000000000007 
[   49.900487] x11: 000000000000016d x10: 0000000005f5e0ff 
[   49.905863] x9 : 000000000000016e x8 : 70752064656b6361 
[   49.911240] x7 : 62207972746e6520 x6 : ffff000008e40a53 
[   49.916616] x5 : 0000000000000000 x4 : 0000000000000000 
[   49.921993] x3 : 0000000000000000 x2 : 00000000a0033fd6 
[   49.927370] x1 : ffff000008081a00 x0 : 0000000000000000 
[   49.932745] 
[   49.934309] Process insmod (pid: 2328, stack limit = 0xffff800015af8020)
[   49.941073] Stack: (0xffff800015afbc40 to 0xffff800015afc000)
[   49.946885] bc40: ffff800015afbc60 ffff0000080830b8 ffff000000b71470 ffff800015af8000
[   49.954776] bc60: ffff800015afbcd0 ffff00000816521c ffff000000b73080 ffff000008d80000
[   49.962667] bc80: ffff000000b73080 ffff800014f5ad80 ffff000000b73080 ffff800014f5ab80
[   49.970558] bca0: ffff000000b730d0 ffff800014f5abc8 0000000000000001 ffff000008129f68
[   49.978450] bcc0: 0000000000000124 00000000024000c0 ffff800015afbd00 ffff00000812d454
[   49.986341] bce0: ffff800015afbe58 0000000000000001 ffff000000b73080 ffff800014f5ab80
[   49.994232] bd00: ffff800015afbe10 ffff00000812dd78 0000000000000000 0000000000000003
[   50.002124] bd20: 0000aaaadb4dd8d0 0000ffffaf31fcf4 0000000080000000 0000000000000015
[   50.010015] bd40: 0000000000000123 0000000000000111 ffff0000088c2000 ffff800015af8000
[   50.017906] bd60: 000000000003c788 ffff000008b3c088 ffff000000000072 ffff000000000064
[   50.025798] bd80: ffff80000000006e ffff000000b76000 ffff80001511a118 ffff000000b73250
[   50.033689] bda0: ffff0000088d24c0 ffff0000088d24b0 000000007fffffff 0000000000000003
[   50.041581] bdc0: 0000000000000123 ffff0000081dfa18 ffff800015afbe10 0000000000000000
[   50.049472] bde0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
[   50.057364] be00: 0000000000000000 0000000000000000 0000000000000000 ffff000008082ef0
[   50.065255] be20: 0000000000000000 0000000000000000 ffffffffffffffff 0000000000000000
[   50.073147] be40: ffff800015afbeb0 000000000003c788 ffff00000cb6d000 ffff00000cb6d000
[   50.081038] be60: 000000000003c788 ffff00000cba9088 ffff00000cba8f70 ffff00000cb8d838
[   50.088929] be80: 0000000000003000 0000000000003798 0000000000000000 0000000000000000
[   50.096820] bea0: 0000000000000bd0 0000001a00000019 0000000000000008 0000000000000005
[   50.104712] bec0: 0000000000000003 0000aaaadb4dd8d0 0000000000000000 0000000000000003
[   50.112603] bee0: 0000000000000000 000000000001fd31 0000000000000001 0000000000000001
[   50.120497] bf00: 0000000000000111 fefefefefefefeff 00000000ffffffff 0000000000000030
[   50.128386] bf20: 0000000000000004 0000000000000008 0000ffffaf259a94 0000ffffaf3a1588
[   50.136278] bf40: 0000ffffaf31fcd0 0000aaaadb4f02b0 0000ffffcb3fe1b0 0000aaaaf319f190
[   50.144169] bf60: 0000000000000000 0000aaaadb4dd8d0 0000000000000000 0000000000000002
[   50.152061] bf80: 0000aaaaf319e0d0 0000ffffcb3fe518 0000000000000000 0000000000000000
[   50.159952] bfa0: 0000000000000000 0000ffffcb3fe450 0000aaaadb4d3bd0 0000ffffcb3fe450
[   50.167843] bfc0: 0000ffffaf31fcf4 0000000080000000 0000000000000003 0000000000000111
[   50.175735] bfe0: 0000000000000000 0000000000000000 0000000000000000 0002000000000035
[   50.183624] Call trace:
[   50.186141] Exception stack(0xffff800015afba70 to 0xffff800015afbba0)
[   50.192644] ba60:                                   ffff000000b73380 0001000000000000
[   50.200536] ba80: ffff800015afbc40 ffff000000b71568 0000000000000006 0000000000000006
[   50.208428] baa0: ffff000008e42e4a 000000000000001c ffff000008e40000 ffff000008b39520
[   50.216323] bac0: ffff800015afbb60 ffff0000080ff5a0 ffff000000b73380 ffff000000b72370
[   50.224210] bae0: 0000000000000000 ffff800014f5ad80 ffff000000b730d0 ffff800014f5abc8
[   50.232102] bb00: 0000000000000001 ffff000008129f68 0000000000000000 ffff000008081a00
[   50.239993] bb20: 00000000a0033fd6 0000000000000000 0000000000000000 0000000000000000
[   50.247889] bb40: ffff000008e40a53 62207972746e6520 70752064656b6361 000000000000016e
[   50.255776] bb60: 0000000005f5e0ff 000000000000016d 0000000000000007 ffff000008e40a35
[   50.263668] bb80: ffff000088e40a27 0000000000000006 0000000000000012 0000aaaadb4f02b0
[   50.271564] [<ffff000000b71568>] init_module+0xf8/0x1f0 [mod_init]
[   50.277808] [<ffff0000080830b8>] do_one_initcall+0x38/0x128
[   50.283441] [<ffff00000816521c>] do_init_module+0x5c/0x1b8
[   50.288992] [<ffff00000812d454>] load_module+0x1a44/0x20b8
[   50.294540] [<ffff00000812dd78>] SyS_finit_module+0xd8/0xe8
[   50.300176] [<ffff000008082ef0>] el0_svc_naked+0x24/0x28
[   50.305554] Code: 58000802 52800000 f9400661 b9400042 (b9000022) 
--[ end trace 13

推荐答案

发现了我的错误.我研究的是局部变量"而不是重点.这样就解决了:

Found my error. I worked on the "local variable" instead of the point. This fixed it:

*ptep = clear_pte_bit(*ptep, __pgprot((_AT(pteval_t, 1) << 7)));

其余代码正确

这篇关于ARM64-Linux内存写保护不会禁用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆