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

vfs: explicitly cast s_maxbytes in fiemap_check_ranges

If fiemap_check_ranges is passed a large enough value, then it's
possible that the value would be cast to a signed value for comparison
against s_maxbytes when we change it to loff_t. Make sure that doesn't
happen by explicitly casting s_maxbytes to an unsigned value for the
purposes of comparison.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Robert Love <rlove@google.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Mandeep Singh Baines <msb@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

authored by

Jeff Layton and committed by
Al Viro
5aa98b70 05cc0cee

+5 -4
+5 -4
fs/ioctl.c
··· 162 162 static int fiemap_check_ranges(struct super_block *sb, 163 163 u64 start, u64 len, u64 *new_len) 164 164 { 165 + u64 maxbytes = (u64) sb->s_maxbytes; 166 + 165 167 *new_len = len; 166 168 167 169 if (len == 0) 168 170 return -EINVAL; 169 171 170 - if (start > sb->s_maxbytes) 172 + if (start > maxbytes) 171 173 return -EFBIG; 172 174 173 175 /* 174 176 * Shrink request scope to what the fs can actually handle. 175 177 */ 176 - if ((len > sb->s_maxbytes) || 177 - (sb->s_maxbytes - len) < start) 178 - *new_len = sb->s_maxbytes - start; 178 + if (len > maxbytes || (maxbytes - len) < start) 179 + *new_len = maxbytes - start; 179 180 180 181 return 0; 181 182 }