ovl: protect copying of realinode attributes to ovl inode
authorAmir Goldstein <amir73il@gmail.com>
Thu, 24 Aug 2023 11:51:17 +0000 (14:51 +0300)
committerAmir Goldstein <amir73il@gmail.com>
Mon, 30 Oct 2023 22:12:55 +0000 (00:12 +0200)
ovl_copyattr() may be called concurrently from aio completion context
without any lock and that could lead to overlay inode attributes getting
permanently out of sync with real inode attributes.

Use ovl inode spinlock to protect ovl_copyattr().

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
fs/overlayfs/util.c

index 868afd8834c323d652aa33abb145084d0c235450..4a9e7efc90aacfb1e45053c30a82b0c686f0a03d 100644 (file)
@@ -1403,6 +1403,7 @@ void ovl_copyattr(struct inode *inode)
        realinode = ovl_i_path_real(inode, &realpath);
        real_idmap = mnt_idmap(realpath.mnt);
 
+       spin_lock(&inode->i_lock);
        vfsuid = i_uid_into_vfsuid(real_idmap, realinode);
        vfsgid = i_gid_into_vfsgid(real_idmap, realinode);
 
@@ -1413,4 +1414,5 @@ void ovl_copyattr(struct inode *inode)
        inode_set_mtime_to_ts(inode, inode_get_mtime(realinode));
        inode_set_ctime_to_ts(inode, inode_get_ctime(realinode));
        i_size_write(inode, i_size_read(realinode));
+       spin_unlock(&inode->i_lock);
 }