[Bug 268909] [zfs] panic from null pointer dereference in avl_rotation

From: <bugzilla-noreply_at_freebsd.org>
Date: Thu, 12 Jan 2023 16:32:00 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=268909

            Bug ID: 268909
           Summary: [zfs] panic from null pointer dereference in
                    avl_rotation
           Product: Base System
           Version: 13.1-STABLE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: jfc@mit.edu

During a ZFS scrub my kernel crashed in openzfs/module/avl/avl.c function
avl_rotation because gchild was null in this code:

        gchild = child->avl_child[right];
        gleft = gchild->avl_child[left];
        gright = gchild->avl_child[right];

Longer:

While a zpool scrub was active and nothing else was going on my system crashed
due to a page fault in kernel mode.  Faulting address was 0x8.

Hardware is
CPU: AMD Opteron(tm) X3421 APU                       (2096.10-MHz K8-class CPU)
  Origin="AuthenticAMD"  Id=0x660f01  Family=0x15  Model=0x60  Stepping=1

Software is 13.1-STABLE as of January 9 (f61fca7409f6).

Call chain at fault is

  avl_rotation + 0x51
  avl_remove + 0x1b3
  scan_io_queues_run_one + 0xad3
  taskq_run + 0x1f

Thread name is "zfskern/dsl_scan_iss".

The struct trapframe passed to trap_pfault holds

(lldb) p/x *frame
(trapframe) $2 = {
  tf_rdi = 0xfffff800c1210460
  tf_rsi = 0xfffff80300b0d968
  tf_rdx = 0x0000000000000001
  tf_rcx = 0x0000000000000001
  tf_r8 = 0xfffff80300b0d968
  tf_r9 = 0xfffff802674b7a78
  tf_rax = 0x00000000ffffffff
  tf_rbx = 0x00000000ffffffff
  tf_rbp = 0xfffffe0125165ca0
  tf_r10 = 0x0000000000000000
  tf_r11 = 0xfffff80300000a78
  tf_r12 = 0x0000000000000000
  tf_r13 = 0x0000000000000000
  tf_r14 = 0x0000000000000000
  tf_r15 = 0xfffff802674b7a78
  tf_trapno = 0x0000000c
  tf_fs = 0x0013
  tf_gs = 0x001b
  tf_addr = 0x0000000000000008
  tf_flags = 0x00000001
  tf_es = 0x003b
  tf_ds = 0x003b
  tf_err = 0x0000000000000000
  tf_rip = 0xffffffff81d0f461
  tf_cs = 0x0000000000000020
  tf_rflags = 0x0000000000010246
  tf_rsp = 0xfffffe0125165c68
  tf_ss = 0x0000000000000028
}

The faulting instruction is the load (movq) at address 0x461 in the annotated
disassembly below.  It corresponds to line 409 of avl.c.

# avl_rotation(avl_tree_t *tree, avl_node_t *node, int balance)
0x410: 55               pushq  %rbp
0x411: 48 89 e5         movq   %rsp, %rbp
0x414: 41 57            pushq  %r15
0x416: 41 56            pushq  %r14
0x418: 41 55            pushq  %r13
0x41a: 41 54            pushq  %r12
0x41c: 53               pushq  %rbx
0x41d: 48 83 ec 10      subq   $0x10, %rsp
0x421: 49 89 f0         movq   %rsi, %r8
0x424: 89 d1            movl   %edx, %ecx
0x426: f7 d1            notl   %ecx
0x428: c1 e9 1f         shrl   $0x1f, %ecx          # left = 1
0x42b: 41 89 ca         movl   %ecx, %r10d
0x42e: 41 83 f2 01      xorl   $0x1, %r10d          # right = 0
0x432: d1 fa            sarl   %edx
0x434: 89 d0            movl   %edx, %eax
0x436: f7 d8            negl   %eax                 # right_heavy = -1
0x438: 4c 8b 4e 10      movq   0x10(%rsi), %r9
0x43c: 8f 4a 78 10 ...  bextrl $0x102, %r9d, %r13d
0x445: 49 83 e1 f8      andq   $-0x8, %r9
0x449: 4c 8b 1c ce      movq   (%rsi,%rcx,8), %r11  # child =
0xfffff80300000a78
0x44d: 41 8b 5b 10      movl   0x10(%r11), %ebx
0x451: 83 e3 03         andl   $0x3, %ebx
0x454: ff cb            decl   %ebx                 # child_bal = -1
0x456: 39 c3            cmpl   %eax, %ebx
0x458: 75 73            jne    0x4cd                # first if (...)
0x45a: 45 89 d6         movl   %r10d, %r14d
0x45d: 4f 8b 24 f3      movq   (%r11,%r14,8), %r12  # loads null
0x461: 4d 8b 3c cc      movq   (%r12,%rcx,8), %r15  # page fault %r12=0, %rcx=1
0x465: 4b 8b 1c f4      movq   (%r12,%r14,8), %rbx
0x469: 49 89 1c c8      movq   %rbx, (%r8,%rcx,8)
0x46d: 48 85 db         testq  %rbx, %rbx
0x470: 74 2c            je     0x49e                # if (gright != NULL)

-- 
You are receiving this mail because:
You are the assignee for the bug.