aboutsummaryrefslogtreecommitdiffstats
path: root/fs/debugfs
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2011-02-07 09:00:27 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-02-18 11:07:18 -0500
commit25d41d8455ec1ee7433e146ee94436dc4195f420 (patch)
tree2f5bc09d4ac7024d08fa8c1c0988171d8b792fcb /fs/debugfs
parentb38360a284f8acab4ae431b387c05a4e19ff4129 (diff)
debugfs: Fix filesystem reference counting on debugfs_remove() failure
When __debugfs_remove() fails (because simple_rmdir() fails e.g. when a directory is not empty), we must not decrement use count of the filesystem as nothing was in fact deleted. This fixes use after free caused by debugfs in some cases. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/debugfs')
-rw-r--r--fs/debugfs/inode.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index d38c88fb63ae..e7a7a2f07324 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -307,7 +307,7 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
307} 307}
308EXPORT_SYMBOL_GPL(debugfs_create_symlink); 308EXPORT_SYMBOL_GPL(debugfs_create_symlink);
309 309
310static void __debugfs_remove(struct dentry *dentry, struct dentry *parent) 310static int __debugfs_remove(struct dentry *dentry, struct dentry *parent)
311{ 311{
312 int ret = 0; 312 int ret = 0;
313 313
@@ -330,6 +330,7 @@ static void __debugfs_remove(struct dentry *dentry, struct dentry *parent)
330 dput(dentry); 330 dput(dentry);
331 } 331 }
332 } 332 }
333 return ret;
333} 334}
334 335
335/** 336/**
@@ -348,7 +349,8 @@ static void __debugfs_remove(struct dentry *dentry, struct dentry *parent)
348void debugfs_remove(struct dentry *dentry) 349void debugfs_remove(struct dentry *dentry)
349{ 350{
350 struct dentry *parent; 351 struct dentry *parent;
351 352 int ret;
353
352 if (!dentry) 354 if (!dentry)
353 return; 355 return;
354 356
@@ -357,9 +359,10 @@ void debugfs_remove(struct dentry *dentry)
357 return; 359 return;
358 360
359 mutex_lock(&parent->d_inode->i_mutex); 361 mutex_lock(&parent->d_inode->i_mutex);
360 __debugfs_remove(dentry, parent); 362 ret = __debugfs_remove(dentry, parent);
361 mutex_unlock(&parent->d_inode->i_mutex); 363 mutex_unlock(&parent->d_inode->i_mutex);
362 simple_release_fs(&debugfs_mount, &debugfs_mount_count); 364 if (!ret)
365 simple_release_fs(&debugfs_mount, &debugfs_mount_count);
363} 366}
364EXPORT_SYMBOL_GPL(debugfs_remove); 367EXPORT_SYMBOL_GPL(debugfs_remove);
365 368