Received: by 10.223.164.202 with SMTP id h10csp2144392wrb; Thu, 16 Nov 2017 10:03:38 -0800 (PST) X-Google-Smtp-Source: AGs4zMYGKLh7Hz5LAyR6KlqKn64VlTpFCmDZBb8Wv2Rz2E1PMfnrN9ee24U7DYqq8ssxIxbm+Bgu X-Received: by 10.159.196.151 with SMTP id c23mr2516233plo.276.1510855418100; Thu, 16 Nov 2017 10:03:38 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510855418; cv=none; d=google.com; s=arc-20160816; b=IUQHDFbRv2HljztI0eCmo3VKCFfHBYfxTBMdhIwWZ4GBviKaxthGUL4DOFbMGEjb+o 8QHm5uRk8zYl8TIHmrkfnpJXDtok4B2vK+XvqQvBMh/mgwoAkCiNa9sAMucSHkliM46U RABssgjLKVfthZbd5iZ0vbsCP2WC93rHpqZ3+0/Z8HgHwCVYOgjNh36HHlSxxaVHl7n/ L1UyE7XDBT9btmhAIfQdup1AjjnJzBt0mzqsR9Qvwsd3/paloGOYuJpGuIakKctNOVOC wnQiYyOS6xkAbCl/ipqXesxUP85Urogksxzie3mE078zGcJMmRWaImHf1kiCjMrEcOp+ dN+A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:to:from :dkim-signature:arc-authentication-results; bh=sgtN/joTKcv1fMBRbAizl829h7A9/WP/ec8Xz00vw5k=; b=OTkY2jMe9GfWzqjAKE/zzZYO/3TPMt6Kpux2We/xisWEbNOnp7cQhouMIFl1T0rj/M MZ8UI7TC+8Tbn/Tsx1+RCHgaMa6bd8wvGc9ueaeRKYin8iECNKMyNWVGJsBCWC/u3hp6 bkXyXFu/p18hUBUVGTNqgOFTb/MccItV+TF1oggxAdhWSX/ZVnxldIM4F2QWS8GSblzK q14VvqpjpMfLTurbwalwAgRqMEVb9hNEKccQ3h1I0H1YcFe7wLLZRY26lzLvvbJGhee9 9OtNoTPM00H7UqdxufobxcUH5ZdTErX7raKck5kfdiIj9NxUiPDwkBQGBmps0EoVTGyt i1Og== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@android.com header.s=20161025 header.b=BI+XZXKc; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=android.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id a14si1249990plt.567.2017.11.16.10.03.25; Thu, 16 Nov 2017 10:03:38 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@android.com header.s=20161025 header.b=BI+XZXKc; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=android.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936472AbdKPR5T (ORCPT + 92 others); Thu, 16 Nov 2017 12:57:19 -0500 Received: from mail-it0-f65.google.com ([209.85.214.65]:41616 "EHLO mail-it0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965681AbdKPR5E (ORCPT ); Thu, 16 Nov 2017 12:57:04 -0500 Received: by mail-it0-f65.google.com with SMTP id x28so1010378ita.0 for ; Thu, 16 Nov 2017 09:57:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=android.com; s=20161025; h=from:to:subject:date:message-id; bh=sgtN/joTKcv1fMBRbAizl829h7A9/WP/ec8Xz00vw5k=; b=BI+XZXKcwj2zL8UEqr+t3ws1VAe1hgappOH2j1OGYE/Wjtt65laUpChn1EYIi0wA9K 9vazbq18vhufHciZZZHEOUL4q7CQ8uUMCQ4rnGxp5OoDREQCgrYcI8zNa38fSifkISki q198U3vr8+yUrZ5byuTp3sJpvsQPJbRIH2EzuVF16Kj2ulFVfsZRGRmLDtulFyJ5slzy n+WXmiNl1HENEdK6zYhVzUQviCSJyxBWJI9uQ0TvVWN/FDU2k5sOQpV2UlRXoIa2OpBZ pZFwCDWgpzI7+zybeJkZ4p293ixHpSs23BHOeFvkYMMgQ9EmLmy5KnQH2bwYyOIpKQFn anCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=sgtN/joTKcv1fMBRbAizl829h7A9/WP/ec8Xz00vw5k=; b=qZsYzr4G/vCLicmgE+w6HUjAaEQqy/CngYH5yCVVFP+uuopaoJv+UF1Q/lryhnZyTF xe8CDpp8tmO9TwxQeSkANZaH79Jp/Bi1WvSH1CLxdDAFGcoUDSZ9f9Ww2fjj4KjF+5Lj /CJRB+a+vHRAQFTgiMDpDyQAkUxecZSro9VPksynp0e3ucZF5h/OTvtR+rRYDhv7rIPY HK09U7nh+o+0xwfxuww4f93H3HV3pdcCjTMB74iZrNr0wKYLEii9uMUp15RrwFhAcDvi Pe7zPl+cBmURDpig2DVmlxyjI83hLYbGBGWTIFHiJmuBJKXZ+/P5VGHPylGkJbEh8fhM Souw== X-Gm-Message-State: AJaThX63ERpbWsZUbZma5Lp9VobWVk9GmVNbrUeKCOk/Na20WZXDC2Rl 9ih+aC2/mOnS9jzPlrr19zZaURMf X-Received: by 10.36.172.82 with SMTP id m18mr3229421iti.39.1510855023603; Thu, 16 Nov 2017 09:57:03 -0800 (PST) Received: from ava-linux.mtv.corp.google.com ([172.22.121.103]) by smtp.googlemail.com with ESMTPSA id 194sm1166270ito.20.2017.11.16.09.57.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 16 Nov 2017 09:57:03 -0800 (PST) From: Todd Kjos X-Google-Original-From: Todd Kjos To: tkjos@google.com, gregkh@linuxfoundation.org, arve@android.com, devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org, maco@google.com Subject: [PATCH v2] binder: fix proc->files use-after-free Date: Thu, 16 Nov 2017 09:56:50 -0800 Message-Id: <20171116175650.40362-1-tkjos@google.com> X-Mailer: git-send-email 2.15.0.448.gf294e3d99a-goog Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 always use get_files_struct() to obtain struct_files so that the refcount on the files_struct is used to prevent a premature free. proc->files is removed since we get it every time. Signed-off-by: Todd Kjos --- drivers/android/binder.c | 63 +++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index fddf76ef5bd6..ea07b35fb533 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -458,9 +458,8 @@ struct binder_ref { }; enum binder_deferred_state { - BINDER_DEFERRED_PUT_FILES = 0x01, - BINDER_DEFERRED_FLUSH = 0x02, - BINDER_DEFERRED_RELEASE = 0x04, + BINDER_DEFERRED_FLUSH = 0x01, + BINDER_DEFERRED_RELEASE = 0x02, }; /** @@ -481,8 +480,6 @@ enum binder_deferred_state { * (invariant after initialized) * @tsk task_struct for group_leader of process * (invariant after initialized) - * @files files_struct for process - * (invariant after initialized) * @deferred_work_node: element for binder_deferred_list * (protected by binder_deferred_lock) * @deferred_work: bitmap of deferred work to perform @@ -529,7 +526,6 @@ struct binder_proc { struct list_head waiting_threads; int pid; struct task_struct *tsk; - struct files_struct *files; struct hlist_node deferred_work_node; int deferred_work; bool is_dead; @@ -875,22 +871,34 @@ static void binder_free_thread(struct binder_thread *thread); static void binder_free_proc(struct binder_proc *proc); static void binder_inc_node_tmpref_ilocked(struct binder_node *node); +static struct files_struct *binder_get_files_struct(struct binder_proc *proc) +{ + return get_files_struct(proc->tsk); +} + static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) { - struct files_struct *files = proc->files; + struct files_struct *files; unsigned long rlim_cur; unsigned long irqs; + int ret; + files = binder_get_files_struct(proc); if (files == NULL) return -ESRCH; - if (!lock_task_sighand(proc->tsk, &irqs)) - return -EMFILE; + if (!lock_task_sighand(proc->tsk, &irqs)) { + ret = -EMFILE; + goto err; + } rlim_cur = task_rlimit(proc->tsk, RLIMIT_NOFILE); unlock_task_sighand(proc->tsk, &irqs); - return __alloc_fd(files, 0, rlim_cur, flags); + ret = __alloc_fd(files, 0, rlim_cur, flags); +err: + put_files_struct(files); + return ret; } /* @@ -899,8 +907,12 @@ static int task_get_unused_fd_flags(struct binder_proc *proc, int flags) static void task_fd_install( struct binder_proc *proc, unsigned int fd, struct file *file) { - if (proc->files) - __fd_install(proc->files, fd, file); + struct files_struct *files = binder_get_files_struct(proc); + + if (files) { + __fd_install(files, fd, file); + put_files_struct(files); + } } /* @@ -908,18 +920,20 @@ static void task_fd_install( */ static long task_close_fd(struct binder_proc *proc, unsigned int fd) { + struct files_struct *files = binder_get_files_struct(proc); int retval; - if (proc->files == NULL) + if (files == NULL) return -ESRCH; - retval = __close_fd(proc->files, fd); + retval = __close_fd(files, fd); /* can't restart close syscall because file table entry was cleared */ if (unlikely(retval == -ERESTARTSYS || retval == -ERESTARTNOINTR || retval == -ERESTARTNOHAND || retval == -ERESTART_RESTARTBLOCK)) retval = -EINTR; + put_files_struct(files); return retval; } @@ -4561,7 +4575,6 @@ static void binder_vma_close(struct vm_area_struct *vma) (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, (unsigned long)pgprot_val(vma->vm_page_prot)); binder_alloc_vma_close(&proc->alloc); - binder_defer_work(proc, BINDER_DEFERRED_PUT_FILES); } static int binder_vm_fault(struct vm_fault *vmf) @@ -4603,10 +4616,8 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma) vma->vm_private_data = proc; ret = binder_alloc_mmap_handler(&proc->alloc, vma); - if (ret) - return ret; - proc->files = get_files_struct(current); - return 0; + + return ret; err_bad_arg: pr_err("binder_mmap: %d %lx-%lx %s failed %d\n", @@ -4778,8 +4789,6 @@ static void binder_deferred_release(struct binder_proc *proc) struct rb_node *n; int threads, nodes, incoming_refs, outgoing_refs, active_transactions; - BUG_ON(proc->files); - mutex_lock(&binder_procs_lock); hlist_del(&proc->proc_node); mutex_unlock(&binder_procs_lock); @@ -4861,8 +4870,6 @@ static void binder_deferred_release(struct binder_proc *proc) static void binder_deferred_func(struct work_struct *work) { struct binder_proc *proc; - struct files_struct *files; - int defer; do { @@ -4879,21 +4886,11 @@ static void binder_deferred_func(struct work_struct *work) } mutex_unlock(&binder_deferred_lock); - files = NULL; - if (defer & BINDER_DEFERRED_PUT_FILES) { - files = proc->files; - if (files) - proc->files = NULL; - } - if (defer & BINDER_DEFERRED_FLUSH) binder_deferred_flush(proc); if (defer & BINDER_DEFERRED_RELEASE) binder_deferred_release(proc); /* frees proc */ - - if (files) - put_files_struct(files); } while (proc); } static DECLARE_WORK(binder_deferred_work, binder_deferred_func); -- 2.15.0.448.gf294e3d99a-goog From 1584592444745619308@xxx Mon Nov 20 13:38:36 +0000 2017 X-GM-THRID: 1584592444745619308 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread