APPLIED: [B][PATCH 0/2] Kernel oops due to uninitialized list on kernfs

Kleber Souza kleber.souza at canonical.com
Fri Jul 16 15:30:51 UTC 2021


On 30.06.21 20:59, Guilherme G. Piccoli wrote:
> BugLink: https://bugs.launchpad.net/bugs/1934175
> 
> 
> [Impact]
> * We had a recent report of a kernel crash due to a NULL pointer dereference
> in a Bionic 4.15 derivative kernel, as per the following log collected:
> 
> [...]
> [537105.767348] SLUB: Unable to allocate memory on node -1,
> gfp=0x14000c0(GFP_KERNEL)
> [...]
> [537105.767368] BUG: unable to handle kernel NULL pointer dereference at 0000000000000008
> [537105.777711] IP: kernfs_kill_sb+0x31/0x70
> [537105.783582] PGD 0 P4D 0
> [537105.787844] Oops: 0002 [#1] SMP PTI
> [...]
> RIP: 0010:kernfs_kill_sb+0x31/0x70
> RSP: 0018:ffffb90aec1afd00 EFLAGS: 00010286
> RAX: 0000000000000000 RBX: ffff9fdbd567d900 RCX: ffffa0143885ae01
> RDX: 0000000000000000 RSI: ffffa0143885ae00 RDI: ffffffffa2937c40
> RBP: ffffb90aec1afd10 R08: ffffa0150b581510 R09: 000000018100004d
> R10: ffffb90aec1afcd8 R11: 0000000000000100 R12: ffffa01436e43000
> R13: ffffa01436e43000 R14: 0000000000000000 R15: ffff9fdbd567d900
> FS: 00007fe41a615b80(0000) GS:ffffa01afea40000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 0000000000000008 CR3: 0000007dfe3cc003 CR4: 00000000003606e0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
> Call Trace:
>   sysfs_kill_sb+0x1f/0x40
>   deactivate_locked_super+0x48/0x80
>   kernfs_mount_ns+0x1eb/0x230
>   sysfs_mount+0x66/0xc0
>   mount_fs+0x37/0x160
>   ? alloc_vfsmnt+0x1b3/0x230
>   vfs_kern_mount.part.24+0x5d/0x110
>   do_mount+0x5ed/0xce0
> [...]
> 
> * The following detailed call stack plus the disassembly help to understand
> the cause of the issue:
> 
> mount_fs()
>   sysfs_mount()
>    kernfs_mount_ns() <inlined kernfs_fill_super() fails, very likely due to being unable to allocate memory>
>     deactivate_locked_super() <given the callback .kill_sb = sysfs_kill_sb, next function is called>
>      sysfs_kill_sb()
>       kernfs_kill_sb() <OOPS due to the unitialized list>
> 
> The below disassembly of kernfs_kill_sb() clarifies exactly the issue:
> 
> ffffffff812f46e0 <kernfs_kill_sb>:
> [ ... prologue ...]
> 48 8b 9f 08 04 00 00 mov 0x408(%rdi),%rbx # %rbx = kernfs_super_info *info = sb->s_fs_info
> 49 89 fc mov %rdi,%r12 # %r12 = super_block *sb
> 48 c7 c7 40 7c 53 82 mov $0xffffffff82537c40,%rdi # %rdi = &kernfs_mutex (global)
> R_X86_64_32S kernfs_mutex
> e8 ee da 67 00 callq ffffffff819721f0 <mutex_lock> # mutex_lock(&kernfs_mutex);
> [...]
> 48 8b 53 18 mov 0x18(%rbx),%rdx # %rdx = info->node
> 48 8b 43 20 mov 0x20(%rbx),%rax # based on splat, RAX == 0x0 [info->head.prev]
> 48 89 42 08 mov %rax,0x8(%rdx) # <- OOPS [tried to assign next->prev = prev, see __list_del()]
> 48 89 10 mov %rdx,(%rax)
> 48 b8 00 01 00 00 00 movabs $0xdead000000000100,%rax # node->next = LIST_POISON1
> [...]
> 
> * The fix for this issue comes from upstream commit 82382acec0c9 ("kernfs: deal
> with kernfs_fill_super() failures"); this commit is a very trivial fix that
> adds an INIT_LIST_HEAD(&info->node) in kernfs_mount_ns(), making the list
> prev/next pointers valid since the beginning. Unfortunately this commit wasn't
> CCed to stable email when sent, so it wasn't automatically picked up by Ubuntu
> kernel; now it was properly submitted to stable list [0].
> 
> * Along with this fix, we found another commit (7b745a4e4051) which is a
> small/simple fix to correlated code, that also should have been sent to 4.14.y
> stable branch, but for some reason wasn't. Since both commits were accepted in
> linux-stable, we are hereby proposing the backport for Ubuntu kernel 4.15.
> 
> [0] https://lore.kernel.org/stable/20210622210622.9925-1-gpiccoli@canonical.com/
> 
> 
> [Test Case]
> * We don't have a real test case, although low-memory condition or an artificial
> kprobe reproducer could easily trigger the issue.
> 
> * We booted a qemu virtual machine with a kernel containing both patches with no issues.
> 
> 
> [Where problems could occur]
> * The likelihood of issues are low, specially due to the fact both patches are
> very simple and they are on upstream kernel for more than 3 years (and were
> quickly accepted in 4.14.y stable branch last week).
> 
> * With that sad, the second patch could potentially introduce issues with
> super_block references - I honestly cannot conceive any issues potentially
> caused by patch 1.
> 
> 
> Al Viro (2):
>    kernfs: deal with kernfs_fill_super() failures
>    unfuck sysfs_mount()
> 
>   fs/kernfs/mount.c | 1 +
>   fs/sysfs/mount.c  | 6 +++---
>   2 files changed, 4 insertions(+), 3 deletions(-)
> 


Applied to bionic:linux.

Thanks,
Kleber




More information about the kernel-team mailing list