mirror of
https://github.com/torvalds/linux.git
synced 2026-09-13 06:17:27 +02:00
smb/client: validate new EOF for zero range
When FALLOC_FL_ZERO_RANGE is used without FALLOC_FL_KEEP_SIZE,
smb3_zero_range() may extend EOF without checking RLIMIT_FSIZE, allowing
the file to grow beyond the caller's file-size limit.
Fix this by calling inode_newsize_ok() before sending the zero-range
request when the operation would extend EOF.
Reproducer, using a file on a CIFS mount:
bash -c '
FILE=/mnt/cifs/repro
trap "" SIGXFSZ
ulimit -f 3072
truncate -s 2M "$FILE"
fallocate --zero-range -o 0 -l 4M "$FILE"
echo "fallocate rc=$?"
stat -c "file size=%s" "$FILE"
'
Before this change, the operation succeeds despite the 3 MiB limit:
fallocate rc=0
file size=4194304
After this change, fallocate fails and leaves the file at 2 MiB.
Fixes: 72c419d9b0 ("cifs: fix smb3_zero_range so it can expand the file-size when required")
Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
This commit is contained in:
parent
1519dc88c8
commit
88972e3575
|
|
@ -3444,6 +3444,13 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
|
|||
trace_smb3_zero_enter(xid, cfile->fid.persistent_fid, tcon->tid,
|
||||
ses->Suid, offset, len);
|
||||
|
||||
new_size = offset + len;
|
||||
if (!keep_size && i_size_read(inode) < new_size) {
|
||||
rc = inode_newsize_ok(inode, new_size);
|
||||
if (rc)
|
||||
goto out;
|
||||
}
|
||||
|
||||
filemap_invalidate_lock(inode->i_mapping);
|
||||
|
||||
netfs_read_sizes(inode, &i_size, &remote_i_size, &zero_point);
|
||||
|
|
@ -3474,7 +3481,6 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
|
|||
/*
|
||||
* do we also need to change the size of the file?
|
||||
*/
|
||||
new_size = offset + len;
|
||||
if (keep_size == false && (unsigned long long)i_size_read(inode) < new_size) {
|
||||
rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
|
||||
cfile->fid.volatile_fid, cfile->pid, new_size);
|
||||
|
|
@ -3491,6 +3497,7 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
|
|||
|
||||
zero_range_exit:
|
||||
filemap_invalidate_unlock(inode->i_mapping);
|
||||
out:
|
||||
free_xid(xid);
|
||||
if (rc)
|
||||
trace_smb3_zero_err(xid, cfile->fid.persistent_fid, tcon->tid,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user