New issue
Advanced search Search tips
Starred by 1 user
Status: Fixed
Owner:
Closed: Feb 2017
Cc:



Sign in to add a comment
LG: touchscreen driver write_log kernel read/write
Project Member Reported by markbrand@google.com, Nov 14 2016 Back to list
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.

This bug is subject to a 90 day disclosure deadline. If 90 days elapse
without a broadly available patch, then the bug report will automatically
become visible to the public.

 
touchscreen_kernel_ds.c
4.1 KB View Download
kernel_ds
17.5 KB View Download
Project Member Comment 1 by markbrand@google.com, Nov 15 2016
Labels: -Reported-2016-Nov-14 Reported-2016-Nov-15
Project Member Comment 2 by markbrand@google.com, Jan 9 2017
Labels: LVE-SMP-160013
Fix announced in LG January bulletin: https://lgsecurity.lge.com/
Project Member Comment 3 by markbrand@google.com, Feb 9 2017
Labels: -Restrict-View-Commit
Status: Fixed
Derestricting since the issue is reported fixed. Haven't been able to check fix since the update is not available for my test device yet.
Sign in to add a comment