dmabuf: fix use-after-free of dmabuf's file->f_inode
[platform/kernel/linux-rpi.git] / drivers / dma-buf / dma-buf.c
index 844967f..922416b 100644 (file)
@@ -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,