Bug 199377

Summary: Invalid pointer dereference in xfs_ilock_attr_map_shared() 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.x, 4.15.x Tree: Mainline
Regression: No
Attachments: The (compressed) crafted image which causes crash
poc.c

Description Wen Xu 2018-04-12 03:23:09 UTC
Created attachment 275327 [details]
The (compressed) crafted image which causes crash

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

- Reproduce
# mkdir mnt
# mount -t xfs 120.img mnt
# gcc -o poc poc.c
# ./poc ./mnt

- Reason
static int
xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
		struct inode *inode, const char *name, void *value, size_t size)
{
	int xflags = handler->flags;
	struct xfs_inode *ip = XFS_I(inode);
	int error, asize = size;

	/* Convert Linux syscall to XFS internal ATTR flags */
	if (!size) {
		xflags |= ATTR_KERNOVAL;
		value = NULL;
	}

	error = xfs_attr_get(ip, (unsigned char *)name, value, &asize, xflags);
	if (error)
		return error;
	return asize;
}

ip is invalid (0x8) returned from XFS_I. 

- KASAN report
[  113.423036] XFS (loop0): Mounting V4 Filesystem
[  113.437776] XFS (loop0): Ending clean mount
[  118.235107] ==================================================================
[  118.236472] BUG: KASAN: null-ptr-deref in xfs_ilock_attr_map_shared+0x49/0x70
[  118.237601] Read of size 1 at addr 0000000000000012 by task poc/1428

[  118.238905] CPU: 0 PID: 1428 Comm: poc Not tainted 4.16.0-rc1+ #2
[  118.238929] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[  118.238955] Call Trace:
[  118.239027]  dump_stack+0x5c/0x86
[  118.239091]  kasan_report+0x108/0x390
[  118.239098]  ? xfs_ilock_attr_map_shared+0x49/0x70
[  118.239104]  xfs_ilock_attr_map_shared+0x49/0x70
[  118.239149]  xfs_attr_get+0x185/0x210
[  118.239156]  ? xfs_attr_get_ilocked+0x90/0x90
[  118.239205]  ? entry_SYSCALL_64_after_hwframe+0x21/0x86
[  118.239254]  ? unlazy_walk+0xb4/0x150
[  118.239260]  ? terminate_walk+0xcf/0x1e0
[  118.239266]  xfs_xattr_get+0xac/0x100
[  118.239271]  ? xfs_trans_roll+0x120/0x120
[  118.239275]  ? path_parentat+0xa0/0xa0
[  118.239373]  ? fsnotify+0xd4/0x700
[  118.239378]  ? path_parentat+0xa0/0xa0
[  118.239404]  ? xattr_resolve_name+0xff/0x190
[  118.239410]  __vfs_getxattr+0x61/0x80
[  118.239427]  cap_inode_need_killpriv+0x2a/0x40
[  118.239465]  security_inode_need_killpriv+0x45/0x60
[  118.239472]  notify_change+0x2d7/0x670
[  118.239478]  ? chown_common+0x276/0x310
[  118.239481]  chown_common+0x276/0x310
[  118.239486]  ? chmod_common+0x260/0x260
[  118.239511]  ? kasan_kmalloc+0xa6/0xd0
[  118.239518]  ? getname_flags+0x101/0x2b0
[  118.239522]  ? getname_flags+0x101/0x2b0
[  118.239527]  ? __mnt_is_readonly.part.13+0x1f/0x30
[  118.239531]  ? __mnt_want_write+0x98/0xb0
[  118.239535]  SyS_chown+0x102/0x140
[  118.239540]  ? SyS_fchownat+0x180/0x180
[  118.239543]  ? SyS_fchmodat+0x110/0x110
[  118.239603]  ? spurious_fault+0x2f0/0x2f0
[  118.239609]  ? SyS_fchownat+0x180/0x180
[  118.239623]  do_syscall_64+0xe9/0x1f0
[  118.239630]  entry_SYSCALL_64_after_hwframe+0x21/0x86
[  118.239648] RIP: 0033:0x7f7134b85307
[  118.239651] RSP: 002b:00007ffeb2eabc28 EFLAGS: 00000206 ORIG_RAX: 000000000000005c
[  118.239677] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f7134b85307
[  118.239680] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 000000000129d0a0
[  118.239682] RBP: 00007ffeb2eabd90 R08: 0000000000000003 R09: 0000000000000000
[  118.239684] R10: 0000000000000610 R11: 0000000000000206 R12: 0000000000400c20
[  118.239686] R13: 00007ffeb2eabe90 R14: 0000000000000000 R15: 0000000000000000
[  118.239690] ==================================================================
[  118.240840] Disabling lock debugging due to kernel taint
[  118.242560] BUG: unable to handle kernel NULL pointer dereference at 0000000000000012
[  118.243972] IP: xfs_ilock_attr_map_shared+0x49/0x70
[  118.244755] PGD 800000006163f067 P4D 800000006163f067 PUD 6b98e067 PMD 0 
[  118.245827] Oops: 0000 [#1] SMP KASAN PTI
[  118.246533] 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 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 pata_acpi mii floppy
[  118.255115] CPU: 1 PID: 1428 Comm: poc Tainted: G    B            4.16.0-rc1+ #2
[  118.256274] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[  118.257753] RIP: 0010:xfs_ilock_attr_map_shared+0x49/0x70
[  118.258606] RSP: 0018:ffff880067927a88 EFLAGS: 00010296
[  118.259440] RAX: 0000000000000000 RBX: ffff8800667e1100 RCX: 0000000000000000
[  118.260556] RDX: 0000000000000000 RSI: 0000000000000297 RDI: 0000000000000297
[  118.261669] RBP: 0000000000000000 R08: fffffbfff0924d26 R09: ffffffff84926964
[  118.262791] R10: 0000000000000001 R11: fffffbfff0924d25 R12: 1ffff1000cf24f56
[  118.263911] R13: ffff880067927be8 R14: ffff880068a00000 R15: ffffffff83590589
[  118.265038] FS:  00007f7135072700(0000) GS:ffff88006cf00000(0000) knlGS:0000000000000000
[  118.266316] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  118.267234] CR2: 00000000017b3808 CR3: 000000003569a000 CR4: 00000000000006e0
[  118.268361] Call Trace:
[  118.268774]  xfs_attr_get+0x185/0x210
[  118.269371]  ? xfs_attr_get_ilocked+0x90/0x90
[  118.270074]  ? entry_SYSCALL_64_after_hwframe+0x21/0x86
[  118.270926]  ? unlazy_walk+0xb4/0x150
[  118.271523]  ? terminate_walk+0xcf/0x1e0
[  118.272159]  xfs_xattr_get+0xac/0x100
[  118.272756]  ? xfs_trans_roll+0x120/0x120
[  118.273406]  ? path_parentat+0xa0/0xa0
[  118.274015]  ? fsnotify+0xd4/0x700
[  118.274567]  ? path_parentat+0xa0/0xa0
[  118.275188]  ? xattr_resolve_name+0xff/0x190
[  118.275878]  __vfs_getxattr+0x61/0x80
[  118.276476]  cap_inode_need_killpriv+0x2a/0x40
[  118.277196]  security_inode_need_killpriv+0x45/0x60
[  118.277984]  notify_change+0x2d7/0x670
[  118.278593]  ? chown_common+0x276/0x310
[  118.279227]  chown_common+0x276/0x310
[  118.279821]  ? chmod_common+0x260/0x260
[  118.280446]  ? kasan_kmalloc+0xa6/0xd0
[  118.281055]  ? getname_flags+0x101/0x2b0
[  118.281691]  ? getname_flags+0x101/0x2b0
[  118.282326]  ? __mnt_is_readonly.part.13+0x1f/0x30
[  118.283107]  ? __mnt_want_write+0x98/0xb0
[  118.283755]  SyS_chown+0x102/0x140
[  118.284307]  ? SyS_fchownat+0x180/0x180
[  118.284926]  ? SyS_fchmodat+0x110/0x110
[  118.285543]  ? spurious_fault+0x2f0/0x2f0
[  118.286191]  ? SyS_fchownat+0x180/0x180
[  118.286824]  do_syscall_64+0xe9/0x1f0
[  118.287420]  entry_SYSCALL_64_after_hwframe+0x21/0x86
[  118.288228] RIP: 0033:0x7f7134b85307
[  118.288806] RSP: 002b:00007ffeb2eabc28 EFLAGS: 00000206 ORIG_RAX: 000000000000005c
[  118.290001] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f7134b85307
[  118.291142] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 000000000129d0a0
[  118.292269] RBP: 00007ffeb2eabd90 R08: 0000000000000003 R09: 0000000000000000
[  118.293390] R10: 0000000000000610 R11: 0000000000000206 R12: 0000000000400c20
[  118.294513] R13: 00007ffeb2eabe90 R14: 0000000000000000 R15: 0000000000000000
[  118.295650] Code: 14 bd 08 00 00 00 48 89 df 89 ee e8 22 fe ff ff 89 e8 5b 5d c3 48 8d 7b 38 e8 f4 4f d3 ff 48 8b 6b 38 48 8d 7d 12 e8 57 4d d3 ff <f6> 45 12 02 75 d0 bd 04 00 00 00 48 89 df 89 ee e8 f2 fd ff ff 
[  118.298667] RIP: xfs_ilock_attr_map_shared+0x49/0x70 RSP: ffff880067927a88
[  118.299766] CR2: 0000000000000012
[  118.300392] ---[ end trace 84e20e93f614b75d ]---

- Credit
Reported by Wen Xu from SSLab, Gatech
Comment 1 Wen Xu 2018-04-12 03:23:24 UTC
Created attachment 275329 [details]
poc.c
Comment 2 Wen Xu 2018-04-13 06:14:42 UTC
This issue is still reproducible on latest kernel branch...
Comment 3 Eric Sandeen 2018-04-17 04:35:10 UTC
[PATCH] xfs: enhance dinode verifier

on the list should fix this.