All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Christian König" <ckoenig.leichtzumerken@gmail.com>
To: Charan Teja Reddy <charante@codeaurora.org>,
	sumit.semwal@linaro.org, christian.koenig@amd.com, arnd@arndb.de,
	linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org
Cc: linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org
Subject: Re: [Linaro-mm-sig] [PATCH] dmabuf: fix use-after-free of dmabuf's file->f_inode
Date: Mon, 4 Jan 2021 12:52:44 +0100	[thread overview]
Message-ID: <0dcbf9c5-3c28-0f57-0069-3fe5dc3aa7f6@gmail.com> (raw)
In-Reply-To: <1609760177-6083-1-git-send-email-charante@codeaurora.org>

Am 04.01.21 um 12:36 schrieb Charan Teja Reddy:
> 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.
>
> Fixes: 4ab59c3c638c ("dma-buf: Move dma_buf_release() from fops to dentry_ops")
> Signed-off-by: Charan Teja Reddy <charante@codeaurora.org>

Not an expert on the debugfs stuff in DMA-buf, but the explanation 
sounds perfectly correct to me.

Acked-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/dma-buf/dma-buf.c | 21 +++++++++++++++++----
>   1 file changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index 0eb80c1..a14dcbb 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c
> @@ -76,10 +76,6 @@ static void dma_buf_release(struct dentry *dentry)
>   
>   	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 dentry *dentry)
>   	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 seq_file *m, struct file *file)
>   }
>   
>   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,


WARNING: multiple messages have this Message-ID (diff)
From: "Christian König" <ckoenig.leichtzumerken@gmail.com>
To: Charan Teja Reddy <charante@codeaurora.org>,
	sumit.semwal@linaro.org, christian.koenig@amd.com, arnd@arndb.de,
	linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org
Cc: linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org
Subject: Re: [Linaro-mm-sig] [PATCH] dmabuf: fix use-after-free of dmabuf's file->f_inode
Date: Mon, 4 Jan 2021 12:52:44 +0100	[thread overview]
Message-ID: <0dcbf9c5-3c28-0f57-0069-3fe5dc3aa7f6@gmail.com> (raw)
In-Reply-To: <1609760177-6083-1-git-send-email-charante@codeaurora.org>

Am 04.01.21 um 12:36 schrieb Charan Teja Reddy:
> 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.
>
> Fixes: 4ab59c3c638c ("dma-buf: Move dma_buf_release() from fops to dentry_ops")
> Signed-off-by: Charan Teja Reddy <charante@codeaurora.org>

Not an expert on the debugfs stuff in DMA-buf, but the explanation 
sounds perfectly correct to me.

Acked-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/dma-buf/dma-buf.c | 21 +++++++++++++++++----
>   1 file changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
> index 0eb80c1..a14dcbb 100644
> --- a/drivers/dma-buf/dma-buf.c
> +++ b/drivers/dma-buf/dma-buf.c
> @@ -76,10 +76,6 @@ static void dma_buf_release(struct dentry *dentry)
>   
>   	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 dentry *dentry)
>   	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 seq_file *m, struct file *file)
>   }
>   
>   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,

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2021-01-04 11:53 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-04 11:36 [PATCH] dmabuf: fix use-after-free of dmabuf's file->f_inode Charan Teja Reddy
2021-01-04 11:36 ` Charan Teja Reddy
2021-01-04 11:52 ` Christian König [this message]
2021-01-04 11:52   ` [Linaro-mm-sig] " Christian König
2021-01-05  6:48   ` Sumit Semwal
2021-01-05  6:48     ` Sumit Semwal

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0dcbf9c5-3c28-0f57-0069-3fe5dc3aa7f6@gmail.com \
    --to=ckoenig.leichtzumerken@gmail.com \
    --cc=arnd@arndb.de \
    --cc=charante@codeaurora.org \
    --cc=christian.koenig@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linaro-mm-sig@lists.linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=sumit.semwal@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.