• Brian Foster's avatar
    xfs: fix tmpfile/selinux deadlock and initialize security · 330033d6
    Brian Foster authored
    xfstests generic/004 reproduces an ilock deadlock using the tmpfile
    interface when selinux is enabled. This occurs because
    xfs_create_tmpfile() takes the ilock and then calls d_tmpfile(). The
    latter eventually calls into xfs_xattr_get() which attempts to get the
    lock again. E.g.:
    
    xfs_io          D ffffffff81c134c0  4096  3561   3560 0x00000080
    ffff8801176a1a68 0000000000000046 ffff8800b401b540 ffff8801176a1fd8
    00000000001d5800 00000000001d5800 ffff8800b401b540 ffff8800b401b540
    ffff8800b73a6bd0 fffffffeffffffff ffff8800b73a6bd8 ffff8800b5ddb480
    Call Trace:
    [<ffffffff8177f969>] schedule+0x29/0x70
    [<ffffffff81783a65>] rwsem_down_read_failed+0xc5/0x120
    [<ffffffffa05aa97f>] ? xfs_ilock_attr_map_shared+0x1f/0x50 [xfs]
    [<ffffffff813b3434>] call_rwsem_down_read_failed+0x14/0x30
    [<ffffffff810ed179>] ? down_read_nested+0x89/0xa0
    [<ffffffffa05aa7f2>] ? xfs_ilock+0x122/0x250 [xfs]
    [<ffffffffa05aa7f2>] xfs_ilock+0x122/0x250 [xfs]
    [<ffffffffa05aa97f>] xfs_ilock_attr_map_shared+0x1f/0x50 [xfs]
    [<ffffffffa05701d0>] xfs_attr_get+0x90/0xe0 [xfs]
    [<ffffffffa0565e07>] xfs_xattr_get+0x37/0x50 [xfs]
    [<ffffffff8124842f>] generic_getxattr+0x4f/0x70
    [<ffffffff8133fd9e>] inode_doinit_with_dentry+0x1ae/0x650
    [<ffffffff81340e0c>] selinux_d_instantiate+0x1c/0x20
    [<ffffffff813351bb>] security_d_instantiate+0x1b/0x30
    [<ffffffff81237db0>] d_instantiate+0x50/0x70
    [<ffffffff81237e85>] d_tmpfile+0xb5/0xc0
    [<ffffffffa05add02>] xfs_create_tmpfile+0x362/0x410 [xfs]
    [<ffffffffa0559ac8>] xfs_vn_tmpfile+0x18/0x20 [xfs]
    [<ffffffff81230388>] path_openat+0x228/0x6a0
    [<ffffffff810230f9>] ? sched_clock+0x9/0x10
    [<ffffffff8105a427>] ? kvm_clock_read+0x27/0x40
    [<ffffffff8124054f>] ? __alloc_fd+0xaf/0x1f0
    [<ffffffff8123101a>] do_filp_open+0x3a/0x90
    [<ffffffff817845e7>] ? _raw_spin_unlock+0x27/0x40
    [<ffffffff8124054f>] ? __alloc_fd+0xaf/0x1f0
    [<ffffffff8121e3ce>] do_sys_open+0x12e/0x210
    [<ffffffff8121e4ce>] SyS_open+0x1e/0x20
    [<ffffffff8178eda9>] system_call_fastpath+0x16/0x1b
    
    xfs_vn_tmpfile() also fails to initialize security on the newly created
    inode.
    
    Pull the d_tmpfile() call up into xfs_vn_tmpfile() after the transaction
    has been committed and the inode unlocked. Also, initialize security on
    the inode based on the parent directory provided via the tmpfile call.
    Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
    330033d6
xfs_inode.h 11.9 KB