Bug 202759

Summary: Kernel panic 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
11.c
Minimized test code

Description Jungyeon 2019-03-04 20:51:29 UTC
Created attachment 281491 [details]
The (compressed) crafted image which causes crash

- Overview
After mounting crafted image, I got this kernel panic while running attached program.

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

- Kernel messages (I used /dev/sdb to get 10.img in following reproduces)
[   74.612165] BTRFS critical (device sdb): corrupt leaf: root=3 block=20975616 slot=0, unexpected item end, have 11675 expect 3995
[   74.618692] BTRFS critical (device sdb): corrupt leaf: root=4 block=29552640 slot=6, bad key order, prev (25288767438849 204 37748736) current (1 204 71303168)
[   74.626048] BTRFS error (device sdb): bad tree block start, want 29364224 have 1099524214784
[   74.631597] BTRFS error (device sdb): parent transid verify failed on 29773824 wanted 19 found 17592186044435
[   74.636260] BTRFS critical (device sdb): corrupt leaf: root=5 block=29683712 slot=16, bad key order, prev (6658 84 3671074431) current (258 84 3972760053)
[  348.495666] btrfs bad mapping eb start 29761536 len 4096, wanted 18236 18446744073705343172
[  348.499583] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
[  348.501547] #PF error: [INSTR]
[  348.502326] PGD 8000000235700067 P4D 8000000235700067 PUD 22ad9b067 PMD 0
[  348.504040] Oops: 0010 [#1] SMP PTI
[  348.504920] CPU: 0 PID: 1251 Comm: a.out Tainted: G        W         5.0.0-rc8+ #9
[  348.506795] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014
[  348.508992] RIP: 0010:          (null)
[  348.509934] Code: Bad RIP value.
[  348.510767] RSP: 0018:ffff8c07b7a03d88 EFLAGS: 00010046
[  348.512061] RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000000
[  348.513822] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff8c07abb6eac8
[  348.515595] RBP: ffff8c07b7a03dd0 R08: 0000000000000000 R09: 0000000000000000
[  348.517352] R10: 0000000000000400 R11: 001dcd6500000000 R12: ffff8c07b7a03de8
[  348.519133] R13: ffffffffffffffe8 R14: ffffffffb247e018 R15: 0000000000000000
[  348.520889] FS:  00007fdbea9dd700(0000) GS:ffff8c07b7a00000(0000) knlGS:0000000000000000
[  348.522896] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  348.524315] CR2: ffffffffffffffd6 CR3: 000000022b8cc006 CR4: 00000000000206f0
[  348.526077] Call Trace:
[  348.526712]  <IRQ>
[  348.527239]  ? __wake_up_common+0x8c/0x130
[  348.528267]  __wake_up_common_lock+0x80/0xc0
[  348.529334]  __wake_up+0x13/0x20
[  348.530153]  wake_up_klogd_work_func+0x40/0x60
[  348.531272]  irq_work_run_list+0x55/0x80
[  348.532258]  ? tick_sched_do_timer+0x60/0x60
[  348.533330]  irq_work_tick+0x40/0x50
[  348.534233]  update_process_times+0x42/0x60
[  348.535300]  tick_sched_handle+0x29/0x60
[  348.536285]  tick_sched_timer+0x3c/0x80
[  348.537250]  __hrtimer_run_queues+0x106/0x270
[  348.538339]  hrtimer_interrupt+0x116/0x240
[  348.539377]  smp_apic_timer_interrupt+0x6f/0x150
[  348.540528]  apic_timer_interrupt+0xf/0x20
[  348.541553]  </IRQ>
[  348.542097] RIP: 0010:__memset+0x24/0x30
[  348.543093] Code: 90 90 90 90 90 90 66 66 90 66 90 49 89 f9 48 89 d1 83 e2 07 48 c1 e9 03 40 0f b6 f6 48 b8 01 01 01 01 01 01 01 01 48 0f af c6 <f3> 48 ab 89 d1 f3 aa 4c 89 c8 c3 90 49 89 f9 40 88 f0 48 89 d1 f3
[  348.547720] RSP: 0018:ffffacf140ffbb98 EFLAGS: 00010206 ORIG_RAX: ffffffffffffff13
[  348.549582] RAX: 0000000000000000 RBX: ffffffffffbfc8c4 RCX: 1ffffffffff3c91b
[  348.551344] RDX: 0000000000000004 RSI: 0000000000000000 RDI: ffff8c07abc00000
[  348.553094] RBP: ffffacf140ffbbb0 R08: 0000000000000001 R09: ffff8c07ab9e8018
[  348.554852] R10: 0000000000000000 R11: ffffacf140ffb9ed R12: ffff8c07ab9e8018
[  348.556606] R13: 0000000000000000 R14: 0000000004c00000 R15: 0000000000001000
[  348.558363]  ? read_extent_buffer+0x137/0x140
[  348.559475]  __btrfs_lookup_bio_sums+0x449/0x690
[  348.560632]  btrfs_lookup_bio_sums+0x16/0x20
[  348.561702]  btrfs_submit_bio_hook+0xc3/0x180
[  348.562799]  submit_one_bio+0x5d/0x80
[  348.563720]  extent_read_full_page+0x56/0x70
[  348.564789]  btrfs_readpage+0x25/0x30
[  348.565714]  generic_file_read_iter+0x615/0xc70
[  348.566858]  ? __page_cache_alloc+0x20/0x20
[  348.567908]  __vfs_read+0x11f/0x1a0
[  348.568790]  vfs_read+0x95/0x140
[  348.569608]  ksys_read+0x55/0xc0
[  348.570425]  __x64_sys_read+0x1a/0x20
[  348.571417]  do_syscall_64+0x5a/0x110
[  348.572339]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  348.573598] RIP: 0033:0x7fdbea4f84d9
[  348.574508] 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
[  348.579116] RSP: 002b:00007ffe606b4e78 EFLAGS: 00000203 ORIG_RAX: 0000000000000000
[  348.580994] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fdbea4f84d9
[  348.582793] RDX: 00000000000009e4 RSI: 00007ffe606b5120 RDI: 0000000000000003
[  348.584551] RBP: 00007ffe606b9130 R08: 00007ffe606b9218 R09: 00007ffe606b9218
[  348.586310] R10: 00007fdbea7d1ab0 R11: 0000000000000203 R12: 00000000004004e0
[  348.588084] R13: 00007ffe606b9210 R14: 0000000000000000 R15: 0000000000000000
[  348.589845] Modules linked in:
[  348.590631] CR2: 0000000000000000
[  348.591466] ---[ end trace 09d27bb643f91404 ]---
[  348.592618] RIP: 0010:          (null)
[  348.593562] Code: Bad RIP value.
[  348.594377] RSP: 0018:ffff8c07b7a03d88 EFLAGS: 00010046
[  348.595723] RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000000
[  348.597479] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff8c07abb6eac8
[  348.599250] RBP: ffff8c07b7a03dd0 R08: 0000000000000000 R09: 0000000000000000
[  348.601002] R10: 0000000000000400 R11: 001dcd6500000000 R12: ffff8c07b7a03de8
[  348.602766] R13: ffffffffffffffe8 R14: ffffffffb247e018 R15: 0000000000000000
[  348.604516] FS:  00007fdbea9dd700(0000) GS:ffff8c07b7a00000(0000) knlGS:0000000000000000
[  348.606521] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  348.607941] CR2: ffffffffffffffd6 CR3: 000000022b8cc006 CR4: 00000000000206f0
[  348.609700] Kernel panic - not syncing: Fatal exception in interrupt
[  348.624577] Kernel Offset: 0x2fc00000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
[  348.627257] ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---
Comment 1 Jungyeon 2019-03-04 20:51:52 UTC
Created attachment 281493 [details]
11.c
Comment 2 Jungyeon 2019-03-04 20:52:52 UTC
Comment on attachment 281493 [details]
11.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;
>       unsigned char v19[117];
>       memcpy(v19,
>"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
>117);
>       char v20[] = "trusted.sslab";
>       unsigned char v21[82];
>       memcpy(v21,
>"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
>82);
>       char v22[] = "system.t7eS60jQ";
>       char v23[] = "security.KdPoXmQX";
>       v18 = syscall(SYS_open, (long)v17, 2, 0);
>       syscall(SYS_read, (long)v18, (long)v0, 2532);
>       syscall(SYS_fsync, (long)v18);
>       syscall(SYS_ftruncate, (long)v18, 4211);
>       syscall(SYS_pwrite64, (long)v18, (long)v1, 5270, 3504);
>       syscall(SYS_setxattr, (long)v13, (long)v20, (long)v19, 117, 1);
>       syscall(SYS_setxattr, (long)v12, (long)v22, (long)v21, 82, 1);
>       syscall(SYS_removexattr, (long)v16, (long)v23);
>       syscall(SYS_pread64, (long)v18, (long)v0, 6128, 4914);
>       syscall(SYS_rmdir, (long)v3);
>       syscall(SYS_access, (long)v7, 2);
>       syscall(SYS_fsync, (long)v18);
>
>       close(v18);
>       return 0;
>}
>/* Active fds: v18 */
>/* Files
>Path: .
>Type: dir
>Xattrs: 
>Path: foo/bar/stress/f5
>Type: file
>Xattrs: 
>Path: foo/bar/xattr
>Type: file
>Xattrs: 
>Path: foo/bar/fifo
>Type: fifo
>Xattrs: 
>Path: foo/bar/hln
>Type: file
>Xattrs: 
>Path: foo/bar/baz
>Type: file
>Xattrs: 
>Path: foo/bar/stress/f7
>Type: file
>Xattrs: 
>Path: foo/bar/stress/f3
>Type: file
>Xattrs: 
>Path: foo/bar/stress/f4
>Type: file
>Xattrs: 
>Path: foo/bar/acl
>Type: file
>Xattrs: 
>Path: foo/bar/stress/f2
>Type: file
>Xattrs: 
>name: trusted.sslab\x00
>Path: foo/bar/stress/f1
>Type: file
>Xattrs: 
>name: system.t7eS60jQ\x00
>Path: foo/bar/stress
>Type: dir
>Xattrs: 
>Path: foo/bar/sln
>Type: symlink
>Xattrs: 
>Path: foo/bar
>Type: dir
>Xattrs: 
>*/
Comment 3 Jungyeon 2019-03-07 03:59:58 UTC
Created attachment 281553 [details]
Minimized test code

Attaching minimized version of program with the same result. (Plz use this)
Comment 4 David Sterba 2019-05-21 12:17:47 UTC
Thanks for the report. Fixed by 448de471cd4cab0ced "btrfs: Check the first key and level for cached extent buffer", now in 5.2-rc.