Skip to content

Commit 03bea60

Browse files
author
Miklos Szeredi
committed
ovl: get_write_access() in truncate
When truncating a file we should check write access on the underlying inode. And we should do so on the lower file as well (before copy-up) for consistency. Original patch and test case by Aihua Zhang. - - >o >o - - test.c - - >o >o - - #include <stdio.h> #include <errno.h> #include <unistd.h> int main(int argc, char *argv[]) { int ret; ret = truncate(argv[0], 4096); if (ret != -1) { fprintf(stderr, "truncate(argv[0]) should have failed\n"); return 1; } if (errno != ETXTBSY) { perror("truncate(argv[0])"); return 1; } return 0; } - - >o >o - - >o >o - - >o >o - - Reported-by: Aihua Zhang <zhangaihua1@huawei.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Cc: <stable@vger.kernel.org>
1 parent a4859d7 commit 03bea60

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

fs/overlayfs/inode.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,37 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
5959
if (err)
6060
goto out;
6161

62+
if (attr->ia_valid & ATTR_SIZE) {
63+
struct inode *realinode = d_inode(ovl_dentry_real(dentry));
64+
65+
err = -ETXTBSY;
66+
if (atomic_read(&realinode->i_writecount) < 0)
67+
goto out_drop_write;
68+
}
69+
6270
err = ovl_copy_up(dentry);
6371
if (!err) {
72+
struct inode *winode = NULL;
73+
6474
upperdentry = ovl_dentry_upper(dentry);
6575

76+
if (attr->ia_valid & ATTR_SIZE) {
77+
winode = d_inode(upperdentry);
78+
err = get_write_access(winode);
79+
if (err)
80+
goto out_drop_write;
81+
}
82+
6683
inode_lock(upperdentry->d_inode);
6784
err = notify_change(upperdentry, attr, NULL);
6885
if (!err)
6986
ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
7087
inode_unlock(upperdentry->d_inode);
88+
89+
if (winode)
90+
put_write_access(winode);
7191
}
92+
out_drop_write:
7293
ovl_drop_write(dentry);
7394
out:
7495
return err;

0 commit comments

Comments
 (0)