Bug 202757

Summary: NULL pointer dereference when mounting and operating a crafted btrfs image
Product: File System Reporter: Jungyeon (jungyeon)
Component: btrfsAssignee: BTRFS virtual assignee (fs_btrfs)
Status: RESOLVED CODE_FIX    
Severity: normal CC: dsterba
Priority: P1    
Hardware: All   
OS: Linux   
Kernel Version: 5.0-rc8 Subsystem:
Regression: No Bisected commit-id:
Attachments: The (compressed) crafted image which causes crash
05.c

Description Jungyeon 2019-03-04 20:47:39 UTC
Created attachment 281487 [details]
The (compressed) crafted image which causes crash

- Overview
After mounting crafted image, I got this null pointer dereference while running attached program.

- Produces
mkdir test
mount -t btrfs 05.img test 
gcc 05.c
cp a.out test
cd test
./a.out

- Kernel messages

[  267.856121] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
[  267.859071] #PF error: [normal kernel read fault]
[  267.860771] PGD 800000022a954067 P4D 800000022a954067 PUD 22ebee067 PMD 0 
[  267.862728] Oops: 0000 [#1] SMP PTI
[  267.863664] CPU: 0 PID: 1175 Comm: a.out Not tainted 5.0.0-rc8+ #9
[  267.865286] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
[  267.867648] RIP: 0010:write_extent_buffer+0xaf/0x140
[  267.868964] Code: 83 fa 08 73 40 f6 c2 04 75 76 85 d2 74 0b 41 0f b6 01 f6 c2 02 88 01 75 79 49 01 d1 49 83 c2 08 31 c9 49 29 d0 74 57 49 8b 02 <48> 8b 70 08 48 8d 56 ff 83 e6 01 48 0f 44 d0 48 8b 12 83 e2 04 75
[  267.873862] RSP: 0018:ffffb286812a3ce0 EFLAGS: 00010206
[  267.875191] RAX: 0000000000000000 RBX: ffff9950ab7c0900 RCX: 0000000000000000
[  267.876984] RDX: 0000000000000020 RSI: ffff9950ab7c098c RDI: ffff9950b07ce000
[  267.878795] RBP: ffffb286812a3ce0 R08: 0000000000000006 R09: ffff9950ab7c098c
[  267.880595] R10: ffff9950ab2ae960 R11: 0000000000001000 R12: ffff9950ab2ae8c0
[  267.882402] R13: 00000000ffffffff R14: ffff9950aa930000 R15: ffff9950b07c7a10
[  267.884193] FS:  00007f3f53e0e700(0000) GS:ffff9950b7a00000(0000) knlGS:0000000000000000
[  267.886251] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  267.887706] CR2: 0000000000000008 CR3: 000000022b8ee005 CR4: 00000000000206f0
[  267.889507] Call Trace:
[  267.890149]  __btrfs_run_delayed_items+0x1af/0x620
[  267.891366]  ? __wake_up_common_lock+0x8e/0xc0
[  267.892494]  btrfs_run_delayed_items+0x13/0x20
[  267.893635]  btrfs_commit_transaction+0x1f9/0x950
[  267.894835]  ? dput+0x9d/0x120
[  267.895625]  ? btrfs_log_dentry_safe+0x61/0x80
[  267.896756]  btrfs_sync_file+0x34f/0x3a0
[  267.897794]  vfs_fsync_range+0x48/0x80
[  267.898751]  do_fsync+0x3d/0x70
[  267.899561]  __x64_sys_fsync+0x14/0x20
[  267.900524]  do_syscall_64+0x5a/0x110
[  267.901480]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  267.902767] RIP: 0033:0x7f3f539294d9
[  267.903684] Code: 00 f3 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 8f 29 2c 00 f7 d8 64 89 01 48
[  267.908384] RSP: 002b:00007ffcee34d1c8 EFLAGS: 00000207 ORIG_RAX: 000000000000004a
[  267.910310] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f3f539294d9
[  267.912097] RDX: 00007f3f539294d9 RSI: ffffffffffffff98 RDI: 0000000000000003
[  267.913891] RBP: 00007ffcee351460 R08: 00007ffcee351548 R09: 00007ffcee351548
[  267.915684] R10: 00007ffcee351548 R11: 0000000000000207 R12: 00000000004004e0
[  267.917487] R13: 00007ffcee351540 R14: 0000000000000000 R15: 0000000000000000
[  267.919282] Modules linked in:
[  267.920072] CR2: 0000000000000008
[  267.920944] ---[ end trace 3845badcc6d58cc1 ]---
[  267.922147] RIP: 0010:write_extent_buffer+0xaf/0x140
[  267.923423] Code: 83 fa 08 73 40 f6 c2 04 75 76 85 d2 74 0b 41 0f b6 01 f6 c2 02 88 01 75 79 49 01 d1 49 83 c2 08 31 c9 49 29 d0 74 57 49 8b 02 <48> 8b 70 08 48 8d 56 ff 83 e6 01 48 0f 44 d0 48 8b 12 83 e2 04 75
[  267.928111] RSP: 0018:ffffb286812a3ce0 EFLAGS: 00010206
[  267.929445] RAX: 0000000000000000 RBX: ffff9950ab7c0900 RCX: 0000000000000000
[  267.931254] RDX: 0000000000000020 RSI: ffff9950ab7c098c RDI: ffff9950b07ce000
[  267.933058] RBP: ffffb286812a3ce0 R08: 0000000000000006 R09: ffff9950ab7c098c
[  267.934888] R10: ffff9950ab2ae960 R11: 0000000000001000 R12: ffff9950ab2ae8c0
[  267.936700] R13: 00000000ffffffff R14: ffff9950aa930000 R15: ffff9950b07c7a10
[  267.938524] FS:  00007f3f53e0e700(0000) GS:ffff9950b7a00000(0000) knlGS:0000000000000000
[  267.940581] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  267.942061] CR2: 0000000000000008 CR3: 000000022b8ee005 CR4: 00000000000206f0
Comment 1 Jungyeon 2019-03-04 20:48:10 UTC
Created attachment 281489 [details]
05.c
Comment 2 Jungyeon 2019-03-04 20:54:02 UTC
Comment on attachment 281489 [details]
05.c

>#include <sys/types.h>
>#include <sys/mount.h>
>#include <sys/mman.h>
>#include <sys/stat.h>
>#include <sys/xattr.h>
>#include <sys/syscall.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>
>#define SYS_newlstat   107
>#define SYS_newstat    106
>
>int main(int argc, char *argv[])
>{
>       unsigned char v0[8192] = { 0, };
>       unsigned char v1[8192] = { 0, };
>       char v2[] = ".";
>       char v3[] = "foo";
>       char v4[] = "foo/bar";
>       char v5[] = "foo/bar/baz";
>       char v6[] = "foo/bar/xattr";
>       char v7[] = "foo/bar/acl";
>       char v8[] = "foo/bar/fifo";
>       char v9[] = "foo/bar/hln";
>       char v10[] = "foo/bar/sln";
>       char v11[] = "foo/bar/stress";
>       char v12[] = "foo/bar/stress/f1";
>       char v13[] = "foo/bar/stress/f2";
>       char v14[] = "foo/bar/stress/f3";
>       char v15[] = "foo/bar/stress/f4";
>       char v16[] = "foo/bar/stress/f5";
>       char v17[] = "foo/bar/stress/f7";
>       long v18;
>       long v19;
>       char v20[] = "foo/bar/stress/Uzwe3ELy";
>       unsigned char v21[104];
>       memcpy(v21,
>"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
>104);
>       //memcpy(v21,
>"6\xb94\x01m\xac\xc3,\x8a5W\x96\xa8\xa9\xc9\xd6&l\xa0\x9e\xd4\x88\x80\xa2\x93\xd18\x90FyC\xfc\xb3\xf6\xfd!\xa3AN\xadv\xa5E\x9e\xce\x0fvt\xfa\x17\x13O
>\x94\xf2\xb3\xe5\xaa\xc3\xac$\x07\xa9\xd7\xfd'y"hG\xcf^\xec\x94\xfd\xbb$t\xaf\x9e\x0b\xc2\xee+\xd6\xe1^\xbd\x0c#j0\xa9\x93\x88(\xba\x02\xc9\xa2I\x99\x01\xb5",
>104);
>       char v22[] = "user.sslab";
>       long v23;
>       char v24[] = "foo/bar/stress/fFq9CDvy";
>       char v25[] = "foo/bar/stress/fFq9CDvy/7pGHviqv";
>       v18 = syscall(SYS_open, (long)v16, 2, 0);
>       syscall(SYS_read, (long)v18, (long)v0, 7932);
>       syscall(SYS_fsync, (long)v18);
>       syscall(SYS_access, (long)v12, 4);
>       syscall(SYS_pwrite64, (long)v18, (long)v1, 345, 7244);
>       v19 = syscall(SYS_open, (long)v4, 65536, 0);
>       syscall(SYS_symlink, (long)v16, (long)v20);
>       syscall(SYS_setxattr, (long)v4, (long)v22, (long)v21, 104, 1);
>       syscall(SYS_read, (long)v18, (long)v0, 7146);
>       syscall(SYS_fsync, (long)v18);
>       syscall(SYS_newlstat, (long)v5, (long)v1);
>       syscall(SYS_fsync, (long)v19);
>       syscall(SYS_pwrite64, (long)v18, (long)v1, 5644, 3191);
>       syscall(SYS_fsync, (long)v18);
>       syscall(SYS_ftruncate, (long)v18, 181);
>       syscall(SYS_ftruncate, (long)v18, 1027);
>       syscall(SYS_getdents64, (long)v19, (long)v1, 4879);
>       syscall(SYS_readlink, (long)v2, (long)v1, 8192);
>       v23 = syscall(SYS_open, (long)v20, 2, 0);
>       syscall(SYS_lseek, (long)v18, 2088, 4);
>       syscall(SYS_fsync, (long)v23);
>       syscall(SYS_rmdir, (long)v3);
>       syscall(SYS_fsync, (long)v23);
>       syscall(SYS_ftruncate, (long)v18, 6161);
>       syscall(SYS_read, (long)v23, (long)v0, 7779);
>       syscall(SYS_mkdir, (long)v24, 511);
>       syscall(SYS_lseek, (long)v18, 3594, 0);
>       syscall(SYS_unlink, (long)v8);
>       syscall(SYS_symlink, (long)v11, (long)v25);
>       syscall(SYS_fsync, (long)v18);
>
>       close(v18);
>       close(v19);
>       close(v23);
>       return 0;
>}
>/* Active fds: v18 v19 v23 */
>/* Files
>Path: .
>Type: dir
>Xattrs: 
>Path: foo/bar/hln
>Type: file
>Xattrs: 
>Path: foo/bar
>Type: dir
>Xattrs: 
>name: user.sslab\x00
>Path: foo/bar/stress/f3
>Type: file
>Xattrs: 
>Path: foo/bar/baz
>Type: file
>Xattrs: 
>Path: foo/bar/stress/f7
>Type: file
>Xattrs: 
>Path: foo/bar/stress/f5
>Type: file
>Xattrs: 
>Path: foo/bar/stress/f2
>Type: file
>Xattrs: 
>Path: foo/bar/stress/Uzwe3ELy
>Type: symlink
>Xattrs: 
>Path: foo/bar/stress
>Type: dir
>Xattrs: 
>Path: foo/bar/acl
>Type: file
>Xattrs: 
>Path: foo/bar/stress/f4
>Type: file
>Xattrs: 
>Path: foo/bar/xattr
>Type: file
>Xattrs: 
>Path: foo/bar/stress/f1
>Type: file
>Xattrs: 
>Path: foo/bar/sln
>Type: symlink
>Xattrs: 
>Path: foo/bar/stress/fFq9CDvy
>Type: dir
>Xattrs: 
>Path: foo/bar/stress/fFq9CDvy/7pGHviqv
>Type: symlink
>Xattrs: 
>*/
Comment 3 David Sterba 2019-05-21 12:17:27 UTC
Thanks for the report. Fixed by 448de471cd4cab0ced "btrfs: Check the first key and level for cached extent buffer", now in 5.2-rc.