binder: fix proc->files use-after-free

proc->files cleanup is initiated by binder_vma_close. Therefore
a reference on the binder_proc is not enough to prevent the
files_struct from being released while the binder_proc still has
a reference. This can lead to an attempt to dereference the
stale pointer obtained from proc->files prior to proc->files
cleanup. This has been seen once in task_get_unused_fd_flags()
when __alloc_fd() is called with a stale "files".

The fix is to protect proc->files with a mutex to prevent cleanup
while in use.

Signed-off-by: Todd Kjos <tkjos@google.com>
Cc: stable <stable@vger.kernel.org> # 4.14
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by Todd Kjos and committed by Greg Kroah-Hartman 7f3dc008 869b5567

+31 -13
+31 -13
drivers/android/binder.c
··· 482 482 * @tsk task_struct for group_leader of process 483 483 * (invariant after initialized) 484 484 * @files files_struct for process 485 - * (invariant after initialized) 485 + * (protected by @files_lock) 486 + * @files_lock mutex to protect @files 486 487 * @deferred_work_node: element for binder_deferred_list 487 488 * (protected by binder_deferred_lock) 488 489 * @deferred_work: bitmap of deferred work to perform ··· 531 530 int pid; 532 531 struct task_struct *tsk; 533 532 struct files_struct *files; 533 + struct mutex files_lock; 534 534 struct hlist_node deferred_work_node; 535 535 int deferred_work; 536 536 bool is_dead; ··· 879 877 880 878 static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) 881 879 { 882 - struct files_struct *files = proc->files; 883 880 unsigned long rlim_cur; 884 881 unsigned long irqs; 882 + int ret; 885 883 886 - if (files == NULL) 887 - return -ESRCH; 888 - 889 - if (!lock_task_sighand(proc->tsk, &irqs)) 890 - return -EMFILE; 891 - 884 + mutex_lock(&proc->files_lock); 885 + if (proc->files == NULL) { 886 + ret = -ESRCH; 887 + goto err; 888 + } 889 + if (!lock_task_sighand(proc->tsk, &irqs)) { 890 + ret = -EMFILE; 891 + goto err; 892 + } 892 893 rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE); 893 894 unlock_task_sighand(proc->tsk, &irqs); 894 895 895 - return __alloc_fd(files, 0, rlim_cur, flags); 896 + ret = __alloc_fd(proc->files, 0, rlim_cur, flags); 897 + err: 898 + mutex_unlock(&proc->files_lock); 899 + return ret; 896 900 } 897 901 898 902 /* ··· 907 899 static void task_fd_install( 908 900 struct binder_proc *proc, unsigned int fd, struct file *file) 909 901 { 902 + mutex_lock(&proc->files_lock); 910 903 if (proc->files) 911 904 __fd_install(proc->files, fd, file); 905 + mutex_unlock(&proc->files_lock); 912 906 } 913 907 914 908 /* ··· 920 910 { 921 911 int retval; 922 912 923 - if (proc->files == NULL) 924 - return -ESRCH; 925 - 913 + mutex_lock(&proc->files_lock); 914 + if (proc->files == NULL) { 915 + retval = -ESRCH; 916 + goto err; 917 + } 926 918 retval = __close_fd(proc->files, fd); 927 919 /* can't restart close syscall because file table entry was cleared */ 928 920 if (unlikely(retval == -ERESTARTSYS || ··· 932 920 retval == -ERESTARTNOHAND || 933 921 retval == -ERESTART_RESTARTBLOCK)) 934 922 retval = -EINTR; 935 - 923 + err: 924 + mutex_unlock(&proc->files_lock); 936 925 return retval; 937 926 } 938 927 ··· 4640 4627 ret = binder_alloc_mmap_handler(&proc->alloc, vma); 4641 4628 if (ret) 4642 4629 return ret; 4630 + mutex_lock(&proc->files_lock); 4643 4631 proc->files = get_files_struct(current); 4632 + mutex_unlock(&proc->files_lock); 4644 4633 return 0; 4645 4634 4646 4635 err_bad_arg: ··· 4666 4651 spin_lock_init(&proc->outer_lock); 4667 4652 get_task_struct(current->group_leader); 4668 4653 proc->tsk = current->group_leader; 4654 + mutex_init(&proc->files_lock); 4669 4655 INIT_LIST_HEAD(&proc->todo); 4670 4656 proc->default_priority = task_nice(current); 4671 4657 binder_dev = container_of(filp->private_data, struct binder_device, ··· 4919 4903 4920 4904 files = NULL; 4921 4905 if (defer & BINDER_DEFERRED_PUT_FILES) { 4906 + mutex_lock(&proc->files_lock); 4922 4907 files = proc->files; 4923 4908 if (files) 4924 4909 proc->files = NULL; 4910 + mutex_unlock(&proc->files_lock); 4925 4911 } 4926 4912 4927 4913 if (defer & BINDER_DEFERRED_FLUSH)