Skip to content

Instantly share code, notes, and snippets.

@mhiramat
Created July 14, 2017 14:10
Show Gist options
  • Save mhiramat/13887f1026d7193a64552c5c345ee27a to your computer and use it in GitHub Desktop.
Save mhiramat/13887f1026d7193a64552c5c345ee27a to your computer and use it in GitHub Desktop.
Linux 4.12.1 kernel overlayfs bug
[ 1153.461894] BUG: unable to handle kernel paging request at ffffffffc0cd8667
[ 1153.461938] IP: report_bug+0x84/0xe0
[ 1153.461956] PGD 392e0d067
[ 1153.461957] P4D 392e0d067
[ 1153.461970] PUD 392e0f067
[ 1153.461983] PMD 48e7bd067
[ 1153.462006] PTE 80000004855d3161
[ 1153.462043] Oops: 0003 [#2] SMP
[ 1153.462058] Modules linked in: overlay xt_CHECKSUM ipt_MASQUERADE nf_nat_masquerade_ipv4 xt_addrtype rfcomm fuse nf_conntrack_tftp ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_conntrack ip_set ebtable_nat ebtable_filter ebtable_broute ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_raw ip6table_mangle ip6table_security ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat iptable_raw iptable_mangle iptable_security iptable_filter ip_tables bnep binfmt_misc nls_iso8859_1 i2c_designware_platform i2c_designware_core snd_hda_codec_hdmi dell_wmi dell_laptop dell_smbios dcdbas brcmfmac snd_hda_codec_realtek snd_hda_codec_generic cfg80211 snd_hda_intel snd_hda_codec snd_hda_core brcmutil snd_pcm snd_hwdep intel_rapl
[ 1153.462365] snd_seq_midi x86_pkg_temp_thermal intel_powerclamp idma64 snd_seq_midi_event snd_rawmidi coretemp btusb virt_dma btrtl snd_seq crct10dif_pclmul crc32_pclmul aesni_intel hci_uart uvcvideo snd_timer aes_x86_64 crypto_simd snd_seq_device cryptd videobuf2_vmalloc glue_helper snd videobuf2_memops videobuf2_v4l2 btbcm videobuf2_core btqca videodev btintel cmac joydev input_leds serio_raw bluetooth media soundcore hid_multitouch mei_me mei kvm_intel processor_thermal_device shpchp intel_lpss_pci intel_soc_dts_iosf kvm int3403_thermal acpi_als intel_lpss_acpi ecdh_generic dell_smo8800 intel_lpss kfifo_buf int3402_thermal industrialio int3400_thermal intel_hid int340x_thermal_zone acpi_thermal_rel acpi_pad sparse_keymap irqbypass parport_pc ppdev lp parport autofs4 btrfs xor raid6_pq usbhid nouveau
[ 1153.462681] i915 ttm i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops drm rtsx_pci_sdmmc mxm_wmi psmouse nvme rtsx_pci ahci nvme_core libahci i2c_hid video pinctrl_sunrisepoint wmi pinctrl_intel
[ 1153.462772] CPU: 4 PID: 8177 Comm: mount Tainted: G D 4.12.1 #42
[ 1153.462803] Hardware name: Dell Inc. XPS 15 9550/0N7TVV, BIOS 1.2.14 08/31/2016
[ 1153.462833] task: ffff9a72d1e18f00 task.stack: ffffaa59c55ac000
[ 1153.462861] RIP: 0010:report_bug+0x84/0xe0
[ 1153.462880] RSP: 0018:ffffaa59c55afb30 EFLAGS: 00010202
[ 1153.462904] RAX: 0000000000000907 RBX: ffffaa59c55afc88 RCX: ffffffffc0cd8663
[ 1153.462934] RDX: 0000000000000001 RSI: 0000000000000001 RDI: ffffffffc0cd219b
[ 1153.462964] RBP: ffffaa59c55afb40 R08: 0000000000000000 R09: 000000000000039c
[ 1153.463001] R10: 0000000000000000 R11: ffff9a7262729038 R12: ffffffffc0cd219b
[ 1153.463035] R13: 0000000000000006 R14: 0000000000000004 R15: ffffaa59c55afbc0
[ 1153.463067] FS: 00007f15cfc93840(0000) GS:ffff9a72fdd00000(0000) knlGS:0000000000000000
[ 1153.463106] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 1153.463131] CR2: ffffffffc0cd8667 CR3: 0000000494693000 CR4: 00000000003406e0
[ 1153.463162] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 1153.463192] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 1153.463223] Call Trace:
[ 1153.463240] fixup_bug+0x2c/0x50
[ 1153.463257] do_trap+0xa0/0x170
[ 1153.463274] do_error_trap+0x77/0xf0
[ 1153.463307] ? ovl_getattr+0x19b/0x1b0 [overlay]
[ 1153.463330] ? lookup_fast+0xc0/0x2e0
[ 1153.463349] ? trace_hardirqs_off_thunk+0x1a/0x34
[ 1153.463372] do_invalid_op+0x20/0x30
[ 1153.463391] invalid_op+0x1e/0x30
[ 1153.463409] RIP: 0010:ovl_getattr+0x19b/0x1b0 [overlay]
[ 1153.463432] RSP: 0018:ffffaa59c55afd30 EFLAGS: 00010206
[ 1153.463455] RAX: 000000000000001a RBX: 0000000000000000 RCX: 0000000000000000
[ 1153.463486] RDX: 0000000000000fff RSI: ffffaa59c55afd50 RDI: ffff9a72ce220270
[ 1153.463517] RBP: ffffaa59c55afe00 R08: ffffaa59c55afd40 R09: ffff9a72ce2201e8
[ 1153.463547] R10: 0000000000000000 R11: ffff9a7262729038 R12: ffffaa59c55afea8
[ 1153.463581] R13: 0000000000000000 R14: ffff9a72d4bfd0c0 R15: ffff9a726aa52480
[ 1153.463616] vfs_getattr_nosec+0x70/0x80
[ 1153.463635] vfs_getattr+0x36/0x40
[ 1153.463653] vfs_statx+0x7f/0xc0
[ 1153.463670] SYSC_newlstat+0x2e/0x50
[ 1153.463688] SyS_newlstat+0xe/0x10
[ 1153.463705] entry_SYSCALL_64_fastpath+0x23/0xbd
[ 1153.463726] RIP: 0033:0x7f15cf57ec55
[ 1153.463743] RSP: 002b:00007fff3f273648 EFLAGS: 00000246 ORIG_RAX: 0000000000000006
[ 1153.463776] RAX: ffffffffffffffda RBX: 00007f15cf84cb20 RCX: 00007f15cf57ec55
[ 1153.463806] RDX: 00007fff3f273690 RSI: 00007fff3f273690 RDI: 0000000001bd8350
[ 1153.463836] RBP: 0000000000001011 R08: 0000000001bd8310 R09: 73636e696d2f6372
[ 1153.463867] R10: 00007f15cf84cb78 R11: 0000000000000246 R12: 00007f15cf84cb78
[ 1153.463917] R13: 00007f15cf84cb78 R14: 0000000000002710 R15: 0000000000000000
[ 1153.463954] Code: e8 f2 fd ff ff 48 89 c1 48 85 c9 74 4e 0f b7 41 04 89 c6 83 e6 01 a8 02 74 15 66 85 f6 74 10 a8 04 ba 01 00 00 00 75 27 83 c8 04 <66> 89 41 04 66 85 f6 74 27 0f b6 49 05 4c 89 e2 45 31 c9 49 89
[ 1153.464085] RIP: report_bug+0x84/0xe0 RSP: ffffaa59c55afb30
[ 1153.464114] CR2: ffffffffc0cd8667
[ 1153.464134] ---[ end trace 4c80b5c2002f890f ]---
@mhiramat
Copy link
Author

$ eu-addr2line -e ~/kbin/linux.x86_64/fs/overlayfs/overlay.ko ovl_getattr+0x19b
/home/mhiramat/ksrc/linux/fs/overlayfs/inode.c:104

@mhiramat
Copy link
Author

                    /*
                     * Lower hardlinks are broken on copy up to different
                     * upper files, so we cannot use the lower origin st_ino
                     * for those different files, even for the same fs case.
                     */
                    if (is_dir || lowerstat.nlink == 1)
                            stat->ino = lowerstat.ino;  // <-- 104

@mhiramat
Copy link
Author

3194:       49 89 44 24 20          mov    %rax,0x20(%r12)
3199:       eb 8b                   jmp    3126 <ovl_getattr+0x126>
319b:       0f ff                   (bad)    # <=== This is the bug!
319d:       e9 70 ff ff ff          jmpq   3112 <ovl_getattr+0x112>
31a2:       0f 1f 40 00             nopl   0x0(%rax)
31a6:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
31ad:       00 00 00 

@mhiramat
Copy link
Author

30f8:       e8 00 00 00 00          callq  30fd <ovl_getattr+0xfd>
30fd:       85 c0                   test   %eax,%eax
30ff:       75 5b                   jne    315c <ovl_getattr+0x15c>
3101:       8b 85 78 ff ff ff       mov    -0x88(%rbp),%eax
3107:       41 39 44 24 28          cmp    %eax,0x28(%r12)
310c:       0f 85 89 00 00 00       jne    319b <ovl_getattr+0x19b>  <=== here is the jump to 0x19b

@mhiramat
Copy link
Author

$ eu-addr2line -e ~/kbin/linux.x86_64/fs/overlayfs/overlay.ko ovl_getattr+0x10c
/home/mhiramat/ksrc/linux/fs/overlayfs/inode.c:97
$ eu-addr2line -e ~/kbin/linux.x86_64/fs/overlayfs/overlay.ko ovl_getattr+0x0ff
/home/mhiramat/ksrc/linux/fs/overlayfs/inode.c:94

@mhiramat
Copy link
Author

mhiramat commented Jul 14, 2017

                    ovl_path_lower(dentry, &realpath);
                    err = vfs_getattr(&realpath, &lowerstat,
                                      lowermask, flags);
                    if (err)                                        <=== 94
                            goto out; 

                    WARN_ON_ONCE(stat->dev != lowerstat.dev);  <=====97
                    /*
                     * Lower hardlinks are broken on copy up to different
                     * upper files, so we cannot use the lower origin st_ino
                     * for those different files, even for the same fs case.
                     */
                    if (is_dir || lowerstat.nlink == 1)
                            stat->ino = lowerstat.ino;

@mhiramat
Copy link
Author

[ 1087.181263] BUG: unable to handle kernel paging request at ffffffffc0cd8667
[ 1087.181314] IP: report_bug+0x84/0xe0
$ eu-addr2line -e ~/kbin/linux.x86_64/vmlinux report_bug+0x84
/home/mhiramat/ksrc/linux/lib/bug.c:177

@mhiramat
Copy link
Author

enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
{
[...]
if (warning && once) {
if (done)
return BUG_TRAP_TYPE_WARN;

                    /*
                     * Since this is the only store, concurrency is not an issue.
                     */
                    bug->flags |= BUGFLAG_DONE; <--------------------177
            }

@mhiramat
Copy link
Author

mhiramat commented Jul 15, 2017

$ objdump -d ~/kbin/linux.x86_64/lib/bug.o

 00000000000001b0 <report_bug>:
 [...]  (1b0 + 84 = 234)
 228:   a8 04                   test   $0x4,%al
 22a:   ba 01 00 00 00          mov    $0x1,%edx
 22f:   75 27                   jne    258 <report_bug+0xa8>
 231:   83 c8 04                or     $0x4,%eax
 234:   66 89 41 04             mov    %ax,0x4(%rcx)   <----- report_bug+0x84
 238:   66 85 f6                test   %si,%si
 23b:   74 27                   je     264 <report_bug+0xb4>

@mhiramat
Copy link
Author

コンパイラのバグかなあ?
何が起きてるかって言うと、bug構造体の値がおかしいようにみえる。

@mhiramat
Copy link
Author

report_bugの全容は以下の通り。0x234に至るためには一番近いジャンプ先アドレスが0x216なので、必ず
movzwl 0x4(%rcx),%eaxから先の処理を通ることになる。この間にrcxを破壊している処理はない。

00000000000001b0 <report_bug>:
 1b0:	55                   	push   %rbp
 1b1:	48 89 e5             	mov    %rsp,%rbp
 1b4:	41 54                	push   %r12
 1b6:	53                   	push   %rbx
 1b7:	49 89 fc             	mov    %rdi,%r12
 1ba:	48 89 f3             	mov    %rsi,%rbx
 1bd:	e8 00 00 00 00       	callq  1c2 <report_bug+0x12>
 1c2:	31 d2                	xor    %edx,%edx
 1c4:	85 c0                	test   %eax,%eax
 1c6:	0f 84 8c 00 00 00    	je     258 <report_bug+0xa8>
 1cc:	48 c7 c0 00 00 00 00 	mov    $0x0,%rax
 1d3:	48 3d 00 00 00 00    	cmp    $0x0,%rax
 1d9:	73 2b                	jae    206 <report_bug+0x56>
 1db:	48 63 15 00 00 00 00 	movslq 0x0(%rip),%rdx        # 1e2 <report_bug+0x32>
 1e2:	48 01 c2             	add    %rax,%rdx
 1e5:	49 39 d4             	cmp    %rdx,%r12
 1e8:	75 10                	jne    1fa <report_bug+0x4a>
 1ea:	e9 97 00 00 00       	jmpq   286 <report_bug+0xd6>
 1ef:	48 63 08             	movslq (%rax),%rcx
 1f2:	48 01 c1             	add    %rax,%rcx
 1f5:	49 39 cc             	cmp    %rcx,%r12
 1f8:	74 65                	je     25f <report_bug+0xaf>
 1fa:	48 83 c0 08          	add    $0x8,%rax
 1fe:	48 3d 00 00 00 00    	cmp    $0x0,%rax
 204:	72 e9                	jb     1ef <report_bug+0x3f>
 206:	4c 89 e7             	mov    %r12,%rdi
 209:	e8 f2 fd ff ff       	callq  0 <find_bug.part.2>
 20e:	48 89 c1             	mov    %rax,%rcx
 211:	48 85 c9             	test   %rcx,%rcx
 214:	74 4e                	je     264 <report_bug+0xb4>
 216:	0f b7 41 04          	movzwl 0x4(%rcx),%eax
 21a:	89 c6                	mov    %eax,%esi
 21c:	83 e6 01             	and    $0x1,%esi
 21f:	a8 02                	test   $0x2,%al
 221:	74 15                	je     238 <report_bug+0x88>
 223:	66 85 f6             	test   %si,%si
 226:	74 10                	je     238 <report_bug+0x88>
 228:	a8 04                	test   $0x4,%al
 22a:	ba 01 00 00 00       	mov    $0x1,%edx
 22f:	75 27                	jne    258 <report_bug+0xa8>
 231:	83 c8 04             	or     $0x4,%eax
 234:	66 89 41 04          	mov    %ax,0x4(%rcx)
 238:	66 85 f6             	test   %si,%si
 23b:	74 27                	je     264 <report_bug+0xb4>
 23d:	0f b6 49 05          	movzbl 0x5(%rcx),%ecx
 241:	4c 89 e2             	mov    %r12,%rdx
 244:	45 31 c9             	xor    %r9d,%r9d
 247:	49 89 d8             	mov    %rbx,%r8
 24a:	31 f6                	xor    %esi,%esi
 24c:	31 ff                	xor    %edi,%edi
 24e:	e8 00 00 00 00       	callq  253 <report_bug+0xa3>
 253:	ba 01 00 00 00       	mov    $0x1,%edx
 258:	5b                   	pop    %rbx
 259:	89 d0                	mov    %edx,%eax
 25b:	41 5c                	pop    %r12
 25d:	5d                   	pop    %rbp
 25e:	c3                   	retq   
 25f:	48 89 c1             	mov    %rax,%rcx
 262:	eb ad                	jmp    211 <report_bug+0x61>
 264:	48 c7 c7 00 00 00 00 	mov    $0x0,%rdi
 26b:	e8 00 00 00 00       	callq  270 <report_bug+0xc0>
 270:	4c 89 e6             	mov    %r12,%rsi
 273:	48 c7 c7 00 00 00 00 	mov    $0x0,%rdi
 27a:	e8 00 00 00 00       	callq  27f <report_bug+0xcf>
 27f:	ba 02 00 00 00       	mov    $0x2,%edx
 284:	eb d2                	jmp    258 <report_bug+0xa8>
 286:	48 89 c1             	mov    %rax,%rcx
 289:	eb 8b                	jmp    216 <report_bug+0x66>

@mhiramat
Copy link
Author

読めるアドレスに書き込みをした時にエラーが出ているので、多分bug entryが何かのキッカケでread onlyになっているんじゃなかろうか。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment