Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fuse: validate outarg offset and size in notify store/retrieve

Add validation checking for outarg offset and outarg size values passed
in by the server. MAX_LFS_FILESIZE is the maximum file size supported.
The fuse_notify_store_out and fuse_notify_retrieve_out structs take in
a uint64_t offset.

Add logic to ensure:
* outarg.offset is less than MAX_LFS_FILESIZE
* outarg.offset + outarg.size cannot exceed MAX_LFS_FILESIZE
* potential uint64_t overflow is fixed when adding outarg.offset and
outarg.size.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>

authored by

Joanne Koong and committed by
Miklos Szeredi
65161470 59ba47b6

+10 -4
+10 -4
fs/fuse/dev.c
··· 1783 1783 if (size - sizeof(outarg) != outarg.size) 1784 1784 return -EINVAL; 1785 1785 1786 + if (outarg.offset >= MAX_LFS_FILESIZE) 1787 + return -EINVAL; 1788 + 1786 1789 nodeid = outarg.nodeid; 1790 + num = min(outarg.size, MAX_LFS_FILESIZE - outarg.offset); 1787 1791 1788 1792 down_read(&fc->killsb); 1789 1793 ··· 1800 1796 index = outarg.offset >> PAGE_SHIFT; 1801 1797 offset = outarg.offset & ~PAGE_MASK; 1802 1798 file_size = i_size_read(inode); 1803 - end = outarg.offset + outarg.size; 1799 + end = outarg.offset + num; 1804 1800 if (end > file_size) { 1805 1801 file_size = end; 1806 - fuse_write_update_attr(inode, file_size, outarg.size); 1802 + fuse_write_update_attr(inode, file_size, num); 1807 1803 } 1808 1804 1809 - num = outarg.size; 1810 1805 while (num) { 1811 1806 struct folio *folio; 1812 1807 unsigned int folio_offset; ··· 1885 1882 num = min(outarg->size, fc->max_write); 1886 1883 if (outarg->offset > file_size) 1887 1884 num = 0; 1888 - else if (outarg->offset + num > file_size) 1885 + else if (num > file_size - outarg->offset) 1889 1886 num = file_size - outarg->offset; 1890 1887 1891 1888 num_pages = (num + offset + PAGE_SIZE - 1) >> PAGE_SHIFT; ··· 1966 1963 return err; 1967 1964 1968 1965 fuse_copy_finish(cs); 1966 + 1967 + if (outarg.offset >= MAX_LFS_FILESIZE) 1968 + return -EINVAL; 1969 1969 1970 1970 down_read(&fc->killsb); 1971 1971 err = -ENOENT;