Skip to content

General protection fault with metadata_csum mode #115

@hayley-leblanc

Description

@hayley-leblanc

Hi,

I'm working with NOVA in metadata_csum mode on a QEMU/KVM virtual machine. Unmounting and remounting an instance of NOVA with this configuration is consistently leading to a general protection fault. The following is a trace obtained by mounting a fresh NOVA instance, immediately unmounting it, and then re-mounting it.

[   31.439366] ------------[ cut here ]------------
[   31.440266] General protection fault in user access. Non-canonical address?
[   31.440303] WARNING: CPU: 0 PID: 326 at arch/x86/mm/extable.c:125 ex_handler_uaccess+0x6a/0x70
[   31.442344] Modules linked in: nova(E)
[   31.442733] CPU: 0 PID: 326 Comm: mount Tainted: G            E     5.1.0+ #433
[   31.443504] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
[   31.444414] RIP: 0010:ex_handler_uaccess+0x6a/0x70
[   31.444910] Code: 41 5d 5d c3 e8 b7 4a 12 00 80 3d aa cc 76 01 00 75 d0 e8 a9 4a 12 00 48 c7 c7 b0 07 49 82 c6 05 95 cc 76 01 01 e8 56 58 02 00 <0f> 0b eb8
[   31.446750] RSP: 0018:ffffc90001d3f908 EFLAGS: 00010282
[   31.447273] RAX: 0000000000000000 RBX: ffffffff8200287c RCX: ffffffff8112b323
[   31.447983] RDX: 0000000000000000 RSI: ffffffff82b5f99f RDI: 0000000000000293
[   31.448696] RBP: ffffc90001d3f920 R08: 0000000a4e32c4ad R09: 000000000000003f
[   31.449402] R10: 0000000000000000 R11: 0000000000000000 R12: ffffc90001d3f998
[   31.450107] R13: 000000000000000d R14: 0000000000000000 R15: 0000000000000000
[   31.450813] FS:  00007f7ba9929e40(0000) GS:ffff888237e00000(0000) knlGS:0000000000000000
[   31.451612] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   31.452193] CR2: 00007ff7436db000 CR3: 00000002353da000 CR4: 00000000000006b0
[   31.452919] Call Trace:
[   31.453177]  fixup_exception+0x5a/0x80
[   31.453557]  do_general_protection+0x50/0x160
[   31.454002]  general_protection+0x1e/0x30
[   31.454411] RIP: 0010:__copy_user_nocache+0x41/0xf0
[   31.454903] Code: d9 29 ca 8a 06 88 07 48 ff c6 48 ff c7 ff c9 75 f2 89 d1 83 e2 3f c1 e9 06 74 52 4c 8b 06 4c 8b 4e 08 4c 8b 56 10 4c 8b 5e 18 <4c> 0f c36
[   31.456761] RSP: 0018:ffffc90001d3fa48 EFLAGS: 00010203
[   31.457323] RAX: ffff8882367dc140 RBX: ffff518101d3fb88 RCX: 0000000000000001
[   31.458029] RDX: 0000000000000038 RSI: ffff888100001180 RDI: ffff518101d3fb88
[   31.458736] RBP: ffffc90001d3fa68 R08: 0000000000000000 R09: 0000000000000000
[   31.459442] R10: 0000000000000000 R11: 0000000000000000 R12: ffff888100001180
[   31.460149] R13: 0000000000000078 R14: ffff8882352d7000 R15: ffff888233443000
[   31.460921]  ? memcpy_to_pmem_nocache+0x2f/0x36 [nova]
[   31.461439]  nova_free_inode_log+0x16d/0x338 [nova]
[   31.461931]  ? nova_insert_range_node+0x10d/0x11e [nova]
[   31.462466]  nova_init_blockmap_from_inode+0xd4/0x3da [nova]
[   31.463041]  ? crc32c+0x67/0xb0
[   31.463362]  ? xas_find_marked+0x18d/0x3e0
[   31.463778]  ? __switch_to_asm+0x34/0x70
[   31.464177]  ? __switch_to_asm+0x40/0x70
[   31.464583]  ? find_first_zero_bit+0x5e/0x90
[   31.465011]  ? find_first_zero_bit+0x5e/0x90
[   31.465443]  nova_recovery+0x47d/0xadd [nova]
[   31.465882]  ? nova_recovery+0x47d/0xadd [nova]
[   31.466337]  ? _cond_resched+0x19/0x40
[   31.466719]  ? __kmalloc+0x1fe/0x210
[   31.467083]  ? nova_lite_journal_soft_init+0x4e3/0x5a3 [nova]
[   31.467660]  nova_fill_super+0xcf9/0xf4b [nova]
[   31.468147]  mount_bdev+0x1cc/0x210
[   31.468564]  ? nova_init+0x81c/0x81c [nova]
[   31.468975]  nova_mount+0x39/0x42 [nova]
[   31.469365]  legacy_get_tree+0x2f/0x80
[   31.469732]  vfs_get_tree+0x35/0x140
[   31.470086]  do_mount+0x9a9/0x1150
[   31.470459]  ? memdup_user+0x63/0x90
[   31.470926]  ? copy_mount_options+0x192/0x2b0
[   31.471388]  ksys_mount+0xb0/0x120
[   31.471733]  __x64_sys_mount+0x2b/0x30
[   31.472111]  do_syscall_64+0x67/0x160
[   31.472496]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[   31.473004] RIP: 0033:0x7f7ba8fe748a
[   31.473369] Code: 48 8b 0d 11 fa 2a 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d 018
[   31.475216] RSP: 002b:00007ffdede8e4b8 EFLAGS: 00000206 ORIG_RAX: 00000000000000a5
[   31.475972] RAX: ffffffffffffffda RBX: 000055d3f9b76060 RCX: 00007f7ba8fe748a
[   31.476686] RDX: 000055d3f9b76240 RSI: 000055d3f9b76280 RDI: 000055d3f9b76260
[   31.477390] RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000020
[   31.478094] R10: 00000000c0ed0000 R11: 0000000000000206 R12: 000055d3f9b76260
[   31.478800] R13: 000055d3f9b76240 R14: 0000000000000000 R15: 00000000ffffffff
[   31.479505] ---[ end trace 91599f8f056cc37f ]---

I believe the problem is that nova_init_blockmap_from_inode() defines a nova_inode_info_header but only fills in some of its fields. nova_free_inode_log(), which is called before nova_init_blockmap_from_inode() returns, attempts to dereference the alter_pi_addr field, which hasn't been set and can contain a bad pointer. Zeroing out the inode info header struct fixes the issue for me. I'll submit a PR soon.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions