summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2019-11-04 15:54:29 -0800
committerTejun Heo <tj@kernel.org>2019-11-12 08:18:03 -0800
commit880df131617393252f1fff701ed5b7b6d14c52c4 (patch)
treefc28379549f13b2ac6d4cbf1171b3d31aba6b470
parentb680b08171ebf890a4ebb7f82ada9959f4534ade (diff)
downloadlinux-880df131617393252f1fff701ed5b7b6d14c52c4.tar.bz2
kernfs: kernfs_find_and_get_node_by_ino() should only look up activated nodes
kernfs node can be created in two separate steps - allocation and activation. This is used to make kernfs nodes visible only after the internal states attached to the node are fully initialized. kernfs_find_and_get_node_by_id() currently allows lookups of nodes which aren't activated yet and thus can expose nodes are which are still being prepped by kernfs users. Fix it by disallowing lookups of nodes which aren't activated yet. kernfs_find_and_get_node_by_ino() Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Namhyung Kim <namhyung@kernel.org>
-rw-r--r--fs/kernfs/dir.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 798f0f03b62b..beabb585a7d8 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -714,7 +714,13 @@ struct kernfs_node *kernfs_find_and_get_node_by_ino(struct kernfs_root *root,
if (!kn)
goto err_unlock;
- if (unlikely(!atomic_inc_not_zero(&kn->count)))
+ /*
+ * ACTIVATED is protected with kernfs_mutex but it was clear when
+ * @kn was added to idr and we just wanna see it set. No need to
+ * grab kernfs_mutex.
+ */
+ if (unlikely(!(kn->flags & KERNFS_ACTIVATED) ||
+ !atomic_inc_not_zero(&kn->count)))
goto err_unlock;
spin_unlock(&kernfs_idr_lock);