2017-07-20 177 views
0

我试图从LKM内禁用ARM64系统上的内存写保护。 (Xen hypervisor的DOM0中的开始)ARM64 - Linux内存写保护将不会禁用

我通过使用Linux内核函数找到了相应的PTE到虚拟地址。

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)写入使用Linux内核函数添加“使pte可写”事件,尽管此位(位51)用于第2阶段转换(我的工作是与舞台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的内存时仍然获得内核恐慌,我调用函数,以便两次禁用写保护,CHEC k我的设置。这些是输出用于两个函数调用:

[ 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的从右边第二个)

正如你所看到的,第二次调用该函数之后,我们预计第一轮的最后一个PTE值与第二轮的第一个(输出NR:1804.101637!= 1804.161172)相同,这不是这里的情况。

我正在写与此命令的记忆:

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

其中el1_sync containts我使用的PTE找到virtuall地址。

有人看到,为什么我的PTE配置没有更新/重置? 如果有人让我直接写入内核内存,我也会很感激任何其他输入。我的目标是只要写入给定的虚拟地址的页面。 (就像许多在x86的rootkit,但ARM64)

问候 弗洛里安

内核oops中书写时:(Virtuall地址: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: 000000000000ffff0000088c2000 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: 000000000000ffff0000081dfa18 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.2] 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 
+0

- 移动评论回答 - – MajorasKid

回答

0

发现我的错误。我研究了“局部变量”而不是点。这个固定:

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

休息是正确的