Bug 199423

Summary: Invalid pointer dereference in xfs_bmapi_write() when mounting and operating a crafted xfs image
Product: File System Reporter: Wen Xu (wen.xu)
Component: XFSAssignee: Eric Sandeen (sandeen)
Status: RESOLVED CODE_FIX    
Severity: normal CC: sandeen, wen.xu
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 4.16, 4.17 Subsystem:
Regression: No Bisected commit-id:
Attachments: The (compressed) crafted image which causes crash
poc.c
Kernel config

Description Wen Xu 2018-04-17 02:00:50 UTC
Created attachment 275419 [details]
The (compressed) crafted image which causes crash

- Overview
Invalid pointer dereference triggered in xfs_bmapi_write() when mounting and operating a crafted xfs image

- Reproduce (4.17/4.16)
# mkdir mnt
# mount -t xfs 91.img mnt
# gcc -o poc poc.c
# ./poc ./mnt

- Location
https://elixir.bootlin.com/linux/latest/source/fs/xfs/libxfs/xfs_bmap.c#L4311
ifp->if_broot can be NULL

- Kernel Message
[  140.484390] XFS (loop0): Mounting V4 Filesystem
[  140.489148] XFS (loop0): Ending clean mount
[  146.282828] XFS (loop0): Metadata corruption detected at xfs_agf_verify+0x3f/0x240, xfs_agf block 0x1
[  146.284321] XFS (loop0): Unmount and run xfs_repair
[  146.285097] XFS (loop0): First 128 bytes of corrupted metadata buffer:
[  146.286105] 00000000d6c493ab: 58 41 47 46 00 20 00 01 00 00 00 00 00 00 10 00  XAGF. ..........
[  146.287411] 000000003ba15879: 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 01  ................
[  146.288756] 00000000c77d12a0: 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 03  ................
[  146.292162] 000000002a3fa47c: 00 00 00 04 00 00 0c 80 00 00 0c 80 00 00 00 00  ................
[  146.293540] 000000006d1fa685: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
[  146.294851] 00000000307ee9c1: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
[  146.296154] 000000001facf664: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
[  146.297498] 00000000c2a6f52a: 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
[  146.298880] XFS (loop0): metadata I/O error in "xfs_trans_read_buf_map" at daddr 0x1 len 1 error 117
[  146.300343] XFS (loop0): page discard on page 0000000058c10cfb, inode 0x6c1, offset 0.
[  146.301953] XFS (loop0): Metadata corruption detected at xfs_agf_verify+0x3f/0x240, xfs_agf block 0x1
[  146.303363] XFS (loop0): Unmount and run xfs_repair
[  146.304111] XFS (loop0): First 128 bytes of corrupted metadata buffer:
[  146.305150] 00000000d6c493ab: 58 41 47 46 00 20 00 01 00 00 00 00 00 00 10 00  XAGF. ..........
[  146.306481] 000000003ba15879: 00 00 00 01 00 00 00 02 00 00 00 00 00 00 00 01  ................
[  146.307798] 00000000c77d12a0: 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 03  ................
[  146.309148] 000000002a3fa47c: 00 00 00 04 00 00 0c 80 00 00 0c 80 00 00 00 00  ................
[  146.310470] 000000006d1fa685: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
[  146.311784] 00000000307ee9c1: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
[  146.313136] 000000001facf664: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
[  146.314465] 00000000c2a6f52a: 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
[  146.315788] XFS (loop0): metadata I/O error in "xfs_trans_read_buf_map" at daddr 0x1 len 1 error 117
[  146.317232] XFS (loop0): page discard unable to remove delalloc mapping.
[  146.318460] BUG: unable to handle kernel NULL pointer dereference at 0000000000000004
[  146.319661] PGD 800000023065c067 P4D 800000023065c067 PUD 22f5f4067 PMD 0
[  146.320721] Oops: 0000 [#1] SMP PTI
[  146.321296] Modules linked in: snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd soundcore i2c_piix4 mac_hid ib_iser rdma_cm iw_cm ib_cm ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi autofs4 raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx raid1 raid0 multipath linear qxl crct10dif_pclmul crc32_pclmul drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm aesni_intel drm aes_x86_64 crypto_simd cryptd glue_helper 8139too floppy 8139cp pata_acpi mii
[  146.328673] CPU: 0 PID: 1301 Comm: p Not tainted 4.17.0-rc1 #3
[  146.329570] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[  146.331004] RIP: 0010:xfs_bmapi_write+0x9b2/0xcc0
[  146.331724] RSP: 0018:ffffb35641237768 EFLAGS: 00010202
[  146.332521] RAX: 0000000000000000 RBX: 0000000000000400 RCX: 0000000000000000
[  146.333602] RDX: 0000000000000000 RSI: ffff8b0ff434cf00 RDI: ffff8b0ff567c000
[  146.334670] RBP: ffffb356412378e0 R08: 0000000000000400 R09: ffffb35641237950
[  146.335739] R10: ffffb356412378f0 R11: ffff8b0ff5623b58 R12: 0000000000000004
[  146.336810] R13: 0000000000000000 R14: ffffb35641237960 R15: ffffb356412377f8
[  146.337887] FS:  00007f1786da2700(0000) GS:ffff8b0fffc00000(0000) knlGS:0000000000000000
[  146.339100] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  146.339967] CR2: 0000000000000004 CR3: 0000000234e40000 CR4: 00000000000006f0
[  146.341057] Call Trace:
[  146.341476]  ? kmem_zone_alloc+0x8f/0x110
[  146.342101]  xfs_iomap_write_allocate+0x19f/0x3c0
[  146.342830]  xfs_map_blocks+0x208/0x280
[  146.343426]  xfs_do_writepage+0x26e/0x6a0
[  146.344066]  ? clear_page_dirty_for_io+0x217/0x2a0
[  146.344801]  write_cache_pages+0x225/0x4b0
[  146.345449]  ? xfs_add_to_ioend+0x250/0x250
[  146.346116]  ? generic_write_end+0x82/0xb0
[  146.346750]  xfs_vm_writepages+0x6b/0xa0
[  146.347356]  do_writepages+0x1f/0x70
[  146.347921]  __filemap_fdatawrite_range+0xc6/0x100
[  146.348654]  file_write_and_wait_range+0x5a/0xb0
[  146.349376]  xfs_file_fsync+0x67/0x230
[  146.349960]  vfs_fsync_range+0x48/0x80
[  146.350541]  xfs_file_write_iter+0x126/0x150
[  146.351213]  __vfs_write+0xfc/0x170
[  146.351756]  vfs_write+0xb8/0x1b0
[  146.352273]  ksys_write+0x55/0xc0
[  146.352791]  __x64_sys_write+0x1a/0x20
[  146.353399]  do_syscall_64+0x5a/0x110
[  146.353988]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  146.354779] RIP: 0033:0x7f17868b42c0
[  146.355330] RSP: 002b:00007ffd51a76568 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
[  146.356470] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f17868b42c0
[  146.357553] RDX: 0000000000008000 RSI: 00000000006010a0 RDI: 0000000000000003
[  146.358626] RBP: 00007ffd51a765a0 R08: 00000000011fc010 R09: 0000000000000000
[  146.359697] R10: 000000000000086f R11: 0000000000000246 R12: 0000000000400610
[  146.360770] R13: 00007ffd51a766a0 R14: 0000000000000000 R15: 0000000000000000
[  146.361848] Code: 45 85 ed 74 71 83 bd bc fe ff ff 01 0f 84 b2 02 00 00 83 b8 34 01 00 00 03 0f 94 c0 84 c0 74 64 48 8b 85 e0 fe ff ff 48 8b 40 08 <0f> b7 40 04 66 c1 c0 08 0f b7 c0 83 c0 01 89 45 b8 e9 d3 f7 ff
[  146.364693] RIP: xfs_bmapi_write+0x9b2/0xcc0 RSP: ffffb35641237768
[  146.365638] CR2: 0000000000000004
[  146.366215] ---[ end trace 44b40574f882ce7c ]---

Reported by Wen Xu at SSlab, Gatech
Comment 1 Wen Xu 2018-04-17 02:01:05 UTC
Created attachment 275421 [details]
poc.c
Comment 2 Wen Xu 2018-04-17 02:01:27 UTC
Created attachment 275423 [details]
Kernel config
Comment 3 Eric Sandeen 2018-04-17 04:36:39 UTC
[PATCH] xfs: set format back to extents if xfs_bmap_extents_to_btree fails
Comment 4 Eric Sandeen 2018-04-18 03:04:28 UTC
If xfs_bmap_extents_to_btree fails in a mode where we call
xfs_iroot_realloc(-1) to de-allocate the root, set the
format back to extents.

Otherwise we can assume we can dereference ifp->if_broot
based on the XFS_DINODE_FMT_BTREE format, and crash.