Size overflow detected in btrfs_real_readdir

Discuss and suggest new grsecurity features

Moderators: spender, PaX Team

Size overflow detected in btrfs_real_readdir

Postby Stebalien » Mon Oct 19, 2015 1:01 pm

When I enable CONFIG_PAX_SIZE_OVERFLOW in 4.2.3-201510190716, I get the following error:
PAX: size overflow detected in function btrfs_real_readdir fs/btrfs/inode.c:5759 cicus.1124_299 max, count: 57, decl: pos; num: 0; context: dir_context;

Followed by several:
PAX: size overflow detected in function btrfs_sync_file fs/btrfs/file.c:1871 cicus.677_110 max, count: 57289 decl: btrfs_wait_ordered_range; num: 3; context: fndecl;

And a kernel panic.

BTRFS Options:

Code: Select all
CONFIG_BTRFS_FS=y
CONFIG_BTRFS_FS_POSIX_ACL=y
# CONFIG_BTRFS_FS_CHECK_INTEGRITY is not set
# CONFIG_BTRFS_FS_RUN_SANITY_TESTS is not set
# CONFIG_BTRFS_DEBUG is not set
# CONFIG_BTRFS_ASSERT is not set


Grsecurity Options:

Code: Select all
CONFIG_PAX_KERNEXEC_PLUGIN=y
CONFIG_PAX_PER_CPU_PGD=y
CONFIG_PAX_USERCOPY_SLABS=y
CONFIG_GRKERNSEC=y
# CONFIG_GRKERNSEC_CONFIG_AUTO is not set
CONFIG_GRKERNSEC_CONFIG_CUSTOM=y
CONFIG_GRKERNSEC_TPE_UNTRUSTED_GID=612
CONFIG_PAX=y
# CONFIG_PAX_SOFTMODE is not set
# CONFIG_PAX_EI_PAX is not set
# CONFIG_PAX_PT_PAX_FLAGS is not set
CONFIG_PAX_XATTR_PAX_FLAGS=y
CONFIG_PAX_NO_ACL_FLAGS=y
# CONFIG_PAX_HAVE_ACL_FLAGS is not set
# CONFIG_PAX_HOOK_ACL_FLAGS is not set
CONFIG_PAX_NOEXEC=y
CONFIG_PAX_PAGEEXEC=y
CONFIG_PAX_EMUTRAMP=y
CONFIG_PAX_MPROTECT=y
# CONFIG_PAX_MPROTECT_COMPAT is not set
# CONFIG_PAX_ELFRELOCS is not set
CONFIG_PAX_KERNEXEC=y
CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_BTS=y
# CONFIG_PAX_KERNEXEC_PLUGIN_METHOD_OR is not set
CONFIG_PAX_KERNEXEC_PLUGIN_METHOD="bts"
CONFIG_PAX_ASLR=y
CONFIG_PAX_RANDKSTACK=y
CONFIG_PAX_RANDUSTACK=y
CONFIG_PAX_RANDMMAP=y
# CONFIG_PAX_MEMORY_SANITIZE is not set
# CONFIG_PAX_MEMORY_STACKLEAK is not set
# CONFIG_PAX_MEMORY_STRUCTLEAK is not set
CONFIG_PAX_MEMORY_UDEREF=y
CONFIG_PAX_REFCOUNT=y
CONFIG_PAX_CONSTIFY_PLUGIN=y
CONFIG_PAX_USERCOPY=y
# CONFIG_PAX_USERCOPY_DEBUG is not set
# CONFIG_PAX_LATENT_ENTROPY is not set
CONFIG_GRKERNSEC_KMEM=y
CONFIG_GRKERNSEC_IO=y
CONFIG_GRKERNSEC_BPF_HARDEN=y
CONFIG_GRKERNSEC_PERF_HARDEN=y
CONFIG_GRKERNSEC_RAND_THREADSTACK=y
CONFIG_GRKERNSEC_PROC_MEMMAP=y
CONFIG_GRKERNSEC_KSTACKOVERFLOW=y
CONFIG_GRKERNSEC_BRUTE=y
# CONFIG_GRKERNSEC_MODHARDEN is not set
CONFIG_GRKERNSEC_HIDESYM=y
# CONFIG_GRKERNSEC_RANDSTRUCT is not set
CONFIG_GRKERNSEC_KERN_LOCKOUT=y
CONFIG_GRKERNSEC_NO_RBAC=y
# CONFIG_GRKERNSEC_ACL_HIDEKERN is not set
CONFIG_GRKERNSEC_ACL_MAXTRIES=3
CONFIG_GRKERNSEC_ACL_TIMEOUT=30
# CONFIG_GRKERNSEC_PROC is not set
# CONFIG_GRKERNSEC_LINK is not set
# CONFIG_GRKERNSEC_SYMLINKOWN is not set
CONFIG_GRKERNSEC_FIFO=y
# CONFIG_GRKERNSEC_SYSFS_RESTRICT is not set
# CONFIG_GRKERNSEC_ROFS is not set
CONFIG_GRKERNSEC_DEVICE_SIDECHANNEL=y
CONFIG_GRKERNSEC_CHROOT=y
# CONFIG_GRKERNSEC_CHROOT_MOUNT is not set
# CONFIG_GRKERNSEC_CHROOT_DOUBLE is not set
# CONFIG_GRKERNSEC_CHROOT_PIVOT is not set
# CONFIG_GRKERNSEC_CHROOT_CHDIR is not set
# CONFIG_GRKERNSEC_CHROOT_CHMOD is not set
CONFIG_GRKERNSEC_CHROOT_FCHDIR=y
CONFIG_GRKERNSEC_CHROOT_MKNOD=y
CONFIG_GRKERNSEC_CHROOT_SHMAT=y
# CONFIG_GRKERNSEC_CHROOT_UNIX is not set
# CONFIG_GRKERNSEC_CHROOT_FINDTASK is not set
# CONFIG_GRKERNSEC_CHROOT_NICE is not set
CONFIG_GRKERNSEC_CHROOT_SYSCTL=y
CONFIG_GRKERNSEC_CHROOT_RENAME=y
# CONFIG_GRKERNSEC_CHROOT_CAPS is not set
# CONFIG_GRKERNSEC_AUDIT_GROUP is not set
# CONFIG_GRKERNSEC_EXECLOG is not set
CONFIG_GRKERNSEC_RESLOG=y
# CONFIG_GRKERNSEC_CHROOT_EXECLOG is not set
CONFIG_GRKERNSEC_AUDIT_PTRACE=y
# CONFIG_GRKERNSEC_AUDIT_CHDIR is not set
# CONFIG_GRKERNSEC_AUDIT_MOUNT is not set
CONFIG_GRKERNSEC_SIGNAL=y
CONFIG_GRKERNSEC_FORKFAIL=y
# CONFIG_GRKERNSEC_TIME is not set
# CONFIG_GRKERNSEC_PROC_IPADDR is not set
CONFIG_GRKERNSEC_RWXMAP_LOG=y
# CONFIG_GRKERNSEC_DMESG is not set
CONFIG_GRKERNSEC_HARDEN_PTRACE=y
CONFIG_GRKERNSEC_PTRACE_READEXEC=y
# CONFIG_GRKERNSEC_SETXID is not set
CONFIG_GRKERNSEC_HARDEN_IPC=y
CONFIG_GRKERNSEC_TPE=y
CONFIG_GRKERNSEC_TPE_ALL=y
# CONFIG_GRKERNSEC_TPE_INVERT is not set
CONFIG_GRKERNSEC_TPE_GID=612
CONFIG_GRKERNSEC_BLACKHOLE=y
CONFIG_GRKERNSEC_NO_SIMULT_CONNECT=y
# CONFIG_GRKERNSEC_SOCKET is not set
# CONFIG_GRKERNSEC_DENYUSB is not set
CONFIG_GRKERNSEC_SYSCTL=y
# CONFIG_GRKERNSEC_SYSCTL_DISTRO is not set
CONFIG_GRKERNSEC_SYSCTL_ON=y
CONFIG_GRKERNSEC_FLOODTIME=10
CONFIG_GRKERNSEC_FLOODBURST=6
Stebalien
 
Posts: 6
Joined: Tue Mar 12, 2013 6:02 pm

Re: Size overflow detected in btrfs_real_readdir

Postby ephox » Mon Oct 19, 2015 6:30 pm

Hi,

Thanks for report. These are real bugs, you should report them to the btrfs kernel mailing list.

First bug: fs/btrfs/inode.c:5759
This patch writes out the pos value that will overflow after the increment:
Code: Select all
--- fs/btrfs/inode.c.orig       2015-10-18 14:33:04.674254062 +0200
+++ fs/btrfs/inode.c    2015-10-18 14:33:38.322252562 +0200
@@ -5756,6 +5756,7 @@
        }
 
        /* Reached end of directory/root. Bump pos past the last item. */
+       printk(KERN_ERR "Overflow: %llx\n", ctx->pos);
        ctx->pos++;
 
        /*

Send the printed value and the btrfs developers will see the overflow.

Second bug: fs/btrfs/file.c:1871
len = end - start + 1

vfs_fsync calls vfs_fsync_range with 0 and LLONG_MAX for start and end.
In btrfs_sync_file the above expression causes a signed overflow (undefined behaviour) with these values.
ephox
 
Posts: 134
Joined: Tue Mar 20, 2012 4:36 pm

Re: Size overflow detected in btrfs_real_readdir

Postby alan.d » Sun Oct 25, 2015 9:17 am

Has this been reported to the btrfs devs yet? If yes, could you please link to it?
I could only report the second issue, I do not observe the first one. I guess for the second issue, the following information is enough?

Second bug: fs/btrfs/file.c:1871
len = end - start + 1

vfs_fsync calls vfs_fsync_range with 0 and LLONG_MAX for start and end.
In btrfs_sync_file the above expression causes a signed overflow (undefined behaviour) with these values.
alan.d
 
Posts: 34
Joined: Mon Jul 07, 2014 8:20 am

Re: Size overflow detected in btrfs_real_readdir

Postby ephox » Sun Oct 25, 2015 9:34 am

ephox
 
Posts: 134
Joined: Tue Mar 20, 2012 4:36 pm

Re: Size overflow detected in btrfs_real_readdir

Postby kdave » Mon Nov 09, 2015 6:53 am

Fix for the overflow in btrfs_sync_file sent upstream, https://patchwork.kernel.org/patch/7582351/ .
kdave
 
Posts: 11
Joined: Mon Oct 19, 2015 5:35 pm

Re: Size overflow detected in btrfs_real_readdir

Postby PaX Team » Mon Nov 09, 2015 8:21 am

cool, we'll have it in the next patch. what about the first bug, is there a patch for that as well perhaps? (i didn't get any replies from the btrfs list)
PaX Team
 
Posts: 2310
Joined: Mon Mar 18, 2002 4:35 pm

Re: Size overflow detected in btrfs_real_readdir

Postby kdave » Mon Nov 09, 2015 10:09 am

I'm working on it right now, the overflow itself seems harmless, the value is reset to LLONG_MAX afterwards, which is enough to stop readdir. There were some concerns regarding compatibility with 32bit apps, I'm rereading the original discussions.
kdave
 
Posts: 11
Joined: Mon Oct 19, 2015 5:35 pm

Re: Size overflow detected in btrfs_real_readdir

Postby PaX Team » Mon Nov 09, 2015 10:32 am

hmm, where does the reset to LLONG_MAX happen? if you mean line 5781 (in 4.2.5, give or take) then that code is under a conditional check (key_type == BTRFS_DIR_INDEX_KEY, but the signed overflow may not occur when it's false, i don't know), and the ctx->pos >= INT_MAX check will fail since the overflow will produce LLONG_MIN so the reset would be to INT_MAX instead (which may or may not be desirable).
PaX Team
 
Posts: 2310
Joined: Mon Mar 18, 2002 4:35 pm

Re: Size overflow detected in btrfs_real_readdir

Postby kdave » Mon Nov 09, 2015 1:36 pm

The section with "ctx->pos++" is called twice, once when the last readdir emits some entries (sets pos to INT_MAX) and according to strace again where it retuns no entries, but still bumps, going from INT_MAX to LLONG_MAX.

[13810.607107] emit 201
[13810.607107] emitted
[13810.607108] DBG: pos 201
[13810.607108] DBG: (pre) pos 202
[13810.607109] DBG: (post) pos 203
[13810.607110] DBG: last pos 2147483647
[13810.607299] DBG: pos at the start 2147483647
[13810.607303] !emitted
[13810.607304] DBG: pos 2147483647
[13810.607304] DBG: (pre) pos 2147483647
[13810.607305] DBG: (post) pos 2147483648
[13810.607306] DBG: last pos 9223372036854775807


What you describe, I've reliably reproduced when 'pos' is larger than INT_MAX from regular entries, then it's first set to LLONG_MAX, overflows to LLONG_MIN and then is set to INT_MAX:

[13500.982658] emit 4294967495
[13500.982658] emitted
[13500.982659] DBG: pos 4294967495
[13500.982660] DBG: (pre) pos 4294967496
[13500.982660] DBG: (post) pos 4294967497
[13500.982661] DBG: last pos 9223372036854775807
[13500.997339] DBG: pos at the start 9223372036854775807
[13500.997345] !emitted
[13500.997346] DBG: pos 9223372036854775807
[13500.997347] DBG: (pre) pos 9223372036854775807
[13500.997347] DBG: (post) pos -9223372036854775808
[13500.997348] DBG: last pos 2147483647


I'm still not sure how it could happen without artificially setting the pos to be larger than INT_MAX, but according to the logs provided by Victor at http://pastebin.com/S9gjYpYX it is possible.

The fix https://patchwork.kernel.org/patch/7585611/.
kdave
 
Posts: 11
Joined: Mon Oct 19, 2015 5:35 pm

Re: Size overflow detected in btrfs_real_readdir

Postby kdave » Thu Nov 12, 2015 4:20 am

FYI, we have reports that the patch for btrfs_real_readdir is buggy and may cause hangs.
kdave
 
Posts: 11
Joined: Mon Oct 19, 2015 5:35 pm

Re: Size overflow detected in btrfs_real_readdir

Postby spender » Thu Nov 12, 2015 8:50 pm

spender
 
Posts: 2184
Joined: Wed Feb 20, 2002 8:00 pm
Location: VA, USA

Re: Size overflow detected in btrfs_real_readdir

Postby kdave » Fri Nov 13, 2015 2:12 pm

Updated fix, https://patchwork.kernel.org/patch/7611351/ also tested by a reporter of v1 issues.

spender wrote:It seems that code has a history of problems:


Yeah, the 'ctx->pos and 0x7f... tricks' approach looks less fragile to me than the proposed 'f_version' approach. I've tested the 32 to 64 bit overflow on ctx->pos, works as expected.
kdave
 
Posts: 11
Joined: Mon Oct 19, 2015 5:35 pm

Re: Size overflow detected in btrfs_real_readdir

Postby Dwokfur » Fri Dec 18, 2015 7:53 pm

Dwokfur
 
Posts: 99
Joined: Tue Jun 08, 2004 10:07 am
Location: Budapest, Hungary, Europe


Return to grsecurity development