• Greg Kurz's avatar
    fs/9p: search open fids first · 478ba09e
    Greg Kurz authored
    A previous patch fixed the "create-unlink-getattr" idiom: if getattr is
    called on an unlinked file, we try to find an open fid attached to the
    corresponding inode.
    
    We have a similar issue with file permissions and setattr:
    
    open("./test.txt", O_RDWR|O_CREAT, 0666) = 4
    chmod("./test.txt", 0)                  = 0
    truncate("./test.txt", 0)               = -1 EACCES (Permission denied)
    ftruncate(4, 0)                         = -1 EACCES (Permission denied)
    
    The failure is expected with truncate() but not with ftruncate().
    
    This happens because the lookup code does find a matching fid in the
    dentry list. Unfortunately, this is not an open fid and the server
    will be forced to rely on the path name, rather than on an open file
    descriptor. This is the case in QEMU: the setattr operation will use
    truncate() and fail because of bad write permissions.
    
    This patch changes the logic in the lookup code, so that we consider
    open fids first. It gives a chance to the server to match this open
    fid to an open file descriptor and use ftruncate() instead of truncate().
    This does not change the current behaviour for truncate() and other
    path name based syscalls, since file permissions are checked earlier
    in the VFS layer.
    
    With this patch, we get:
    
    open("./test.txt", O_RDWR|O_CREAT, 0666) = 4
    chmod("./test.txt", 0)                  = 0
    truncate("./test.txt", 0)               = -1 EACCES (Permission denied)
    ftruncate(4, 0)                         = 0
    
    Link: http://lkml.kernel.org/r/20200923141146.90046-4-jianyong.wu@arm.comSigned-off-by: default avatarGreg Kurz <groug@kaod.org>
    Signed-off-by: default avatarJianyong Wu <jianyong.wu@arm.com>
    Signed-off-by: default avatarDominique Martinet <asmadeus@codewreck.org>
    478ba09e
fid.c 7.19 KB