Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp3433587ybt; Tue, 23 Jun 2020 02:06:21 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwvqdoTUBWojstEURV6r1AnZEH+Sqikgk/4bz0vv9s98AlsMTMo7wwwEP/3diSd+w6pgLlv X-Received: by 2002:a17:906:b817:: with SMTP id dv23mr19210532ejb.185.1592903181499; Tue, 23 Jun 2020 02:06:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1592903181; cv=none; d=google.com; s=arc-20160816; b=a+HH8stp7aGVjqlEHBl/HLKR8T+P+HLuEY5pv8iY0m4WpTX11cgBI3epr0B39ZBbw4 fKaZTuLX6VaHCAMHOmJ6vS0JNp6qAFUgo1HHgoein7uWptKz8LtMaRQGfYzDT4KG9V9m Leb6yIQfkCOGbrmTWDvMVx/b33j+A3OLkkBcFlbpyokKxsaFfZZyJNx1tBy5yFdXXGEn 164mPz3yB8qiDhdX3HJPe8eFBI2Vns9F2949CWbi7Axbl4bhhTaj8vWeWOHUaR4zh/0n Sg72WN04emGm1A2FW/DmXAbF2PKTv/0iyggFcTxvpR+lMP/Hakkcc+9r7usnHxfoAI6X rcTQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date; bh=kvRkwOSclRBP4Vk/tPleK9YSeU2qMLK9PpxnrREFl+w=; b=XO+ZIx0erTDVtETsPYifYHaoBOrA5smxqVLqSt3DvpUA/KDOWjIxAtkByXc68GNb+m Yd1l8jxVNik0htOr1RGW271tsY4eOXwWxA6wZKGIdgCj3y1TKCq+dKSHQ20HSVMCASM5 +RkcbjjGxldcufW4lfvqwxZP8SXFrJMUaHIkpq1M4KihJ14FNO0SjuEBom7JGtO373xY x/ev41/T+S8MLDhMe+tAgICn8qZbmKUuiR2Q7e9f7djsKvspMVG5a9nmIIMnl6jDPSh4 4a81pS1WCh+SnumjZfYsJxP/i6sq97w347O9yJQT+gH4Ld5NS9z/PklSEhPp62hqNoYD HpFw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id n15si11127476edt.88.2020.06.23.02.05.58; Tue, 23 Jun 2020 02:06:21 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731887AbgFWJEL (ORCPT + 99 others); Tue, 23 Jun 2020 05:04:11 -0400 Received: from youngberry.canonical.com ([91.189.89.112]:42205 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731786AbgFWJEL (ORCPT ); Tue, 23 Jun 2020 05:04:11 -0400 Received: from ip5f5af08c.dynamic.kabel-deutschland.de ([95.90.240.140] helo=wittgenstein) by youngberry.canonical.com with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1jneqb-0004jq-2s; Tue, 23 Jun 2020 09:04:05 +0000 Date: Tue, 23 Jun 2020 11:04:04 +0200 From: Christian Brauner To: Dan Carpenter Cc: Todd Kjos , gregkh@linuxfoundation.org, christian@brauner.io, arve@android.com, devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org, maco@google.com, joel@joelfernandes.org, kernel-team@android.com Subject: Re: [PATCH] binder: fix null deref of proc->context Message-ID: <20200623090404.xwuhdec6c7p4lnd2@wittgenstein> References: <20200622200715.114382-1-tkjos@google.com> <20200623085021.GG4151@kadam> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20200623085021.GG4151@kadam> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Jun 23, 2020 at 11:50:21AM +0300, Dan Carpenter wrote: > On Mon, Jun 22, 2020 at 01:07:15PM -0700, Todd Kjos wrote: > > The binder driver makes the assumption proc->context pointer is invariant after > > initialization (as documented in the kerneldoc header for struct proc). > > However, in commit f0fe2c0f050d ("binder: prevent UAF for binderfs devices II") > > proc->context is set to NULL during binder_deferred_release(). > > > > Another proc was in the middle of setting up a transaction to the dying > > process and crashed on a NULL pointer deref on "context" which is a local > > set to &proc->context: > > > > new_ref->data.desc = (node == context->binder_context_mgr_node) ? 0 : 1; > > > > Here's the stack: > > > > [ 5237.855435] Call trace: > > [ 5237.855441] binder_get_ref_for_node_olocked+0x100/0x2ec > > [ 5237.855446] binder_inc_ref_for_node+0x140/0x280 > > [ 5237.855451] binder_translate_binder+0x1d0/0x388 > > [ 5237.855456] binder_transaction+0x2228/0x3730 > > [ 5237.855461] binder_thread_write+0x640/0x25bc > > [ 5237.855466] binder_ioctl_write_read+0xb0/0x464 > > [ 5237.855471] binder_ioctl+0x30c/0x96c > > [ 5237.855477] do_vfs_ioctl+0x3e0/0x700 > > [ 5237.855482] __arm64_sys_ioctl+0x78/0xa4 > > [ 5237.855488] el0_svc_common+0xb4/0x194 > > [ 5237.855493] el0_svc_handler+0x74/0x98 > > [ 5237.855497] el0_svc+0x8/0xc > > > > The fix is to move the kfree of the binder_device to binder_free_proc() > > so the binder_device is freed when we know there are no references > > remaining on the binder_proc. > > > > Fixes: f0fe2c0f050d ("binder: prevent UAF for binderfs devices II") > > Signed-off-by: Todd Kjos > > --- > > drivers/android/binder.c | 14 +++++++------- > > 1 file changed, 7 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/android/binder.c b/drivers/android/binder.c > > index e47c8a4c83db..f50c5f182bb5 100644 > > --- a/drivers/android/binder.c > > +++ b/drivers/android/binder.c > > @@ -4686,8 +4686,15 @@ static struct binder_thread *binder_get_thread(struct binder_proc *proc) > > > > static void binder_free_proc(struct binder_proc *proc) > > { > > + struct binder_device *device; > > + > > BUG_ON(!list_empty(&proc->todo)); > > BUG_ON(!list_empty(&proc->delivered_death)); > > + device = container_of(proc->context, struct binder_device, context); > > + if (refcount_dec_and_test(&device->ref)) { > > + kfree(proc->context->name); > > + kfree(device); > > + } > > Where is device allocated? > > It looks to me like they are allocated in init_binder_device(). So why > are calling misc_deregister? And it looks like the kfree(proc->context->name); > is wrong as well because that's from the > "device_names = kstrdup(binder_devices_param, GFP_KERNEL);" in > binder_init(). This whole codepath is only hit for binderfs binder devices which are allocated in binderfs.c. Legacy binder devices allocated through the misc device layer always have a reference count > 0. When they are opened there refcount is inced by one and when they are put is deced by 1 since their refcount starts from 1 they're always guaranteed to be at 1. For binderfs binder devices they start with a refcount of 1 as well and it is incremented when they are opened too but there's another dec on their refcount when the binderfs instance is shutting down or when they are deleted through inode eviction. If someone is still keeping the binderfs device alive through proc-> then the final put can't happen during inode eviction but must happen in binder_free_proc() instead. > > To be honest, I'm a bit confused why we're not doing this in module_exit(). Because there's no module_exit() for binder and with binderfs. Their either "y" or "n". If you want to do this work then this can become a little messy since you'd need to mess with userspace when you suddenly invalidate all their references through a forced module unload. Christian