一、漏洞背景

  • Google在2020-03的Android安全公告中,指出了一个联发科芯片手机中的严重安全漏洞,成功利用此漏洞的攻击者可以取得设备的root权限。由于取得了极高的权限,所以攻击者可以进一步实施其它的恶意行为,并且用户毫不知情。漏洞被命名为MediaTek-SU,并以CVE-2020-0069来跟踪。
  • 值得注意的是,XDA-Developers在其报告中写到,早在2019年4月,他们就已经知晓了此事。

二、漏洞细节

  • 在搭载联发科芯片的智能手机上存在命令队列驱动程序/dev/cmdq,该驱动程序具备读写任意内存的功能,代码位于/drivers/misc/mediatek/cmdq/hv1/cmdq_driver.ccmdq_ioctl函数中:
  1. static long cmdq_ioctl(struct file *pFile, unsigned int code, unsigned long param) {
  2. // ...
  3. switch(code) {
  4. // ...
  5. case CMDQ_IOCTL_ALLOC_WRITE_ADDRESS:
  6. do {
  7. struct cmdqWriteAddressStruct addrReq;
  8. dma_addr_t paStart = 0;
  9. CMDQ_LOG("CMDQ_IOCTL_ALLOC_WRITE_ADDRESS\n");
  10. if (copy_from_user(&addrReq, (void *)param, sizeof(addrReq))) {
  11. CMDQ_ERR("CMDQ_IOCTL_ALLOC_WRITE_ADDRESS copy_from_user failed\n");
  12. return -IOCTL_RET_COPY_ALLOC_WRITE_ADDR_FROM_USER_FAIL;
  13. }
  14. status = cmdqCoreAllocWriteAddress(addrReq.count, &paStart);
  15. if (0 != status) {
  16. CMDQ_ERR("CMDQ_IOCTL_ALLOC_WRITE_ADDRESS cmdqCoreAllocWriteAddress() failed\n");
  17. return -IOCTL_RET_ALLOC_WRITE_ADDR_FAIL;
  18. }
  19. addrReq.startPA = (uint32_t) paStart;
  20. CMDQ_LOG("CMDQ_IOCTL_ALLOC_WRITE_ADDRESS get 0x%08x\n", addrReq.startPA);
  21. if (copy_to_user((void *)param, &addrReq, sizeof(addrReq))) {
  22. CMDQ_ERR("CMDQ_IOCTL_ALLOC_WRITE_ADDRESS copy_to_user failed\n");
  23. return -IOCTL_RET_COPY_ALLOC_WRITE_ADDR_TO_USER_FAIL;
  24. }
  25. status = 0;
  26. } while (0);
  27. break;
  28. case CMDQ_IOCTL_READ_ADDRESS_VALUE:
  29. do {
  30. struct cmdqReadAddressStruct readReq;
  31. CMDQ_LOG("CMDQ_IOCTL_READ_ADDRESS_VALUE\n");
  32. if (copy_from_user(&readReq, (void *)param, sizeof(readReq))) {
  33. CMDQ_ERR("CMDQ_IOCTL_READ_ADDRESS_VALUE copy_from_user failed\n");
  34. return -IOCTL_RET_COPY_READ_ADDR_FROM_USER_FAIL;
  35. }
  36. /* this will copy result to readReq->values buffer*/
  37. cmdq_driver_process_read_address_request(&readReq);
  38. status = 0;
  39. } while (0);
  40. break;
  41. // ...
  42. }
  43. // ...
  44. }
  • 由于该驱动程序结点的权限配置错误,导致任意应用都可以通过ioctl系统调用访问该驱动程序,并且读写任意内存,从而获得root权限。
  • 在实际测试过程中发现,联发科将/dev/cmdq的SELinux标签配置为了mtk_cmdq_device,又将该标签的openreadioctl系统调用操作权限赋予给了appdomain域。由于所有Android应用程序都位于appdomain域中,所以就导致任意应用程序可利用该驱动程序提升自身权限到root。

三、漏洞验证

  • 在XDA-Developers论坛上,已经给出了PoC,直接在adb shell中执行即可获得root权限,其源代码并未公开,不过基本的利用原理就是通过ioctl系统调用访问/dev/cmdq来读写内存。
  • 该漏洞影响的内核版本:Linux Kernel 3.18, 4.4, 4.9, 4.14
  • 该漏洞影响的联发科芯片型号:MT6580, MT6595, MT6735, MT6737, MT6738, MT6739, MT6750, MT6753, MT6755, MT6757, MT6758, MT6761, MT6762, MT6763, MT6765, MT6771, MT6779, MT6795, MT6797, MT6799, MT8163, MT8167, MT8173, MT8176, MT8183

四、漏洞影响

  • 任意第三方应用程序都可以利用此漏洞获得root权限,甚至可以关闭SELinux,从而完全控制整个手机。

五、漏洞补丁

  • Google已经在2020-03的Android安全公告中已经修复了该漏洞,其Android安全补丁级别为2020-03-05,关于补丁的细节暂未发布。