aboutsummaryrefslogtreecommitdiffstats
path: root/fs/kernfs
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-12-11 16:02:56 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-12-17 11:59:15 -0500
commitd0ae3d4347ee025cf23b850d484fe8593f7dd0f2 (patch)
tree5d6e4464ab25022c840733b17be5d3480b1dea84 /fs/kernfs
parentbb8b9d095c5c56cce99576cfef0cf9b989f7120d (diff)
kernfs: add REMOVED check to create and rename paths
kernfs currently assumes that the caller doesn't try to create a new node under a removed parent, rename a removed node, or move a node under a removed node. While this works fine for sysfs, it'd be nice to have protection against such cases especially given that kernfs is planned to add support for mkdir, rmdir and rename requsts from userland which may make race conditions more likely. This patch updates create and rename paths to check REMOVED and fail the operation with -ENOENT if performed on or towards removed nodes. Note that remove path already has such check. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/kernfs')
-rw-r--r--fs/kernfs/dir.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index e55bb02f15a4..ba5f372a226d 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -430,6 +430,9 @@ int kernfs_add_one(struct kernfs_addrm_cxt *acxt, struct kernfs_node *kn,
430 if (kernfs_type(parent) != KERNFS_DIR) 430 if (kernfs_type(parent) != KERNFS_DIR)
431 return -EINVAL; 431 return -EINVAL;
432 432
433 if (parent->flags & KERNFS_REMOVED)
434 return -ENOENT;
435
433 kn->hash = kernfs_name_hash(kn->name, kn->ns); 436 kn->hash = kernfs_name_hash(kn->name, kn->ns);
434 kn->parent = parent; 437 kn->parent = parent;
435 kernfs_get(parent); 438 kernfs_get(parent);
@@ -863,6 +866,10 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
863 866
864 mutex_lock(&kernfs_mutex); 867 mutex_lock(&kernfs_mutex);
865 868
869 error = -ENOENT;
870 if ((kn->flags | new_parent->flags) & KERNFS_REMOVED)
871 goto out;
872
866 error = 0; 873 error = 0;
867 if ((kn->parent == new_parent) && (kn->ns == new_ns) && 874 if ((kn->parent == new_parent) && (kn->ns == new_ns) &&
868 (strcmp(kn->name, new_name) == 0)) 875 (strcmp(kn->name, new_name) == 0))