Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86369379

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=990

The following function (and variations on the same code) is used to write to 
files from kernel code in various touchscreen drivers. This copy is from 
RefCode_CustomerImplementation.c - I'm unsure which copy is actually being used
on the LG G4, but I can trigger the vulnerability. A function with the same
issues exists as "write_file" in several files.

int _write_log(char *filename, char *data)
{
  struct file *file;
  loff_t pos = 0;
  int flags;
  char *fname = "/data/logger/touch_self_test.txt";
  char *fname_normal_boot = "/sdcard/touch_self_test.txt";
  char *fname_mfts_folder = "/data/logger/touch_self_test_mfts_folder.txt";
  char *fname_mfts_flat = "/data/logger/touch_self_test_mfts_flat.txt";
  char *fname_mfts_curved = "/data/logger/touch_self_test_mfts_curved.txt";
  int cap_file_exist = 0;

  if (f54_window_crack || f54_window_crack_check_mode == 0) {
    mm_segment_t old_fs = get_fs();
    set_fs(KERNEL_DS);
    flags = O_WRONLY | O_CREAT;

    if (filename == NULL) {
      flags |= O_APPEND;
      switch (mfts_mode) {
      case 0:
        if (factory_boot)
          filename = fname;
        else
          filename = fname_normal_boot;
        break;
      case 1:
        filename = fname_mfts_folder;
        break;
      case 2:
        filename = fname_mfts_flat;
        break;
      case 3:
        filename = fname_mfts_curved;
        break;
      default:
        TOUCH_I("%s : not support mfts_mode\n",
          __func__);
        break;
      }
    } else {
      cap_file_exist = 1;
    }

    if (filename) {
      file = filp_open(filename, flags, 0666);
      sys_chmod(filename, 0666);
    } else {
      TOUCH_E("%s : filename is NULL, can not open FILE\n",
        __func__);
      return -1;
    }

    if (IS_ERR(file)) {
      TOUCH_I("%s : ERR(%ld)  Open file error [%s]\n",
          __func__, PTR_ERR(file), filename);
      set_fs(old_fs);
      return PTR_ERR(file);
    }

    vfs_write(file, data, strlen(data), &pos);
    filp_close(file, 0);
    set_fs(old_fs);

    log_file_size_check(filename);
  }
  return cap_file_exist;
}

int write_log(char *filename, char *data)
{
    return _write_log(filename, data);
}

This code is setting KERNEL_DS, and there is a code-path in which it does not 
restore USER_DS before returning (when mfts_mode is outside the range [0, 3] and
the filename argument is NULL). This can be triggered by first writing to the 
sysfs node /sys/devices/virtual/input/lge_touch/mfts and then reading from the 
sysfs node /sys/devices/virtual/input/lge_touch/sd. (root needed to write to mfts node).

Once the kernel has returned control to userland with KERNEL_DS set, userland can simply read/write from arbitrary kernel addresses. See 
attached for a working exploit for the LG G4, which when run as root will 
disable selinux enforcement.


Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41353.zip