Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp78774imu; Fri, 14 Dec 2018 14:51:23 -0800 (PST) X-Google-Smtp-Source: AFSGD/W3/h67xiyQP8CPBtcvLcp/Vr41jK5/Mkg9nNYgCnCxJyiJpi30RSnuBo8fMzBwV+DBqelo X-Received: by 2002:a62:5950:: with SMTP id n77mr4512642pfb.128.1544827883082; Fri, 14 Dec 2018 14:51:23 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544827883; cv=none; d=google.com; s=arc-20160816; b=B7wXwZEpKyOzGSRhaVmVxOYQZbzElpFXJ0FqkC5qrCBwTgMw9KGkK1pG1+PnK3mJbS a0GOof4L0T5OPQ4bv4FnrgXT3ts8Vd+P/gYMoQi5jQ9dV7zV2dwotWG2NUCUbe2tA5JE 6+5ETpnBBPIpc5wf8p0XgD7zzL1gulbWI6b5MohZKgYqMmywfzohnRlQbM415t3vKhmt 2GOvy+H8uzvcFzEaiUaFlPCX3km8hCsWtQisQ0O9NNc9mM16dQbdf4fOVDnzWJPrfO3G R6qpt919sCJWHfp1FwQTk1QkesEBLTPjTr21+baHEqsK+lS8k3PIih8/kCIt+v0GRPZr UuYA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:message-id:subject:cc :to:from:date; bh=h3XJxApn+eYq9To0E/Vs4SuJYHDg0N96ewlgQkgOjtU=; b=TfR+Lgi0hLwkCrP3wrVRCP0bGkRvnIGlPaUspX4wRrkZHnM/Xu3hHT4fxqZMIf7YyU lYic+IdcQK2j4P/33TrQbY5mHDwPZs5Tp4GhQgTgyOEt5Po+BFtG+TcAmXKQe1xKaLQG CtqVWcLhYkp4aO1MAxJ2HQDz0yQnQPoO462z2pve6UEnwi9MjcXHTv0DjKLY1oXSKZE1 ujeRD71wNZe9D5SwIoKLWHOaLA7C9iAaWOO3WrBI1a+PrgInMPfU68mn+LXjVaxwHJ6I lVESLnIxyj9IT3K1A62fwBXmabU1x1KNQRPnBvp8gMouy6cVv3NNiKPiCdrUxdWicCM4 w62A== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l7si5115779pfb.31.2018.12.14.14.51.08; Fri, 14 Dec 2018 14:51:23 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730833AbeLNWuM (ORCPT + 99 others); Fri, 14 Dec 2018 17:50:12 -0500 Received: from zeniv.linux.org.uk ([195.92.253.2]:42064 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730255AbeLNWuM (ORCPT ); Fri, 14 Dec 2018 17:50:12 -0500 Received: from viro by ZenIV.linux.org.uk with local (Exim 4.91 #2 (Red Hat Linux)) id 1gXwHU-0005Lk-Sh; Fri, 14 Dec 2018 22:50:04 +0000 Date: Fri, 14 Dec 2018 22:50:04 +0000 From: Al Viro To: Todd Kjos Cc: tkjos@google.com, gregkh@linuxfoundation.org, 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 v2] binder: fix use-after-free due to ksys_close() during fdget() Message-ID: <20181214225004.GP2217@ZenIV.linux.org.uk> References: <20181214203815.217014-1-tkjos@google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20181214203815.217014-1-tkjos@google.com> User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Dec 14, 2018 at 12:38:15PM -0800, Todd Kjos wrote: > 44d8047f1d8 ("binder: use standard functions to allocate fds") > exposed a pre-existing issue in the binder driver. > > fdget() is used in ksys_ioctl() as a performance optimization. > One of the rules associated with fdget() is that ksys_close() must > not be called between the fdget() and the fdput(). There is a case > where this requirement is not met in the binder driver which results > in the reference count dropping to 0 when the device is still in > use. This can result in use-after-free or other issues. > > If userpace has passed a file-descriptor for the binder driver using > a BINDER_TYPE_FDA object, then kys_close() is called on it when > handling a binder_ioctl(BC_FREE_BUFFER) command. This violates > the assumptions for using fdget(). > > The problem is fixed by deferring the fd close using task_work_add() > so ksys_close() is called after returning from binder_ioctl(). > > Fixes: 44d8047f1d87a ("binder: use standard functions to allocate fds") > Suggested-by: Al Viro > Signed-off-by: Todd Kjos Umm... IMO you are making it more brittle than needed. Descriptors (as in, integers serving as indices in file descriptor tables) are sensitive to a lot of things and generally you don't want to pass them around, at least not without a lot more context than you do. References to struct file are much more robust. And frankly, ksys_close() is best not touched - what you want is basically a version of __close_fd() that would grab a reference to struct file before filp_close() and passed that reference to you. Then your delayed ksys_close() would turn into (equally delayed) fput(). Something like int rip_fd(int fd, struct file **res) { struct files_struct *files = current->files; struct file *file; struct fdtable *fdt; spin_lock(&files->file_lock); fdt = files_fdtable(files); if (fd >= fdt->max_fds) goto out_unlock; file = fdt->fd[fd]; if (!file) goto out_unlock; rcu_assign_pointer(fdt->fd[fd], NULL); __put_unused_fd(files, fd); spin_unlock(&files->file_lock); get_file(file); *res = file; return filp_close(file, files); out_unlock: spin_unlock(&files->file_lock); *res = NULL; return -ENOENT; } used as error = rip_fd(fd, &file); /* we are committed to arranging fput(file) now, error or not */ Frankly, the main objection to exporting that would be to avoid encouraging the "we'll just pass the number around" kind of braindamage. In case of binder you are locked into that braindamage by an atrocious userland API design and warnings along the lines of "use that and you *will* have to explain yourself; yes, we will be watching" might suffice to prevent additional uses...