2016-11-09

KERNEL SECURITY FLAWS

About a month ago, when I was looking at the android kernle source code, I found a strange logic, it could trigger the device crash by bypassing the detection logic. I test it in Nexus 4 and the security patch level is 20161005.

The last_kmsg:

[  510.188720] Unable to handle kernel paging request at virtual address 40404040
[  510.188873] pgd = e453c000
[  510.188934] [40404040] *pgd=00000000
[  510.189422] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
[  510.189575] CPU: 0    Not tainted  (3.4.0-cyanogenmod-g756c08a #1)
[  510.189636] PC is at memcmp+0x14/0x34
[  510.189727] LR is at iw_set_band_config+0x2c/0x58
[  510.189849] pc : [<c037573c>]    lr : [<c0615260>]    psr: 80000013
[  510.189849] sp : e6567e44  ip : 00000000  fp : c09864e8
[  510.190032] r10: c0615234  r9 : 00000001  r8 : c09c94e8
[  510.190124] r7 : 0000004b  r6 : 00000000  r5 : 40404040  r4 : 40404040
[  510.190246] r3 : 00000000  r2 : 00000008  r1 : c0b7ef56  r0 : 40404040
[  510.190368] Flags: Nzcv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment user
[  510.190429] Control: 10c5787d  Table: a633c06a  DAC: 00000015
[  510.190551]
[  510.190582] PC: 0xc03756bc:
[  510.190704] 56bc  e3520000 1afffff3 e3a00001 e8bd8010 e5d03000 e353004e 0a00000e 
...
[  510.232727] [<c037573c>] (memcmp+0x14/0x34) from [<c0615260>] (iw_set_band_config+0x2c/0x58)
[  510.232788] [<c0615260>] (iw_set_band_config+0x2c/0x58) from [<c08bcdf8>] (ioctl_private_call+0xdc/0x278)
[  510.232940] [<c08bcdf8>] (ioctl_private_call+0xdc/0x278) from [<c08bc788>] (wext_handle_ioctl+0x1cc/0x1e4)
[  510.233062] [<c08bc788>] (wext_handle_ioctl+0x1cc/0x1e4) from [<c078cb6c>] (dev_ioctl+0x65c/0x6a0)
[  510.233215] [<c078cb6c>] (dev_ioctl+0x65c/0x6a0) from [<c0232288>] (vfs_ioctl+0x28/0x3c)
[  510.233337] [<c0232288>] (vfs_ioctl+0x28/0x3c) from [<c0232ccc>] (do_vfs_ioctl+0x484/0x574)
[  510.233428] [<c0232ccc>] (do_vfs_ioctl+0x484/0x574) from [<c0232e04>] (sys_ioctl+0x48/0x74)
[  510.233551] [<c0232e04>] (sys_ioctl+0x48/0x74) from [<c0105a00>] (ret_fast_syscall+0x0/0x30)
[  510.233673] Code: e3a03000 e1a05000 e1530002 0a000005 (e7d54003)
[  510.245880] ---[ end trace 8731deb30c10132d ]---
[  510.246643] Kernel panic - not syncing: Fatal exception
[  511.518859] wcnss_8960: crash shutdown : 0
[  515.030487] Rebooting in 5 seconds..
[  520.046020] Going down for restart now
[  520.046325] in panic

No errors detected
Boot info:
Last boot reason: kernel_panic

so I write a POC and report this security issue to google.

Soon, I received a reply.

    Hey,

    The Nexus 4 is no longer being supported and this vulnerability does not affect any other Nexus devices. Closing issue.

    Thanks,

    Android Security Team

I think they are not going to look at the root cause of the problem.

As we knows, the socket func could be called by ioctl, the ioctl last call func is ioctlprivateiw_point.

static int ioctl_private_iw_point(struct iw_point *iwp, unsigned int cmd,
                  const struct iw_priv_args *descr,
                  iw_handler handler, struct net_device *dev,
                  struct iw_request_info *info, int extra_size)
{
    char *extra;
    int err;
    if (IW_IS_SET(cmd)) {   // is set op
        if (!iwp->pointer && iwp->length != 0)  // set iwp->pointer = 0x40404040 && iwp->length = 0, pass this check
            return -EFAULT;
        if (iwp->length > (descr->set_args & IW_PRIV_SIZE_MASK))
            return -E2BIG;
    } else if (!iwp->pointer)
        return -EFAULT;
    extra = kmalloc(extra_size, GFP_KERNEL);
    if (!extra)
        return -ENOMEM;

    // If it is a SET, get all the extra data in here 
    if (IW_IS_SET(cmd) && (iwp->length != 0)) {     // pass this check because of iwp->length = 0
        if (copy_from_user(extra, iwp->pointer, extra_size)) {
            err = -EFAULT;
            goto out;
        }
    }

    // Call the handler
    // pass all check but iwp->pointer is not valid, will casue a security issue.
    err = handler(dev, info, (union iwreq_data *) iwp, extra); 
}

when i set iwp->pointer = 0x40404040 && iwp->length = 0 but not map 0x40404040, it will pass all check like comment. Once func uses this pointer(not map)and does not detect whether it is valid, it will casue a security issue. and this issue code logic (ioctlprivateiw_point) appeared in all kernel.

by chance, I found the proof in wlanhddwext.c of nexus4. all func listed below in wlanhddwext.c module (nuxus4) will cause kernel panic.

    iw_set_priv,
    iw_qcom_set_wapi_mode, 
    iw_set_keepalive_params, 
    iw_set_packet_filter_params, 
    iw_set_band_config,
    iw_set_dynamic_mcbc_filter,
    iw_setchar_getnone, 
    iw_qcom_set_wapi_bkid,
    iw_set_host_offload
    ...

I gave them the root cause of the above problem. and I say, you can say is a security flaws and the next level func should check this pointer. I only give you a proof by wlanhddwext.c module in nexus4, maybe other modules will appear later. After all, there are still a lot of careless programmers in the world. If you still believe that is not a security issue, i will public it in my blog or other social platform.

Soon, I received a reply.

    Hey,

    We reviewed your latest comments and the code you reference is different in all our other Nexus devices. In those devices, there are adequate checks in place to prevent this issue. We still believe this is not a security issue.

    Thanks,

so, it is really a sad story?

没有评论:

发表评论

Android Root Zap Framework

‎ 1. Warning 请遵守GPL开源协议, 请遵守法律法规, 本项目仅供学习和交流, 请勿用于非法用途! 道路千万条, 安全第一条, 行车不规范, 亲人两行泪. 2. Android Root Zap Frame...