[lkml]   [2017]   [Dec]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Patch in this message
Subject[PATCH] fs: Fix signed integer overflow for vfs_setpos
The undefined behaviour sanatizer detected an signed integer overflow like this:

r0 = memfd_create(&(0x7f0000002000-0x12)="2e726571756573745f6b65795f6175746800",0x0)
lseek(r0, 0x4040000000000000, 0x1)
setsockopt$inet6_IPV6_FLOWLABEL_MGR(r0, 0x29, 0x20,
&(0x7f000000b000-0xd)={@empty={[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]}, 0x9, 0x1, 0xff, 0x2, 0x6, 0x1,0xd27}, 0x20)
mmap(&(0x7f000000e000/0x1000)=nil, 0x1000, 0x3, 0x32,0xffffffffffffffff, 0x0)
ioctl$sock_SIOCGSKNS(r0, 0x894c, &(0x7f000000f000-0x4)=0x10000)
UBSAN: Undefined behaviour in fs/read_write.c:107:12
signed integer overflow:
4629700416936869888 + 4629700416936869888 cannot be represented in type
'long long int'
CPU: 0 PID: 11653 Comm: syz-executor0 Not tainted 4.x.xx+ #2
Hardware name: linux,dummy-virt (DT)
Call trace:
[<ffffffc00008f4d0>] dump_backtrace+0x0/0x2a0
[<ffffffc00008f790>] show_stack+0x20/0x30
[<ffffffc000ec3b5c>] dump_stack+0x11c/0x16c
[<ffffffc000ec3e80>] ubsan_epilogue+0x18/0x70
[<ffffffc000ec4ca0>] handle_overflow+0x14c/0x188
[<ffffffc000ec4d10>] __ubsan_handle_add_overflow+0x34/0x44
[<ffffffc000327740>] generic_file_llseek_size+0x1f8/0x2a0
[<ffffffc0002826fc>] shmem_file_llseek+0x7c/0x1f8
[<ffffffc000327b88>] SyS_lseek+0xc0/0x118

The problem happened because the calculation of signed integer resulted
an overflow for the signed integer, so use the unsigned integer to avoid
undefined behaviour when it does overflow.

Signed-off-by: Ding Tianhong <>
fs/read_write.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/read_write.c b/fs/read_write.c
index f8547b8..2c377fc 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -105,7 +105,7 @@ loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize)
* like SEEK_SET.
- offset = vfs_setpos(file, file->f_pos + offset, maxsize);
+ offset = vfs_setpos(file, (u64)file->f_pos + offset, maxsize);
return offset;

 \ /
  Last update: 2017-12-07 14:21    [W:0.059 / U:2.592 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site