• Tejun Heo's avatar
    kernfs: associate a new kernfs_node with its parent on creation · db4aad20
    Tejun Heo authored
    Once created, a kernfs_node is always destroyed by kernfs_put().
    Since ba7443bc ("sysfs, kernfs: implement
    kernfs_create/destroy_root()"), kernfs_put() depends on kernfs_root()
    to locate the ino_ida.  kernfs_root() in turn depends on
    kernfs_node->parent being set for !dir nodes.  This means that
    kernfs_put() of a !dir node requires its ->parent to be initialized.
    
    This leads to oops when a newly created !dir node is destroyed without
    going through kernfs_add_one() or after failing kernfs_add_one()
    before ->parent is set.  kernfs_root() invoked from kernfs_put() will
    try to dereference NULL parent.
    
    Fix it by moving parent association to kernfs_new_node() from
    kernfs_add_one().  kernfs_new_node() now takes @parent instead of
    @root and determines the root from the parent and also sets the new
    node's parent properly.  @parent parameter is removed from
    kernfs_add_one().  As there's no parent when creating the root node,
    __kernfs_new_node() which takes @root as before and doesn't set the
    parent is used in that case.
    
    This ensures that a kernfs_node in any stage in its life has its
    parent associated and thus can be put.
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    db4aad20
kernfs-internal.h 3.32 KB