size overflow detected in function truncate_pagecache
Posted: Sun Mar 20, 2016 10:34 am
Hello,
while building coreutils in a Docker container I got on the host (x86-64 CPU running with grsecurity-3.1-4.4.6-201603171922.patch) the following lines in dmesg:
The process which is reported as hung (here "chmod") then becomes unkillable.
Adding a test in truncate_pagecache function shows that it is called with new_size=0x7fffffffffffffff, so "holebegin = round_up(newsize, PAGE_SIZE)" overflows (in https://github.com/minipli/linux-grsec/ ... ate.c#L673 ). Indeed to reproduce the overflow, this command is enough, on an XFS filesystem:
(This is what tests/dd/skip-seek-past-file.sh does in coreutils, which triggered the first overflow I have seen).
On ext4 the truncate command fails with "truncate: failed to truncate 'in' at 9223372036854775807 bytes: File too large" without causing any integer overflow. Therefore this issue may be specific to XFS.
while building coreutils in a Docker container I got on the host (x86-64 CPU running with grsecurity-3.1-4.4.6-201603171922.patch) the following lines in dmesg:
- Code: Select all
[ 1201.560188] PAX: size overflow detected in function truncate_pagecache mm/truncate.c:673 cicus.164_14 max, count: 13, decl: unmap_mapping_range; num: 2; context: fndecl;
[ 1201.560194] CPU: 7 PID: 3283 Comm: truncate Tainted: G O 4.4.6.201603171922-1-grsec-selinux #1
[ 1201.560195] Hardware name: Notebook W740SU /W740SU , BIOS 4.6.5 09/11/2014
[ 1201.560197] 5dc081da00000002 5dc081daebccabf3 0000000000000286 0000000000000000
[ 1201.560200] ffffc90015983cf0 ffffffffa12fe63b 0000000000000001 5dc081daebccabf3
[ 1201.560203] ffffffffa18ff322 00000000000002a1 ffffc90015983d20 ffffffffa11c3b0c
[ 1201.560205] Call Trace:
[ 1201.560211] [<ffffffffa12fe63b>] dump_stack+0x76/0xbb
[ 1201.560214] [<ffffffffa11c3b0c>] report_size_overflow+0x6c/0x80
[ 1201.560217] [<ffffffffa114937b>] truncate_pagecache+0x6b/0x180
[ 1201.560219] [<ffffffffa11494c0>] truncate_setsize+0x30/0x40
[ 1201.560236] [<ffffffffc0b084f1>] xfs_setattr_size+0x131/0x380 [xfs]
[ 1201.560247] [<ffffffffc0b087fa>] xfs_vn_setattr+0xba/0xd0 [xfs]
[ 1201.560250] [<ffffffffa11dedd9>] notify_change+0x219/0x360
[ 1201.560253] [<ffffffffa11b99d0>] do_truncate+0x80/0xd0
[ 1201.560255] [<ffffffffa11b9dba>] do_sys_ftruncate.constprop.2+0x12a/0x180
[ 1201.560258] [<ffffffffa11b9e87>] SyS_ftruncate+0x17/0x30
[ 1201.560261] [<ffffffffa161ceb0>] entry_SYSCALL_64_fastpath+0x12/0x86
[ 1440.503238] INFO: task chmod:3308 blocked for more than 120 seconds.
[ 1440.503243] Tainted: G O 4.4.6.201603171922-1-grsec-selinux #1
[ 1440.503244] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[ 1440.503247] chmod D ffffc90015a53da8 0 3308 2944 0x00000080
[ 1440.503251] ffffc90015a53da8 ffffc90015a53ef8 ffffc90015a53d60 ffffffffa11cf085
[ 1440.503253] ffff88040d9d1500 ffff88036bdcbf00 ffff88036afcacf8 ffffc90015a53dd0
[ 1440.503255] 1306b8cb7788ddec ffff88036bdcc930 ffff88036afcacfc ffff88036bdcbf00
[ 1440.503258] Call Trace:
[ 1440.503265] [<ffffffffa11cf085>] ? putname+0x55/0x60
[ 1440.503270] [<ffffffffa1618967>] schedule+0x37/0x90
[ 1440.503274] [<ffffffffa1618d60>] schedule_preempt_disabled+0x10/0x20
[ 1440.503277] [<ffffffffa1619b4a>] __mutex_lock_slowpath+0xda/0x160
[ 1440.503279] [<ffffffffa16198f2>] mutex_lock+0x22/0x40
[ 1440.503283] [<ffffffffa11b8ffc>] chmod_common+0x5c/0x1b0
[ 1440.503285] [<ffffffffa11cf0fd>] ? getname_flags+0x6d/0x1f0
[ 1440.503288] [<ffffffffa11cf70b>] ? user_path_at_empty+0x3b/0x50
[ 1440.503290] [<ffffffffa11ba588>] SyS_fchmodat+0x58/0xc0
[ 1440.503292] [<ffffffffa161ceb0>] entry_SYSCALL_64_fastpath+0x12/0x86
The process which is reported as hung (here "chmod") then becomes unkillable.
Adding a test in truncate_pagecache function shows that it is called with new_size=0x7fffffffffffffff, so "holebegin = round_up(newsize, PAGE_SIZE)" overflows (in https://github.com/minipli/linux-grsec/ ... ate.c#L673 ). Indeed to reproduce the overflow, this command is enough, on an XFS filesystem:
- Code: Select all
truncate --size=9223372036854775807 filename
(This is what tests/dd/skip-seek-past-file.sh does in coreutils, which triggered the first overflow I have seen).
On ext4 the truncate command fails with "truncate: failed to truncate 'in' at 9223372036854775807 bytes: File too large" without causing any integer overflow. Therefore this issue may be specific to XFS.