Messages in this thread | | | From | Dmitry Vyukov <> | Date | Thu, 9 Mar 2017 11:16:12 +0100 | Subject | Re: kasan behavior when built with unsupported compiler |
| |
On Thu, Mar 9, 2017 at 10:58 AM, Nikolay Borisov <n.borisov.lkml@gmail.com> wrote: > > > On 9.03.2017 11:46, Andrey Ryabinin wrote: >> On 03/08/2017 11:10 AM, Nikolay Borisov wrote: >> >>> >>> So apparently this is indeed a false positive, resulting from using the old >>> compiler. I used the attached patch to verify it. >>> >>> And what it prints is : >>> [ 17.184288] Assigned fbdev-blacklist.conff(ffff880001ea8020)20 whole object: ffff88006ae8fdb0 inode:ffff88006bff60d0 >>> [ 17.185808] Calling filldir with ffff88006ae8fdb0 >>> >>> So the first line essentially happens when the object ffff88006ae8fdb0 is >>> being allocated and the second when it's used in filldir. The warning in >>> ext4_ext_map_blocks doesn't trigger. However, if I remove the check for >>> the value of ext4_global_pointer then I see multiple lines such as: >>> [ 17.386283] ext4_ext_map_blocks:freeing pointer used in ext4_htree_store_dirent: ffff88006ae8fdb0 inode: ffff88006bff60d0 >>> [ 17.387601] Assigned fbdev-blacklist.conff(ffff880001eb3020)20 whole object: ffff88006ae8fdb0 inode:ffff88006bff60d0 >>> [ 17.388740] Calling filldir with ffff88006ae8fdb0 >>> >>> so that same object was used right before it is allocated again in >>> ext4_htree_store_dirent. And when you think about it it is logical since >>> before filling in the dentry names in ext4_htree_store_dirent ext4 has to fetch the >>> contents of the directory from disk. >>> >>> This leads me to believe that kasan is getting confused thinking that >>> the object is being freed >> >> As I said before, this is *not* use-after-free. It's out-of-bounds access. >> No, kasan is not confused, it doesn't think that object is freed. >> Object is allocated and kasan see it as allocated object. >> The problem is that filldir reads past the end of that allocated object. >> >> I don't see any sign that it's a false-positive. > > Okay in that case I will continue digging. So the name is indeed housed > at the end of the struct fname. In ext4_htree_store_dirent this > structure seems allocated correctly sizeof(struct fname) + ent_name->len > + 1; > > Also the read should indeed be 20 bytes since the filename in question > fbdev-blacklist.conf is indeed 20 bytes. This implies that the 'namlen' > passed to copy_to_user is also correct. I guess I will have to look at > the generated assembly between the 2 gcc versions and see if anything > pops out. > >> >> >>> AFTER being allocated in >>> ext4_htree_store_dirent but testing shows it's being freed BEFORE. So >>> I deem this a false positive, triggered by the compiler.
Looking at this report I don't see how this is OOB. Object starts at 0xffff88006a2255e0, object size is 69 bytes (from shadow). ffff88006a22560e + 20 bytes is not OOB.
BUG: KASAN: slab-out-of-bounds in filldir+0xc8/0x170 at addr ffff88006a22560e Read of size 20 by task systemd/1 ============================================================================= BUG kmalloc-96 (Not tainted): kasan: bad access detected -----------------------------------------------------------------------------
Disabling lock debugging due to kernel taint INFO: Allocated in ext4_htree_store_dirent+0x3e/0x120 age=0 cpu=2 pid=1 [< none >] ___slab_alloc+0x636/0x6a0 mm/slub.c:2446 [< none >] __slab_alloc+0x4f/0x86 mm/slub.c:2475 [< inline >] slab_alloc_node mm/slub.c:2538 [< inline >] slab_alloc mm/slub.c:2580 [< none >] __kmalloc+0x27a/0x340 mm/slub.c:3561 [< inline >] kmalloc include/linux/slab.h:483 [< inline >] kzalloc include/linux/slab.h:622 [< none >] ext4_htree_store_dirent+0x3e/0x120 fs/ext4/dir.c:447 [< none >] htree_dirblock_to_tree+0x16a/0x190 fs/ext4/namei.c:1001 [< none >] ext4_htree_fill_tree+0xaa/0x310 fs/ext4/namei.c:1075 [< inline >] ext4_dx_readdir fs/ext4/dir.c:571 [< none >] ext4_readdir+0x698/0x950 fs/ext4/dir.c:121 [< none >] iterate_dir+0x7d/0x190 fs/readdir.c:50 [< inline >] SYSC_getdents fs/readdir.c:230 [< none >] SyS_getdents+0x91/0x120 fs/readdir.c:212 [< none >] entry_SYSCALL_64_fastpath+0x23/0xc1 arch/x86/entry/entry_64.S:207
INFO: Freed in ext4_ext_map_blocks+0x7f9/0x23e0 age=1 cpu=2 pid=1 [< none >] __slab_free+0x31b/0x440 mm/slub.c:2657 [< inline >] slab_free mm/slub.c:2810 [< none >] kfree+0x27f/0x2d0 mm/slub.c:3662 [< none >] ext4_ext_map_blocks+0x7f9/0x23e0 fs/ext4/extents.c:4619 [< none >] ext4_map_blocks+0x3b4/0x5b0 fs/ext4/inode.c:529 [< none >] ext4_getblk+0x54/0x1a0 fs/ext4/inode.c:929 [< none >] ext4_bread+0x13/0x90 fs/ext4/inode.c:979 [< none >] __ext4_read_dirblock+0x3f/0x380 fs/ext4/namei.c:99 [< none >] htree_dirblock_to_tree+0x48/0x190 fs/ext4/namei.c:959 [< none >] ext4_htree_fill_tree+0xaa/0x310 fs/ext4/namei.c:1075 [< inline >] ext4_dx_readdir fs/ext4/dir.c:571 [< none >] ext4_readdir+0x698/0x950 fs/ext4/dir.c:121 [< none >] iterate_dir+0x7d/0x190 fs/readdir.c:50 [< inline >] SYSC_getdents fs/readdir.c:230 [< none >] SyS_getdents+0x91/0x120 fs/readdir.c:212 [< none >] entry_SYSCALL_64_fastpath+0x23/0xc1 arch/x86/entry/entry_64.S:207 INFO: Slab 0xffffea0001a88900 objects=20 used=17 fp=0xffff88006a224e10 flags=0x4080 INFO: Object 0xffff88006a2255e0 @offset=5600 fp=0x45b282a2484c60d4
Bytes b4 ffff88006a2255d0: 02 00 00 00 01 00 00 00 c9 ac fb ff 00 00 00 00 ................ Object ffff88006a2255e0: d4 60 4c 48 a2 82 b2 45 18 8a 82 6a 00 88 ff ff .`LH...E...j.... Object ffff88006a2255f0: 38 51 22 6a 00 88 ff ff 88 8b 82 6a 00 88 ff ff 8Q"j.......j.... Object ffff88006a225600: 00 00 00 00 00 00 00 00 28 03 08 00 14 01 66 62 ........(.....fb Object ffff88006a225610: 64 65 76 2d 62 6c 61 63 6b 6c 69 73 74 2e 63 6f dev-blacklist.co Object ffff88006a225620: 6e 66 00 00 00 00 00 00 00 00 00 00 00 00 00 00 nf.............. Object ffff88006a225630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ CPU: 2 PID: 1 Comm: systemd Tainted: G B 4.7.0-nbor #171 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 0000000000000000 ffff88006cd97c58 ffffffff8146bd4c ffff8800000946c0 ffff88006a2255e0 ffff88006cd97c88 ffffffff81198d96 ffff8800000946c0 ffffea0001a88900 ffff88006a2255e0 0000000000000000 ffff88006cd97cb0 Call Trace: [< inline >] __dump_stack lib/dump_stack.c:15 [<ffffffff8146bd4c>] dump_stack+0x85/0xc9 lib/dump_stack.c:51 [<ffffffff81198d96>] print_trailer+0x116/0x190 mm/slub.c:667 [<ffffffff811992c1>] object_err+0x41/0x50 mm/slub.c:674 [< inline >] print_address_description mm/kasan/report.c:180 [< inline >] kasan_report_error mm/kasan/report.c:276 [<ffffffff811a0a42>] kasan_report+0x282/0x530 mm/kasan/report.c:298 [< inline >] check_memory_region_inline mm/kasan/kasan.c:292 [<ffffffff8119ffa7>] check_memory_region+0x137/0x160 mm/kasan/kasan.c:299 [<ffffffff811a0041>] kasan_check_read+0x11/0x20 mm/kasan/kasan.c:304 [< inline >] copy_to_user ./arch/x86/include/asm/uaccess.h:760 [<ffffffff811ccc08>] filldir+0xc8/0x170 fs/readdir.c:195 [< inline >] dir_emit include/linux/fs.h:3134 [<ffffffff8124af38>] call_filldir+0x88/0x140 fs/ext4/dir.c:510 [< inline >] ext4_dx_readdir fs/ext4/dir.c:586 [<ffffffff8124b934>] ext4_readdir+0x714/0x950 fs/ext4/dir.c:121 [<ffffffff811ccd2d>] iterate_dir+0x7d/0x190 fs/readdir.c:50 [< inline >] SYSC_getdents fs/readdir.c:230 [<ffffffff811ccf71>] SyS_getdents+0x91/0x120 fs/readdir.c:212 [<ffffffff816d7d80>] entry_SYSCALL_64_fastpath+0x23/0xc1 arch/x86/entry/entry_64.S:207 Memory state around the buggy address: ffff88006a225500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff88006a225580: fc fc fc fc fc fc fc fc fc fc fc fc 00 00 00 00 >ffff88006a225600: 00 00 00 00 05 fc fc fc fc fc fc fc fc fc fc fc ^ ffff88006a225680: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc ffff88006a225700: fc fc fc fc fc fc fc fc fc fc fc fc fc fc 00 00
| |