From patchwork Tue Jul 7 15:17:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg Kroah-Hartman X-Patchwork-Id: 235019 Delivered-To: patch@linaro.org Received: by 2002:a54:2c11:0:0:0:0:0 with SMTP id g17csp311327ecp; Tue, 7 Jul 2020 08:32:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz69irAuxfUXjJnms2zD82h1THEUAtkaQliq3YXHhCV1pCXdwUPOSiSzx5cepWpTZLN1rYN X-Received: by 2002:a05:6402:176e:: with SMTP id da14mr46929660edb.262.1594135952122; Tue, 07 Jul 2020 08:32:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594135952; cv=none; d=google.com; s=arc-20160816; b=qt4LFlaMjfndFVm9QoTxd/ytOUKDvvwkqxR/3nEicofAxS2BInBX/7XHYhvImjoZQF 68xJLiotf1OCnJCItnOdKcC6F6MqgbTi7fz2WKbj7/FfIdsFcBOtZOgu+GpsrejDMplP Ntct+OzD1LwnawteG/esFhTJ/+8yhhJE6vBzkw0/s8dsKXEDO3qe+e+esYqIrGR173ZA wL4XNusMJp8DQz9Ov+VIn/+biB9uz7Umk8V2+dL/4PibdRqKcNOPx2A5Lk5Pb4bUQAaa W++zwJ3kh4+tQ+Z0N7kogApSRHDETy39NwAQgsX5fNNwgr1ds4Vnq8f8Ciu5nY7V8rS1 WAVA== 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=ebD2sHpKmOGuhsI7u1sfmfDeTvojKLsKEUrxN88VzOZ7nV/P1B/cd5OF9wKZtRvyRm hAnloLXVZgHxuPtbgGW0yEXE/nfBnGi2h33Ki+nbFBAs00lY3BziJn6KSq7dW2dSfC6o 3UyVaR90o7wbNSIcvLyV3fOKNEAoir8O1vykUxvMPSXSoSNwiRjr/64FZeeVbDRiZa9T 6YUUCfFPh8FjawcfO2uhqyVdAO/9sOuI/kR5E8emJANFa6OQ8OAqk82pdcNN9mjDia9b JfebdRFh3PxTpcTVj9rHZVzZ6PUAY/dCX4JhkcL8hazhC22CFc9trt3IurZUDZXmsiWV SG0Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=LinlGXMj; 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 v19si13970753ejj.608.2020.07.07.08.32.31; Tue, 07 Jul 2020 08:32:32 -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=LinlGXMj; 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 S1729786AbgGGPWB (ORCPT + 15 others); Tue, 7 Jul 2020 11:22:01 -0400 Received: from mail.kernel.org ([198.145.29.99]:34310 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728337AbgGGPWA (ORCPT ); Tue, 7 Jul 2020 11:22:00 -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 4636C2065D; Tue, 7 Jul 2020 15:21:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1594135319; bh=tsP8O2XrM6avr/0AZZLaqustfwT7bO1HRrcl6qYXHwE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LinlGXMjS6ApCfhG8GVlCWYcP+sApGQF1RkRoxtR+iVDir9MIVtSQT1ZyRs/zXRAB U6Uv16yaOXPKcG47ex3LijB86XW7/uYQtA/JtboMXnSoJ1PRBcWeRWmbwXtwfNIzUK KlMVrI/hHmkb+ySnz4z4LNoZAXyjssHP6WXnk220= 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.4 59/65] dma-buf: Move dma_buf_release() from fops to dentry_ops Date: Tue, 7 Jul 2020 17:17:38 +0200 Message-Id: <20200707145755.318431154@linuxfoundation.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200707145752.417212219@linuxfoundation.org> References: <20200707145752.417212219@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,