Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp1133557ybt; Tue, 7 Jul 2020 08:30:05 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwMCUI+Y3x5x+ElsvsAmrnmpN8Wlz16UaK+fgwnyJCiokPX5e89WAKsBg/VV9Ch1ykCXFEz X-Received: by 2002:a17:906:3984:: with SMTP id h4mr42595987eje.254.1594135805546; Tue, 07 Jul 2020 08:30:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1594135805; cv=none; d=google.com; s=arc-20160816; b=PwjggLhs3PTOsFIJ/gT2FOiwRr3l472u6hLZ7a7CBzTvO+jAIHiBF3hMjoNhTsVzqD XA1tSSUKYpH5KrQriA6mI3A4BnhFHAWE12RADbJGV36MFxb4VGNUQSkFUeEVcDrRpw6S gimKzvVvSMdkyz6xv8C9PnZT+ozq9Oibfef5d5W9jUg9SZMtbUhn4lHWyTiF4SbKX7UA +dwi+Zv7idbR/tJ9Lx6xjmtxyLlKZ+e07LtpiWK2QjJUSOEwckB8Qp2MP3XemfBMRniq 7NVAIuqPY3ThMwmZ8JcdCfS29ycCLVOwmbeQVNo3I1MXyqSSem5jMxZaeOVwBmZ/BzsK CpaQ== 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=ayXyorqujlIujxYEr4dhyGVA7YvS5YJnBCLTJWAdUl67nvEKpRckf1VjYgkRDzi74Q C1d2lxEv/Kj6cZzkNYWWQfyO0ipGeIVKeTQzWjWCTOrdFV2Z51hHmne9CsuWU8mRC6kE O0XXjMnDYWPmQf1Ixl5lRe5eVVp+zkGAJk6MNMFvbPvRUqNrgy/F3C5zQzmBRxaPeqVS pOYGDHuuJtqKNeNQwwAOzHwuYcEQqubRGjgpFBN1SzUQ405i0nhSB9P1IzQ/WmJFstQv Jliq/naE2nZsloC2meGjU4Q3QTcXe/OLJWIh7St5m4fXu3tKus0xH73Bl20hld1fKbxi OYUg== 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 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 g16si14213570edu.513.2020.07.07.08.29.42; Tue, 07 Jul 2020 08:30:05 -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; dkim=pass header.i=@kernel.org header.s=default header.b=vjXTO3dB; 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 S1730325AbgGGP05 (ORCPT + 99 others); Tue, 7 Jul 2020 11:26:57 -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 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@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,