Issue 1978: Samsung kernel: Arbitrary-kfree in /dev/vipx and /dev/vertex
依然是samsung的设备。没有该设备代码,下面的代码搬运自原博客
原始博客链接: https://bugs.chromium.org/p/project-zero/issues/detail?id=1978
poc:https://bugs.chromium.org/p/project-zero/issues/attachmentText?aid=423212
代码如下:

static int __vipx_ioctl_get_container(struct vs4l_container_list *karg,
    struct vs4l_container_list __user *uarg)
{
...

  ret = copy_from_user(karg, uarg, sizeof(*karg));  //【1】

...

  ucon = karg->containers;
  size = karg->count * sizeof(*kcon);
  kcon = kzalloc(size, GFP_KERNEL);

...

  karg->containers = kcon;
  ret = copy_from_user(kcon, ucon, size);   // 【2】
  if (ret) {
    vipx_err("Copy failed [CONTAINER] (%d)\n", ret);
    goto p_err_free;        // 【3】
  }

  for (idx = 0; idx < karg->count; ++idx) { 
    ubuf = kcon[idx].buffers;
    size = kcon[idx].count * sizeof(*kbuf);
    kbuf = kzalloc(size, GFP_KERNEL);

...

    kcon[idx].buffers = kbuf;   // Replace user* with krnl*
    ret = copy_from_user(kbuf, ubuf, size);【4】

    if (ret) {
      vipx_err("Copy failed [CONTAINER] (%d)\n", ret);
      goto p_err_free;      // 【5】

      // all pointers are converted
    }
  }
...

  return 0;

p_err_free:
  for (idx = 0; idx < karg->count; ++idx)   // 
    kfree(kcon[idx].buffers);   // 【6】
  kfree(kcon);

p_err:
  return ret;
}
  • 【1】:将uarg复制给了karg
  • 【2】:将ucon的数据复制给了kcon
  • 【3】:在上面的代码中没有看到对ucon有效性的检查,因此如果传入一个无效的ucon地址,copy_from_user就会产生错误,就会来到p_err_free处,对应的【5】,此时就会遍历free kcon里面的buffers指针,但是此时的kcon刚被申请,数据还没有初始化,因此任意free可能会free掉一块有效内存,当free掉无效地址内存时就会发生崩溃。
  • 【4】:假设上面传入的ucon地址是一个有效的地址,把用户空间的containers复制进kcon以后,kcon中的buffers指针就是用户传入的,该驱动仍然没对这个指针进行检查,就执行了copy_from_user,当ubuf非法时又会产生错误,执行p_err_free,如同上面的分析一样,可以任意地址free。

preView