From patchwork Tue Jul 7 15:17:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg KH X-Patchwork-Id: 235018 Delivered-To: patch@linaro.org Received: by 2002:a54:2c11:0:0:0:0:0 with SMTP id g17csp306885ecp; Tue, 7 Jul 2020 08:26:54 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyQ0W+SrbW4j0QejkPYjsm0Y29FLF4bwu2dkLxyldhs4fOxnDj7N+9BgCgYd2Gs8LckYhoa X-Received: by 2002:a17:906:a459:: with SMTP id cb25mr47501988ejb.234.1594135614618; Tue, 07 Jul 2020 08:26:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594135614; cv=none; d=google.com; s=arc-20160816; b=o6W4plsQqsL+qcEIXONTUmp+IO0+c6A2IU395eHErI1M/q1cEz97IpviZHFO5Pw8nB oOasvVHLMhKI3HDKwGHlsZUrrfhFseVBVhy6iXGNJjAR8XEfnZlrydKIF50P40E0nGsm ly6S3iYRQOPDIN0m1USG81GShJ1qlSdo5ERmc4KRz8PpE3mr9HGgn8W+eDC2PBucwug3 0vmO50h/F/W0qRBFWBxTkJEFu0EdNH4iXyLPqDxudWrBKxq8CGHX+3MZ+4irEn15PPZa 1MqNXJo0e3qU4Fpb5VWCW7a/VVOKvcvtR3m2JcaYw91D5LaE5agYWkHRyLPVzbsbo163 0q1g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=zPhKdBGQ1NOZFJWDThQIj+3U/w6NeCsm+T2krskVREk=; b=hl86zANPk0KW4qXUrIe+meLjrAl8mM+QTquKVSRA8QO4mxSVrHFTtNhql04VPH9uVp vQXHKJrsdWVf7DxG276KWOlM2l28Zz9M7aclKQEWbUV5DGdkajzteOOKgW+IzFUjbWXi GjlHb+5zCKHtokL26gHdDCyMf7Aec326Cuwkw461Ejg8UBW4w0QuR0IAQ+rt8plx0N0T TrJ0ugsJ3YGD0lWJVT90OkrcB1SLJavAgFtzk57+vm3rlPX6F/rYFJaw5TALoIH4+RUs whKw78jxF3/s3Sc47Eb9n78mbAgGNuMEjkW+gbI2QRzsWbOTZOxmRuqVTELYLzvwsq5L DUog== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=vjXTO3dB; spf=pass (google.com: domain of stable-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=stable-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 l6si14592321ejx.493.2020.07.07.08.26.54; Tue, 07 Jul 2020 08:26:54 -0700 (PDT) Received-SPF: pass (google.com: domain of stable-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=@kernel.org header.s=default header.b=vjXTO3dB; spf=pass (google.com: domain of stable-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730314AbgGGP0x (ORCPT + 15 others); Tue, 7 Jul 2020 11:26:53 -0400 Received: from mail.kernel.org ([198.145.29.99]:41066 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730302AbgGGP0q (ORCPT ); Tue, 7 Jul 2020 11:26:46 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C21972078D; Tue, 7 Jul 2020 15:26:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1594135605; bh=tsP8O2XrM6avr/0AZZLaqustfwT7bO1HRrcl6qYXHwE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vjXTO3dBsG7ESoofPKwdivqlE+VelHY13tZ7oo8jJQjBieft0vOflkqk5vUkEtcx6 s2dpbox14RrrzBwS9ucR+WPH03rBNFt6U1PDVrKxh1PzZlxjIUQpZiS2WF8Pa4HpO1 asqIl7JNiFERq85h0y6cguSnYg0dxNZzDVQYz6+Q= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+3643a18836bce555bff6@syzkaller.appspotmail.com, Arnd Bergmann , Charan Teja Reddy , Sumit Semwal Subject: [PATCH 5.7 107/112] dma-buf: Move dma_buf_release() from fops to dentry_ops Date: Tue, 7 Jul 2020 17:17:52 +0200 Message-Id: <20200707145806.061508327@linuxfoundation.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200707145800.925304888@linuxfoundation.org> References: <20200707145800.925304888@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Sumit Semwal commit 4ab59c3c638c6c8952bf07739805d20eb6358a4d upstream. Charan Teja reported a 'use-after-free' in dmabuffs_dname [1], which happens if the dma_buf_release() is called while the userspace is accessing the dma_buf pseudo fs's dmabuffs_dname() in another process, and dma_buf_release() releases the dmabuf object when the last reference to the struct file goes away. I discussed with Arnd Bergmann, and he suggested that rather than tying the dma_buf_release() to the file_operations' release(), we can tie it to the dentry_operations' d_release(), which will be called when the last ref to the dentry is removed. The path exercised by __fput() calls f_op->release() first, and then calls dput, which eventually calls d_op->d_release(). In the 'normal' case, when no userspace access is happening via dma_buf pseudo fs, there should be exactly one fd, file, dentry and inode, so closing the fd will kill of everything right away. In the presented case, the dentry's d_release() will be called only when the dentry's last ref is released. Therefore, lets move dma_buf_release() from fops->release() to d_ops->d_release() Many thanks to Arnd for his FS insights :) [1]: https://lore.kernel.org/patchwork/patch/1238278/ Fixes: bb2bb9030425 ("dma-buf: add DMA_BUF_SET_NAME ioctls") Reported-by: syzbot+3643a18836bce555bff6@syzkaller.appspotmail.com Cc: [5.3+] Cc: Arnd Bergmann Reported-by: Charan Teja Reddy Reviewed-by: Arnd Bergmann Signed-off-by: Sumit Semwal Tested-by: Charan Teja Reddy Link: https://patchwork.freedesktop.org/patch/msgid/20200611114418.19852-1-sumit.semwal@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/dma-buf/dma-buf.c | 54 +++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 29 deletions(-) --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -54,37 +54,11 @@ static char *dmabuffs_dname(struct dentr dentry->d_name.name, ret > 0 ? name : ""); } -static const struct dentry_operations dma_buf_dentry_ops = { - .d_dname = dmabuffs_dname, -}; - -static struct vfsmount *dma_buf_mnt; - -static int dma_buf_fs_init_context(struct fs_context *fc) -{ - struct pseudo_fs_context *ctx; - - ctx = init_pseudo(fc, DMA_BUF_MAGIC); - if (!ctx) - return -ENOMEM; - ctx->dops = &dma_buf_dentry_ops; - return 0; -} - -static struct file_system_type dma_buf_fs_type = { - .name = "dmabuf", - .init_fs_context = dma_buf_fs_init_context, - .kill_sb = kill_anon_super, -}; - -static int dma_buf_release(struct inode *inode, struct file *file) +static void dma_buf_release(struct dentry *dentry) { struct dma_buf *dmabuf; - if (!is_dma_buf_file(file)) - return -EINVAL; - - dmabuf = file->private_data; + dmabuf = dentry->d_fsdata; BUG_ON(dmabuf->vmapping_counter); @@ -110,9 +84,32 @@ static int dma_buf_release(struct inode module_put(dmabuf->owner); kfree(dmabuf->name); kfree(dmabuf); +} + +static const struct dentry_operations dma_buf_dentry_ops = { + .d_dname = dmabuffs_dname, + .d_release = dma_buf_release, +}; + +static struct vfsmount *dma_buf_mnt; + +static int dma_buf_fs_init_context(struct fs_context *fc) +{ + struct pseudo_fs_context *ctx; + + ctx = init_pseudo(fc, DMA_BUF_MAGIC); + if (!ctx) + return -ENOMEM; + ctx->dops = &dma_buf_dentry_ops; return 0; } +static struct file_system_type dma_buf_fs_type = { + .name = "dmabuf", + .init_fs_context = dma_buf_fs_init_context, + .kill_sb = kill_anon_super, +}; + static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma) { struct dma_buf *dmabuf; @@ -412,7 +409,6 @@ static void dma_buf_show_fdinfo(struct s } static const struct file_operations dma_buf_fops = { - .release = dma_buf_release, .mmap = dma_buf_mmap_internal, .llseek = dma_buf_llseek, .poll = dma_buf_poll,