mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
dax: fix offset overflow in dax_io
This isn't functionally apparent for some reason, but
when we test io at extreme offsets at the end of the loff_t
rang, such as in fstests xfs/071, the calculation of
"max" in dax_io() can be wrong due to pos + size overflowing.
For example,
# xfs_io -c "pwrite 9223372036854771712 512" /mnt/test/file
enters dax_io with:
start 0x7ffffffffffff000
end 0x7ffffffffffff200
and the rounded up "size" variable is 0x1000. This yields:
pos + size 0x8000000000000000 (overflows loff_t)
end 0x7ffffffffffff200
Due to the overflow, the min() function picks the wrong
value for the "max" variable, and when we send (max - pos)
into i.e. copy_from_iter_pmem() it is also the wrong value.
This somehow(tm) gets magically absorbed without incident,
probably because iter->count is correct. But it seems best
to fix it up properly by comparing the two values as
unsigned.
Signed-off-by: Eric Sandeen <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
This commit is contained in:
parent
4995734e97
commit
023954351f
1 changed files with 6 additions and 1 deletions
7
fs/dax.c
7
fs/dax.c
|
|
@ -208,7 +208,12 @@ static ssize_t dax_io(struct inode *inode, struct iov_iter *iter,
|
|||
dax.addr += first;
|
||||
size = map_len - first;
|
||||
}
|
||||
max = min(pos + size, end);
|
||||
/*
|
||||
* pos + size is one past the last offset for IO,
|
||||
* so pos + size can overflow loff_t at extreme offsets.
|
||||
* Cast to u64 to catch this and get the true minimum.
|
||||
*/
|
||||
max = min_t(u64, pos + size, end);
|
||||
}
|
||||
|
||||
if (iov_iter_rw(iter) == WRITE) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue