Skip to content
  • Andrew Elble's avatar
    NFS: fix BUG() crash in notify_change() with patch to chown_common() · c1b8940b
    Andrew Elble authored
    We have observed a BUG() crash in fs/attr.c:notify_change(). The crash
    occurs during an rsync into a filesystem that is exported via NFS.
    
    1.) fs/attr.c:notify_change() modifies the caller's version of attr.
    2.) 6de0ec00 ("VFS: make notify_change pass ATTR_KILL_S*ID to
        setattr operations") introduced a BUG() restriction such that "no
        function will ever call notify_change() with both ATTR_MODE and
        ATTR_KILL_S*ID set". Under some circumstances though, it will have
        assisted in setting the caller's version of attr to this very
        combination.
    3.) 27ac0ffe ("locks: break delegations on any attribute
        modification") introduced code to handle breaking
        delegations. This can result in notify_change() being re-called. attr
        _must_ be explicitly reset to avoid triggering the BUG() established
        in #2.
    4.) The path that that triggers this is via fs/open.c:chmod_common().
        The combination of attr flags set here and in the first call to
        notify_change() along with a later failed break_deleg_wait()
        results in notify_change() being called again via retry_deleg
        without resetting attr.
    
    Solution is to move retry_deleg in chmod_common() a bit further up to
    ensure attr is completely reset.
    
    There are other places where this seemingly could occur, such as
    fs/utimes.c:utimes_common(), but the attr flags are not initially
    set in such a way to trigger this.
    
    Fixes: 27ac0ffe
    
     ("locks: break delegations on any attribute modification")
    Reported-by: default avatarEric Meddaugh <etmsys@rit.edu>
    Tested-by: default avatarEric Meddaugh <etmsys@rit.edu>
    Signed-off-by: default avatarAndrew Elble <aweits@rit.edu>
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    c1b8940b