• J
    configfs: fix race between dentry put and lookup · 76ae281f
    Junxiao Bi 提交于
    A race window in configfs, it starts from one dentry is UNHASHED and end
    before configfs_d_iput is called.  In this window, if a lookup happen,
    since the original dentry was UNHASHED, so a new dentry will be
    allocated, and then in configfs_attach_attr(), sd->s_dentry will be
    updated to the new dentry.  Then in configfs_d_iput(),
    BUG_ON(sd->s_dentry != dentry) will be triggered and system panic.
    
    sys_open:                     sys_close:
     ...                           fput
                                    dput
                                     dentry_kill
                                      __d_drop <--- dentry unhashed here,
                                               but sd->dentry still point
                                               to this dentry.
    
     lookup_real
      configfs_lookup
       configfs_attach_attr---> update sd->s_dentry
                                to new allocated dentry here.
    
                                       d_kill
                                         configfs_d_iput <--- BUG_ON(sd->s_dentry != dentry)
                                                         triggered here.
    
    To fix it, change configfs_d_iput to not update sd->s_dentry if
    sd->s_count > 2, that means there are another dentry is using the sd
    beside the one that is going to be put.  Use configfs_dirent_lock in
    configfs_attach_attr to sync with configfs_d_iput.
    
    With the following steps, you can reproduce the bug.
    
    1. enable ocfs2, this will mount configfs at /sys/kernel/config and
       fill configure in it.
    
    2. run the following script.
    	while [ 1 ]; do cat /sys/kernel/config/cluster/$your_cluster_name/idle_timeout_ms > /dev/null; done &
    	while [ 1 ]; do cat /sys/kernel/config/cluster/$your_cluster_name/idle_timeout_ms > /dev/null; done &
    Signed-off-by: NJunxiao Bi <junxiao.bi@oracle.com>
    Cc: Joel Becker <jlbec@evilplan.org>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
    76ae281f
dir.c 43.6 KB