TransWikia.com

Can't CVE-2019-2215 on Android: "Unable to handle kernel paging request at virtual address"

Reverse Engineering Asked by PeterHerb on January 11, 2021

I’m playing with Android and I’m trying to gain r/w access to the whole memory using CVE-2019-2215. Long story short, you UAF a binder_thread object and you can read from/write to kernel space.

The first step, getting task_struct, works as expected but overwriting addr_limit doesn’t. The error Unable to handle kernel paging request at virtual address and the fact that other people on other devices can perform this makes me think there’s something else behind that problem.

I get this kernel panic:

[  400.258967] Unable to handle kernel paging request at virtual address fffffffffffffffe
[  400.258997] pgd = ffffffe55194e000
[  400.259007] [fffffffffffffffe] *pgd=00000000d194f003, *pud=00000000d194f003, *pmd=0000000000000000
[  400.259146] ------------[ cut here ]------------
[  400.259152] Kernel BUG at ffffff80e9b9cbc4 [verbose debug info unavailable]
[  400.259159] Internal error: Oops - BUG: 96000005 [#1] PREEMPT SMP
[  400.259167] Modules linked in: wlan(O) exfat(O)
[  400.259203] CPU: 2 PID: 6877 Comm: cve-2019-2215 Tainted: G        W  O    4.4.78-perf+ #1
[  400.259210] Hardware name: Qualcomm Technologies, Inc. SDM 636 PM660 + PM660L MTP E7S (DT)
[  400.259217] task: ffffffe5f84d0d80 ti: ffffffe551910000 task.ti: fffffffffffffffe
[  400.259235] PC is at n_tty_write+0x168/0x3e8
[  400.259242] LR is at n_tty_write+0xa4/0x3e8
[  400.259248] pc : [<ffffff80e9b9cbc4>] lr : [<ffffff80e9b9cb00>] pstate: 60400145
[  400.259253] sp : ffffffe551913c70
[  400.259258] x29: ffffffe551913c70 x28: ffffffe551910000 
[  400.259268] x27: ffffffe51f344230 x26: ffffff80ea687000 
[  400.259278] x25: ffffffe5dcdda200 x24: ffffffe51f341c00 
[  400.259287] x23: ffffffe51f3440d8 x22: ffffff80e96eb000 
[  400.259297] x21: ffffffe51f341c00 x20: 0000000000000008 
[  400.259312] x19: ffffffe51f344000 x18: fca83dec72c82c59 
[  400.259325] x17: 00000070696c35c8 x16: ffffff80e97cd198 
[  400.259334] x15: 0000007fc1ea0b58 x14: 00000000ffffffff 
[  400.259344] x13: 0000000000000000 x12: 0000007fc1ea0bb8 
[  400.259353] x11: 0000000000000000 x10: ffffff80ebe9b848 
[  400.259362] x9 : 0000000000000018 x8 : ffffff80ebe9b000 
[  400.259371] x7 : ffffffdb80000000 x6 : ffffffe51f341c08 
[  400.259380] x5 : ffffffe51f341c08 x4 : 0000000000000000 
[  400.259391] x3 : 0000000000000140 x2 : 00000000000000b8 
[  400.259409] x1 : ffffffe551910000 x0 : fffffffffffffffe 
[  400.259420] 
[  400.259420] PC: 0xffffff80e9b9cb84:
[  400.259426] cb84  b4000061 aa1303e0 d63f0020 b40011b4 b9404320 375811a0 aa1703e0 97ed6d39
[  400.259456] cba4  910203a0 52800021 92f00002 97ed3cda aa1703e0 94275ce6 f9400b80 f9400400
[  400.259482] cbc4  f9400000 37000f60 aa1903e0 97ffeadc 35000f40 f9410e60 b4000060 b941e800
[  400.259509] cbe4  34000ec0 b9413660 36000b00 b4fffc74 f9414276 91400ac4 910ac09a aa1a03e0
[  400.259540] 
[  400.259540] LR: 0xffffff80e9b9cac0:
[  400.259546] cac0  b9413c02 f9004bb5 f9003fa1 37400262 91036277 9108c27b aa1703e0 f000575a
[  400.259577] cae0  aa1803f5 94275d1b aa1303e0 d538411c 97fffeda aa1b03e0 910203a1 97ed3b74
[  400.259603] cb00  b0005500 91302000 f9003ba0 9108c340 f90037a0 1400002a f9401721 f9400c22
[  400.259629] cb20  90ffffe1 9139c021 eb01005f 54fffd20 97fff30a 93407c1a b4fffcda 140000b4
[  400.259657] 
[  400.259657] SP: 0xffffffe551913c30:
[  400.259663] 3c30  e9b9cb00 ffffff80 51913c70 ffffffe5 e9b9cbc4 ffffff80 60400145 00000000
[  400.259691] 3c50  1f344000 ffffffe5 00000008 00000000 00000000 00000080 e9b9cae8 ffffff80
[  400.259718] 3c70  51913d20 ffffffe5 e9b98ddc ffffff80 1f344000 ffffffe5 00000000 00000000
[  400.259757] 3c90  00000008 00000000 00000008 00000000 dcdda200 ffffffe5 69230000 00000070
[  400.259782] 
[  400.259788] Process cve-2019-2215 (pid: 6877, stack limit = 0xffffffe551910028)
[  400.259794] Call trace:
[  400.259803] Exception stack(0xffffffe551913a80 to 0xffffffe551913bb0)
[  400.259812] 3a80: ffffffe51f344000 0000008000000000 0000000082b33000 ffffff80e9b9cbc4
[  400.259821] 3aa0: 0000000060400145 ffffffe5f4005000 ffffffe551913ad0 ffffff80ea460dcc
[  400.259829] 3ac0: ffffffe551913b10 ffffff80e97ba680 0000000000000000 ffffffe5f9403c00
[  400.259837] 3ae0: ffffffe551910000 0000000000000000 ffffffbe57b3d700 000000000004cbc2
[  400.259845] 3b00: ffffffe551910000 0000000000000000 ffffffe551913c30 ffffff80e97ba950
[  400.259852] 3b20: ffffffbe57b3d700 ffffffe5ecf5d800 ffffffe551910000 953d5989c78ca9ec
[  400.259859] Unable to handle kernel NULL pointer dereference at virtual address 00000022
[  400.259863] pgd = ffffffe5619b1000
[  400.259867] [00000022] *pgd=00000000e409f003, *pud=00000000e409f003[  400.259872] 3b40: fffffffffffffffe ffffffe551910000 00000000000000b8 0000000000000140
[  400.259877] 3b60: 0000000000000000 ffffffe51f341c08 ffffffe51f341c08 ffffffdb80000000
[  400.259882] 3b80: ffffff80ebe9b000 0000000000000018 ffffff80ebe9b848 0000000000000000
[  400.259886] 3ba0: 0000007fc1ea0bb8 0000000000000000
[  400.259895] [<ffffff80e9b9cbc4>] n_tty_write+0x168/0x3e8
[  400.259901] [<ffffff80e9b98ddc>] tty_write+0x1d4/0x268
[  400.259913] [<ffffff80e97cbf30>] __vfs_write+0x38/0xfc
[  400.259920] [<ffffff80e97cc848>] vfs_write+0xac/0x16c
[  400.259926] [<ffffff80e97cd1ec>] SyS_write+0x54/0xa4
[  400.259936] [<ffffff80e9683170>] el0_svc_naked+0x24/0x28
[  400.259942] Code: aa1703e0 94275ce6 f9400b80 f9400400 (f9400000) 

I tried changing 0xfffffffffffffffe to something lower but that didn’t work. I also looked at n_tty_write.

It looks like the crash comes from something in this loop: https://elixir.bootlin.com/linux/v4.4.78/source/drivers/tty/n_tty.c#L2352

The n_tty_write+0x168 corresponds to this instruction(859cbc4 asm left, C line 45 from Ghidra right) enter image description here

I tried digging further but it’s taking a huge amount of time, I’d really appreciate any tips from more experienced people.

One Answer

It looks like that you need to recheck your task_struct and thread_info offsets and the offset you're writing the addr_limit to is wrong.

I think that the panic happens in if (signal_pending(current)) { in original source.

Here is what you can do for checking the offsets:

  1. download the corresponding kernel source, compile it and use pahole (git, example usage) for relevant structures. This will show you the exact offset of addr_limit that you need.
  2. If you have /proc/config.gz on your phone, you can pull it, unpack it and see all config constants used for building the kernel. This can help you to check offsets manually.

Answered by w s on January 11, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP