Received: by 10.223.164.202 with SMTP id h10csp89964wrb; Tue, 14 Nov 2017 18:14:12 -0800 (PST) X-Google-Smtp-Source: AGs4zMZTvcFEeU6ju2RzvnVc1d/8uy4NBBlrTlufN/Ceg1VIZbglpsbniTubBDPwwPfYmSJLUKsB X-Received: by 10.101.72.132 with SMTP id n4mr13998161pgs.245.1510712052166; Tue, 14 Nov 2017 18:14:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510712052; cv=none; d=google.com; s=arc-20160816; b=vZHgbEtmR7jIy97zYjr/NIyIiDtQs/srBycaHOunw6aVXJ5QsiRs4YdSi/FpqSVCUu HgOi3I6qtu6JgV9FpRKJ0cEIsfpC034jdtm0cckmZXU0eBtwZ9hMRdzA/Sw45wT6OI5Y bcUjI2kQLfCB3iI/9sMd/s4woezTSLASTggidQ42FHxZccBAqDccmmSFzRndkKi2giye N0rgfFIhBlYaD3/DRKvnJ+/TxG4/UOLUUDyudnhIB/V8rMOmItcxgmrStPvkaDDiDAzr ajh5Jy+tcTVNxWm0XfzqywP4wJOvdNllzi+cPXVKWmedyCyue/jquhNiLCr6A3ftDKGa L0mQ== 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=ZJzzE8F1e1w7+jkQcUQGSufw9zWiEuQ0/d90DUVUA/4=; b=JNf1bFfNWC0GwmPyrt0gewymRhvRaceE5zUEi91x6p4fyBepnUijuHcMtUVrVhXFj1 fYCaB3fqx32TeHYH9EAlgmCU/OfuKy6C3iwBI1TjbrELCU7bahhm44f1TXQgoKiYlk9d HDtbCmKMT3EiNTxXtN8iVOlAMVWCFl+Lr2Xax+2bbTP4tXndqfLA0QoakibSjatXwfEJ ujZ7ha1dabBjsHrO0RI3EDZb7APGDpXxjF7Xi63yPZ7jLsna3H3TX80aaXlC7xTeUFf9 eq0khU/AqF7m/8tmsLArfEqZ3ufjOwnzWpjwnxHkSnY936zsG3hfeag0TDjxCw1tEBwE 21dg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@android.com header.s=20161025 header.b=Pxlg89TG; 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 e4si5078654plb.493.2017.11.14.18.14.00; Tue, 14 Nov 2017 18:14:12 -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=Pxlg89TG; 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 S1756546AbdKOBGp (ORCPT + 87 others); Tue, 14 Nov 2017 20:06:45 -0500 Received: from mail-it0-f68.google.com ([209.85.214.68]:39022 "EHLO mail-it0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756426AbdKOBGj (ORCPT ); Tue, 14 Nov 2017 20:06:39 -0500 Received: by mail-it0-f68.google.com with SMTP id y15so15952671ita.4 for ; Tue, 14 Nov 2017 17:06:38 -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=ZJzzE8F1e1w7+jkQcUQGSufw9zWiEuQ0/d90DUVUA/4=; b=Pxlg89TG3/kt1Zsk/Jt8QIxUugAAR0fbuW/nXAyMcrX4OoYa8y0xqNaDpSUQGcSL2f RSFBM57eE1ouWqNsj3qPzEZFaWvRxqhYWqVw/f6dBXAQF1Ok1wILXo3W5AnGNehCKZVK BxAIzshOAmNXGy/jvHSPSIVCc1rGwVRqA8Me/4B91rlYWQTksr84gbk3mERehp+HLnS1 T4crjIGmw5ZnC87JnZ7lknUasyvS85XnXQv+oL4bSKrBbQyY1tRNh2r/RFyibwWlNr05 smD1a0ra+NM/SBweY+sOIYrdAVX8KfxsFYn4Sa29JPTA0siWdQoAFYgLmv1HgL6eWDxn q6rQ== 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=ZJzzE8F1e1w7+jkQcUQGSufw9zWiEuQ0/d90DUVUA/4=; b=XgeJJcOW9rCV61jdZBMzFC708CUava0BZXJT7Rdm2gXntVmplYOaMiOzQiteDagjdt ZGjbxiZfNixy4wWqTf4vKcf71VcpG6/Eb4MIGPXAbtO7hlQfMMA8GQjsJ22Y6I/L1/GY SK2oZ/X1ewkCkcCNspEYXK4ha24Sl38vvyHpUJ8srSEksJKkurnbkMoucXq40QuiS08/ X8KH5dJtPx9E1b7u7NcbBvDDyF1+Pkz75pycecX7y/Jp9kYN2AizXbWUaiGjvr3Z6WER S/wZZlnYZR8PBYq6M7QMqiHuhlVHU38mFctmrda1pOEQBZrYu7QNlcgrtzAm8ZbWwchn RBSQ== X-Gm-Message-State: AJaThX75OJVWCuixyPKvk7qdxnSGeWkIWdIdrNVgCfOeZVSRH+vor48d VB8FGyiOTBZqFcQsUBg5aqU4mg== X-Received: by 10.36.177.68 with SMTP id c4mr17606816itj.149.1510707997957; Tue, 14 Nov 2017 17:06:37 -0800 (PST) Received: from ava-linux.mtv.corp.google.com ([172.22.121.103]) by smtp.googlemail.com with ESMTPSA id b66sm6023795itb.17.2017.11.14.17.06.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 14 Nov 2017 17:06:37 -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] binder: fix proc->files use-after-free Date: Tue, 14 Nov 2017 17:06:29 -0800 Message-Id: <20171115010629.32859-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..794e58c14b15 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); +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 1584268192426967086@xxx Thu Nov 16 23:44:45 +0000 2017 X-GM-THRID: 1584246036716200762 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread