Commit 9dcbeed4 authored by David Sterba's avatar David Sterba Committed by Chris Mason

btrfs: fix signed overflows in btrfs_sync_file

The calculation of range length in btrfs_sync_file leads to signed
overflow. This was caught by PaX gcc SIZE_OVERFLOW plugin.

https://forums.grsecurity.net/viewtopic.php?f=1&t=4284

The fsync call passes 0 and LLONG_MAX, the range length does not fit to
loff_t and overflows, but the value is converted to u64 so it silently
works as expected.

The minimal fix is a typecast to u64, switching functions to take
(start, end) instead of (start, len) would be more intrusive.

Coccinelle script found that there's one more opencoded calculation of
the length.

<smpl>
@@
loff_t start, end;
@@
* end - start
</smpl>

CC: stable@vger.kernel.org
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent d5f2e33b
...@@ -1882,8 +1882,13 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) ...@@ -1882,8 +1882,13 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
struct btrfs_log_ctx ctx; struct btrfs_log_ctx ctx;
int ret = 0; int ret = 0;
bool full_sync = 0; bool full_sync = 0;
const u64 len = end - start + 1; u64 len;
/*
* The range length can be represented by u64, we have to do the typecasts
* to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync()
*/
len = (u64)end - (u64)start + 1;
trace_btrfs_sync_file(file, datasync); trace_btrfs_sync_file(file, datasync);
/* /*
...@@ -2071,8 +2076,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) ...@@ -2071,8 +2076,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
} }
} }
if (!full_sync) { if (!full_sync) {
ret = btrfs_wait_ordered_range(inode, start, ret = btrfs_wait_ordered_range(inode, start, len);
end - start + 1);
if (ret) { if (ret) {
btrfs_end_transaction(trans, root); btrfs_end_transaction(trans, root);
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment