Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

缓冲区溢出导致内核崩溃 #151

Open
xiran210 opened this issue Dec 16, 2024 · 0 comments
Open

缓冲区溢出导致内核崩溃 #151

xiran210 opened this issue Dec 16, 2024 · 0 comments

Comments

@xiran210
Copy link

xiran210 commented Dec 16, 2024

环境

手机型号:小米10(umi)
内核版本:4.19.318-perf+
系统OS:lineage21
系统版本:14(API 34)
系统指纹:Xiaomi/umi_global/umi:13/RKQ1.211001/V14.0.5.0.TJBMIXM:user/release-key
APatch版本:10763
KernelPatch版本:0.10.7

崩溃原因

bmax121/KernelPatch/kernel/patch/android/userd.c 函数 after_openat 中

static void after_openat(hook_fargs4_t *args, void *udata)
{
    if (args->local.data0) {
        compat_copy_to_user((void *)args->local.data1, ORIGIN_RC_FILE, sizeof(ORIGIN_RC_FILE));
        log_boot("restore rc file: %x\n", args->local.data0);
    }
    if (args->local.data2) {
        fp_unhook_syscall(__NR_openat, before_openat, after_openat);
    }
}

此函数通过判断data0是否恢复用户空间的文件名,并调用log_boot
而在 bmax121/KernelPatch/kpms/demo-syscallhook/syscallhook.c 中
使用了data0用于保存task,导致compat_copy_to_user无论如何都会被调用,可能引起未定义异常

args->local.data0 = (uint64_t)task;

且log_boot也被调用,log_boot实现如下

#define BOOT_LOG_SIZE 0x2000
static char boot_log[BOOT_LOG_SIZE] = { 0 };
static int boot_log_offset = 0;

void log_boot(const char *fmt, ...)
{
    va_list va;
    va_start(va, fmt);
    int ret = vsprintf(boot_log + boot_log_offset, fmt, va);
    va_end(va);
    printk("KP %s", boot_log + boot_log_offset);
    boot_log_offset += ret;
}

当log_boot被多次调用时,会发生缓冲区溢出,最终会覆盖linux_libs_symbol_init初始化的函数表的位置,在before_openat函数中调用compat_strncpy_from_user时由于函数表被覆盖,从而导致PC异常,这也是为什么PC寄存器为restore字符串的hex值的原因,从而导致内核崩溃

解包APatch APK,分析assets\kpimg,具体崩溃位置如下AFA4 ,对应函数为compat_strncpy_from_user,崩溃日志中X16,X3,PC寄存器值一致,验证崩溃位置定位正确

ROM:000000000000AF94 E3 00 00 90                   ADRP            X3, #off_26040@PAGE
ROM:000000000000AF98 63 20 40 F9                   LDR             X3, [X3,#off_26040@PAGEOFF]
ROM:000000000000AF9C 63 00 00 B4                   CBZ             X3, loc_AFA8
ROM:000000000000AF9C
ROM:000000000000AFA0
ROM:000000000000AFA0                               loc_AFA0                                ; CODE XREF: cpyfromuser+1C↓j
ROM:000000000000AFA0 F0 03 03 AA                   MOV             X16, X3
ROM:000000000000AFA4 00 02 1F D6                   BR              X16

崩溃日志

已经关闭内核ASLR

[    0.000000] KP Kernel pa: a0080000
[    0.000000] KP Kernel va: ffffff8008080000
[    0.000000] KP Kernel Version: 413ff
[    0.000000] KP Kernel Patch Version: a07
[    0.000000] KP Kernel Patch Config: 2
[    0.000000] KP Kernel Patch Compile Time: 12:16:35 May  1 2024
[    0.000000] KP Kernel stext prot: 500000a0080793
[    0.000000] KP Region: ffffff8167ac4000, ffffff8167ff4000
[    0.000000] KP KernelPatch start prot: c80001ffac4713
[    0.000000] KP Text: ffffff8167ac4000, ffffff8167ad7620
[    0.000000] KP Data: ffffff8167ae4000, ffffff8167ae8f80
[    0.000000] KP Extra: ffffff8167af4000, ffffff8167aff550
[    0.000000] KP Hook: ffffff8167b00000, ffffff8167c00000
[    0.000000] KP RW: ffffff8167c00000, ffffff8167e00000
[    0.000000] KP ROX: ffffff8167e00000, ffffff8168000000
[    0.000000] KP add vmalloc area: ffffff8167ac4000, 530000
[    0.000000] KP Restore: ffffff80096a7f50, ffffff80096a84c0

...

[    3.270513] Internal error: SP/PC alignment exception: 8a000000 [#1] PREEMPT SMP
[    3.270517] Modules linked in:
[    3.270520] Process init (pid: 1, stack limit = 0x00000000ed062f92)
[    3.270524] CPU: 7 PID: 1 Comm: init Tainted: G S                4.19.318-perf+ #9
[    3.270526] Hardware name: Qualcomm Technologies, Inc. xiaomi umi (DT)
[    3.270529] pstate: 60400005 (nZCv daif +PAN -UAO)
[    3.270532] pc : 0x2065726f747365
[    3.270534] lr : 0xffffff8167ad4298
[    3.270536] sp : ffffff800805b4e0
[    3.270538] x29: ffffff800805b520 x28: ffffffc07fd80f80 
[    3.270541] x27: 0000000000000000 x26: 0000000000000000 
[    3.270543] x25: 0000000056000000 x24: 0000000000213d58 
[    3.270546] x23: ffffff8167b05cc0 x22: ffffff8167b05b80 
[    3.270548] x21: ffffff8167b05b9c x20: ffffff8167ad6fa8 
[    3.270550] x19: ffffff800805bdf8 x18: 0000000000000000 
[    3.270553] x17: 0000000000000000 x16: 722065726f747365 
[    3.270555] x15: 0000000000000000 x14: 0000000000000000 
[    3.270557] x13: 0000000000000000 x12: 0000000000000000 
[    3.270559] x11: 0000000000000000 x10: 0000000000000000 
[    3.270562] x9 : 0000000000000000 x8 : ffffff8167b05ec0 
[    3.270564] x7 : 0000000000000000 x6 : 00000000d503201f 
[    3.270566] x5 : 00000000d503201f x4 : 0000000000000002 
[    3.270568] x3 : 722065726f747365 x2 : 0000000000000020 
[    3.270571] x1 : 0000000000213d58 x0 : ffffff800805b590 
[    3.270573] Call trace:
[    3.270575]  0x2065726f747365
[    3.270577]  0xffffff8167b05f4c
[    3.270584]  el0_svc_common+0x98/0x160
[    3.270587]  el0_svc_handler+0x60/0x78
[    3.270591]  el0_svc+0x8/0x380
[    3.270594] Code: bad PC value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant