Received: by 2002:a05:6a10:2785:0:0:0:0 with SMTP id ia5csp2814627pxb; Mon, 11 Jan 2021 22:02:54 -0800 (PST) X-Google-Smtp-Source: ABdhPJxZZMiARWiQNY50v70zF5DHuwBo/bM6Pu6KR+UCeKz3IKYhDZqxQNWs7gNBNPC2fNe17Ndb X-Received: by 2002:a05:6402:c1c:: with SMTP id co28mr2069604edb.287.1610431374663; Mon, 11 Jan 2021 22:02:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1610431374; cv=none; d=google.com; s=arc-20160816; b=A7ufS9D9f6lgeEXEdcyMyXCtyHU4stXwg+oyBEcjIpuoXW6gHYZsZaP6mNResFCaLS IMQcUNdza4pmd9JzW3rt6I8rSepLoWnyEwqMQdJNXRFjrOpdeJx5omhcDOO3BYl9Dtol 9BsI9sxD41LQR27sRy7MFqsHUJLrHP9VHUpsmYgbLejmKxpJkYC9+H0gbe5BUX140IxO FrpGkm5XqBvaQsGFBRxS9RFRaXKy59kXy60ax5ZIVHMfZhBraedppS/bo4OrKf6qSzqW YvqSOa8IQgxBNYIgwcZECxV4uPqYoqxo7fmw3zHoU35EXT7A1lh/Sl9bmmOoT5h8wR3N HcPw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=oXRZqTC7eV5UH65bAybrE+aqzIjr0ANpEOMm3Um76Xw=; b=CXFNPNk/3Jqtrf+42nf9UVJoL6cP8qs/maGN/bBKKjc15nIjZeVQOqT+lr5MNGudOW RvQVO5+HnZHS73GZ2UUQ5sZsUfwl2XkBiZSFkFLdhvdoRNFZXRs8+n4RUUEbl4EuTHpI 8cYg/FPKxtoqcl8xIWWzsTVHaKPoEgaNz8M6GCm5+R2/eIc03a+ZMw+lsRJloymGaiyd Zvqt0Wfdit52vVqF0xWXj7qCVZoaSTEKj9Mot4Jf+4nuwTxns5UInL/xgehoxQvRilvv My+mVjaMH3NBV1TCqyYvuSmlKMwJjMKOKHcG6tR3bX+wHqthTRphDjVh+iY+vF+fb739 EAHQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=yQq77HVr; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id s13si871028eds.57.2021.01.11.22.02.30; Mon, 11 Jan 2021 22:02:54 -0800 (PST) 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; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=yQq77HVr; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731714AbhAKNiz (ORCPT + 99 others); Mon, 11 Jan 2021 08:38:55 -0500 Received: from mail.kernel.org ([198.145.29.99]:58908 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731552AbhAKNM4 (ORCPT ); Mon, 11 Jan 2021 08:12:56 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 063B6229CA; Mon, 11 Jan 2021 13:12:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1610370760; bh=Z9cMea0DCwPV9ekGawv44LwH2gcwZ+Yd/UNJSXtQM6w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=yQq77HVr9D8IqYBuJQ0oYdqANUGMEuAcUoGUTmn3z8j/XVvHcwjdKRWw8bLNjGxPJ mlE9F8+iMRWNkM/SNQmJ8RfEM7R1Zr7YFnYM+VLzLmS9pbT53Y4WbodUnQXAZr9HL7 YGs5XccLr6GNCOy02yl2SU/WPl4HfeGBdvn0CH0Q= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, =?UTF-8?q?Christian=20K=C3=B6nig?= , Charan Teja Reddy , Sumit Semwal , Thomas Zimmermann Subject: [PATCH 5.4 85/92] dmabuf: fix use-after-free of dmabufs file->f_inode Date: Mon, 11 Jan 2021 14:02:29 +0100 Message-Id: <20210111130043.253495312@linuxfoundation.org> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210111130039.165470698@linuxfoundation.org> References: <20210111130039.165470698@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Charan Teja Reddy commit 05cd84691eafcd7959a1e120d5e72c0dd98c5d91 upstream. It is observed 'use-after-free' on the dmabuf's file->f_inode with the race between closing the dmabuf file and reading the dmabuf's debug info. Consider the below scenario where P1 is closing the dma_buf file and P2 is reading the dma_buf's debug info in the system: P1 P2 dma_buf_debug_show() dma_buf_put() __fput() file->f_op->release() dput() .... dentry_unlink_inode() iput(dentry->d_inode) (where the inode is freed) mutex_lock(&db_list.lock) read 'dma_buf->file->f_inode' (the same inode is freed by P1) mutex_unlock(&db_list.lock) dentry->d_op->d_release()--> dma_buf_release() ..... mutex_lock(&db_list.lock) removes the dmabuf from the list mutex_unlock(&db_list.lock) In the above scenario, when dma_buf_put() is called on a dma_buf, it first frees the dma_buf's file->f_inode(=dentry->d_inode) and then removes this dma_buf from the system db_list. In between P2 traversing the db_list tries to access this dma_buf's file->f_inode that was freed by P1 which is a use-after-free case. Since, __fput() calls f_op->release first and then later calls the d_op->d_release, move the dma_buf's db_list removal from d_release() to f_op->release(). This ensures that dma_buf's file->f_inode is not accessed after it is released. Cc: # 5.4.x- Fixes: 4ab59c3c638c ("dma-buf: Move dma_buf_release() from fops to dentry_ops") Acked-by: Christian König Signed-off-by: Charan Teja Reddy Signed-off-by: Sumit Semwal Signed-off-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/1609857399-31549-1-git-send-email-charante@codeaurora.org Signed-off-by: Greg Kroah-Hartman --- drivers/dma-buf/dma-buf.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -76,10 +76,6 @@ static void dma_buf_release(struct dentr dmabuf->ops->release(dmabuf); - mutex_lock(&db_list.lock); - list_del(&dmabuf->list_node); - mutex_unlock(&db_list.lock); - if (dmabuf->resv == (struct dma_resv *)&dmabuf[1]) dma_resv_fini(dmabuf->resv); @@ -88,6 +84,22 @@ static void dma_buf_release(struct dentr kfree(dmabuf); } +static int dma_buf_file_release(struct inode *inode, struct file *file) +{ + struct dma_buf *dmabuf; + + if (!is_dma_buf_file(file)) + return -EINVAL; + + dmabuf = file->private_data; + + mutex_lock(&db_list.lock); + list_del(&dmabuf->list_node); + mutex_unlock(&db_list.lock); + + return 0; +} + static const struct dentry_operations dma_buf_dentry_ops = { .d_dname = dmabuffs_dname, .d_release = dma_buf_release, @@ -413,6 +425,7 @@ static void dma_buf_show_fdinfo(struct s } static const struct file_operations dma_buf_fops = { + .release = dma_buf_file_release, .mmap = dma_buf_mmap_internal, .llseek = dma_buf_llseek, .poll = dma_buf_poll,