Messages in this thread Patch in this message | | | From | Samuel Holland <> | Subject | [PATCH] debugfs: Fix use-after-free in debugfs_create_devm_seqfile() | Date | Sat, 3 Apr 2021 19:45:04 -0500 |
| |
This function uses devres to clean up its allocation, but it never removes the file referencing that allocation. This causes a use-after-free and an oops if the file is accessed after the owning device is removed.
Fixes: 98210b7f73f1d ("debugfs: add helper function to create device related seq_file") Fixes: 0d519cbf38eed ("debugfs: remove return value of debugfs_create_devm_seqfile()") Signed-off-by: Samuel Holland <samuel@sholland.org> --- fs/debugfs/file.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 686e0ad28788..64f1f918e119 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -1100,6 +1100,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_regset32); struct debugfs_devm_entry { int (*read)(struct seq_file *seq, void *data); struct device *dev; + struct dentry *dentry; }; static int debugfs_devm_entry_open(struct inode *inode, struct file *f) @@ -1117,6 +1118,13 @@ static const struct file_operations debugfs_devm_entry_ops = { .llseek = seq_lseek }; +static void debugfs_devm_entry_release(struct device *dev, void *res) +{ + struct debugfs_devm_entry *entry = res; + + debugfs_remove(entry->dentry); +} + /** * debugfs_create_devm_seqfile - create a debugfs file that is bound to device. * @@ -1136,14 +1144,19 @@ void debugfs_create_devm_seqfile(struct device *dev, const char *name, if (IS_ERR(parent)) return; - entry = devm_kzalloc(dev, sizeof(*entry), GFP_KERNEL); + entry = devres_alloc(debugfs_devm_entry_release, sizeof(*entry), GFP_KERNEL); if (!entry) return; entry->read = read_fn; entry->dev = dev; + entry->dentry = debugfs_create_file(name, S_IRUGO, parent, entry, + &debugfs_devm_entry_ops); + if (IS_ERR(entry->dentry)) { + devres_free(entry); + return; + } - debugfs_create_file(name, S_IRUGO, parent, entry, - &debugfs_devm_entry_ops); + devres_add(dev, entry); } EXPORT_SYMBOL_GPL(debugfs_create_devm_seqfile); -- 2.26.2
| |