- Overview out-of-bound write in ext4_init_block_bitmap() when mounting and operating a crafted ext4 image - Reproduce # mkdir mnt # mount -t ext4 53.img mnt # gcc -o poc poc.c # ./poc ./mnt - Kernel message [ 182.079600] EXT4-fs (loop0): mounted filesystem without journal. Opts: (null) [ 195.423650] BUG: unable to handle kernel paging request at ffff8801147bf000 [ 195.425469] PGD 8af40067 P4D 8af40067 PUD 8af43067 PMD 1146e0063 PTE 80000001147bf061 [ 195.427263] Oops: 0003 [#1] SMP KASAN PTI [ 195.428225] Modules linked in: snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd i2c_piix4 soundcore mac_hid ib_iser rdma_cm iw_cm ib_cm ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi autofs4 btrfs zstd_decompress zstd_compress xxhash raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq raid1 raid0 multipath linear 8139too qxl drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm drm crct10dif_pclmul crc32_pclmul aesni_intel aes_x86_64 crypto_simd cryptd glue_helper 8139cp mii floppy pata_acpi [ 195.439795] CPU: 0 PID: 1271 Comm: a.out Not tainted 4.17.0-rc4+ #4 [ 195.441172] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 [ 195.443268] RIP: 0010:ext4_read_block_bitmap_nowait+0x571/0xa40 [ 195.447872] RSP: 0018:ffff8801080ff0b0 EFLAGS: 00010206 [ 195.449041] RAX: 000000000009c000 RBX: ffff8801139db300 RCX: 0000000000000000 [ 195.450630] RDX: 0000000000000007 RSI: dffffc0000000000 RDI: ffff8801139dbbd4 [ 195.452241] RBP: ffff8801080ff140 R08: ffffed00228f5780 R09: ffff8801147ab800 [ 195.453817] R10: 0000000000000080 R11: ffffed00228f577f R12: ffff8801147ab800 [ 195.455405] R13: ffff8801147ab800 R14: ffff8801139dbb80 R15: 000000000009c001 [ 195.457013] FS: 00007f030c6c8700(0000) GS:ffff88011b000000(0000) knlGS:0000000000000000 [ 195.458825] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 195.460101] CR2: ffff8801147bf000 CR3: 000000010af9e000 CR4: 00000000000006f0 [ 195.461667] Call Trace: [ 195.462232] ext4_mb_init_cache+0x312/0xbd0 [ 195.463186] ? ext4_mb_generate_from_pa+0x220/0x220 [ 195.464298] ? pagecache_get_page+0xca/0x300 [ 195.465269] ext4_mb_init_group+0x255/0x380 [ 195.466225] ext4_mb_good_group+0x252/0x260 [ 195.467178] ext4_mb_regular_allocator+0x5ae/0x840 [ 195.468284] ? ext4_mb_complex_scan_group+0x4b0/0x4b0 [ 195.469409] ? kasan_kmalloc+0xad/0xe0 [ 195.470267] ? ext4_mb_use_preallocated.constprop.28+0x22/0x440 [ 195.471571] ext4_mb_new_blocks+0xc8c/0x15e0 [ 195.472521] ? ext4_xattr_block_find.isra.22+0x2c0/0x2c0 [ 195.473715] ? strlen+0x25/0x40 [ 195.474428] ext4_new_meta_blocks+0x1f9/0x210 [ 195.475417] ? ext4_should_retry_alloc+0xd0/0xd0 [ 195.476483] ? dquot_initialize_needed+0x4c/0x110 [ 195.477566] ext4_xattr_block_set+0xa7e/0x1820 [ 195.478578] ? ext4_xattr_inode_array_free+0x60/0x60 [ 195.479671] ? _cond_resched+0x1a/0x50 [ 195.480532] ? __getblk_gfp+0x31/0x3f0 [ 195.481370] ? __ext4_get_inode_loc+0x231/0x680 [ 195.482369] ? ext4_xattr_ibody_set+0x58/0x120 [ 195.483323] ext4_xattr_set_handle+0x64f/0x920 [ 195.484296] ? ext4_xattr_block_set+0x1820/0x1820 [ 195.485343] ? __dquot_initialize+0xeb/0x5d0 [ 195.486312] ? dqget+0x690/0x690 [ 195.487030] ? _cond_resched+0x1a/0x50 [ 195.487886] ? ext4_journal_check_start+0x77/0xd0 [ 195.488926] ? ext4_xattr_user_list+0x50/0x50 [ 195.489892] ext4_xattr_set+0x114/0x200 [ 195.490754] ? ext4_xattr_set_handle+0x920/0x920 [ 195.491811] ? legitimize_path.isra.28+0x61/0xa0 [ 195.492834] ? strncmp+0x3d/0xc0 [ 195.493555] ext4_xattr_user_set+0x71/0x80 [ 195.494495] __vfs_setxattr+0x7c/0xa0 [ 195.495313] __vfs_setxattr_noperm+0x8d/0x200 [ 195.496301] vfs_setxattr+0xb3/0xc0 [ 195.497089] setxattr+0x1b3/0x260 [ 195.497848] ? vfs_setxattr+0xc0/0xc0 [ 195.498666] ? filename_lookup+0x191/0x280 [ 195.499596] ? filename_parentat+0x2b0/0x2b0 [ 195.500547] ? kasan_kmalloc+0xad/0xe0 [ 195.501406] ? kasan_check_write+0x14/0x20 [ 195.502324] ? strncpy_from_user+0xa8/0x1c0 [ 195.503260] ? __mnt_is_readonly.part.13+0x23/0x30 [ 195.504325] ? __mnt_want_write+0x9d/0xb0 [ 195.505229] path_setxattr+0x134/0x170 [ 195.506066] ? setxattr+0x260/0x260 [ 195.506869] __x64_sys_setxattr+0x6d/0x80 [ 195.507782] do_syscall_64+0x78/0x170 [ 195.508599] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [ 195.509710] RIP: 0033:0x7f030c1e91fa [ 195.510507] RSP: 002b:00007ffe82cc4778 EFLAGS: 00000206 ORIG_RAX: 00000000000000bc [ 195.512183] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f030c1e91fa [ 195.513756] RDX: 00007ffe82cc4860 RSI: 0000000000401498 RDI: 00000000020290c0 [ 195.515310] RBP: 00007ffe82cc48e0 R08: 0000000000000001 R09: 0000000000000001 [ 195.516893] R10: 0000000000000071 R11: 0000000000000206 R12: 0000000000400c20 [ 195.518450] R13: 00007ffe82cc49e0 R14: 0000000000000000 R15: 0000000000000000 [ 195.520042] Code: ff 48 8b 7d a0 e8 c0 5c ed ff 48 8b 45 90 48 8b 7d 88 4c 8b 60 28 e8 af 5b ed ff 4c 89 f8 48 2b 45 98 41 8b 4e 54 48 d3 e8 48 98 <49> 0f ab 04 24 eb 9b 49 c7 c4 8b ff ff ff e9 65 fb ff ff 49 8b [ 195.524186] RIP: ext4_read_block_bitmap_nowait+0x571/0xa40 RSP: ffff8801080ff0b0 [ 195.525803] CR2: ffff8801147bf000 [ 195.526566] ---[ end trace 4883307b4e16d878 ]--- - Reason https://elixir.bootlin.com/linux/v4.17-rc5/source/fs/ext4/balloc.c#L236 tmp = ext4_inode_table(sb, gdp); for (; tmp < ext4_inode_table(sb, gdp) + sbi->s_itb_per_group; tmp++) { if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) ext4_set_bit(EXT4_B2C(sbi, tmp - start), bh->b_data); } out-of-bound accesses happen when setting block bitmap for inode table. tmp - start exceeds the boundary of bh->b_data. Found by Wen Xu from SSLab, Gatech.
Created attachment 276237 [details] The (compressed) crafted image which causes crash
Created attachment 276239 [details] poc.c
This is no longer replicating on the tip of my ext4.git tree: # /vdb/poc/do-865 [ 25.099634] attempt to access beyond end of device [ 25.101223] loop0: rw=0, want=255510, limit=16384 [ 25.103249] EXT2-fs (loop0): error: ext2_readdir: bad page in #2 [ 25.105162] EXT2-fs (loop0): error: remounting filesystem read-only [ 25.108074] attempt to access beyond end of device [ 25.109576] loop0: rw=0, want=255510, limit=16384
Never mind; I see my mistake; I needed to force the use of ext4. The file system doesn't trigger problems on ext2.
Oops, ignore comment #5; this erroneously posted to the wrong bug. Bug #199865 is triggered by the fact block group descriptors were corrupted due to the fact that one of the allocation bitmaps overlapped with the block group descriptors. Then when a block bitmap needed to be initialized, the corrupted block group descriptors resulted in the byte before the bitmap getting zero'ed. This will be fixed via these patches: ext4: always check block group bounds in ext4_init_block_bitmap() ext4: make sure bitmaps and the inode table don't overlap with bg descriptors
Patchwork links: http://patchwork.ozlabs.org/patch/929237/ http://patchwork.ozlabs.org/patch/929238/
This has been assigned CVE-2018-10878 Red Hat Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1596802