Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Feb 2017 23:59:36 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-bugs@FreeBSD.org
Subject:   [Bug 217282] panics during bootup due to a race between vt_change_font() and termcn_cnputc()
Message-ID:  <bug-217282-8@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D217282

            Bug ID: 217282
           Summary: panics during bootup due to a race between
                    vt_change_font() and termcn_cnputc()
           Product: Base System
           Version: CURRENT
          Hardware: amd64
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: freebsd-bugs@FreeBSD.org
          Reporter: jtl@freebsd.org

Running an internal fork of FreeBSD -CURRENT (synced as of r312388), we have
had several machines crash early in bootup with backtraces such as these:
  db> bt
  Tracing pid 20 tid 100135 td 0xfffff80015090500
  vga_bitblt_one_text_pixels_block() at
vga_bitblt_one_text_pixels_block+0x135/frame 0xfffffe15a81af570
  vga_bitblt_text() at vga_bitblt_text+0xd0/frame 0xfffffe15a81af5d0
  vt_flush() at vt_flush+0x2ae/frame 0xfffffe15a81af610
  termcn_cnputc() at termcn_cnputc+0x108/frame 0xfffffe15a81af650
  cnputc() at cnputc+0x6d/frame 0xfffffe15a81af680
  cnputs() at cnputs+0xd8/frame 0xfffffe15a81af6a0
  putchar() at putchar+0x15e/frame 0xfffffe15a81af720
  kvprintf() at kvprintf+0x119/frame 0xfffffe15a81af830
  _vprintf() at _vprintf+0x8d/frame 0xfffffe15a81af910
  printf() at printf+0x53/frame 0xfffffe15a81af970
  g_mirror_update_device() at g_mirror_update_device+0x8aa/frame
0xfffffe15a81af9b0
  g_mirror_worker() at g_mirror_worker+0x1709/frame 0xfffffe15a81afa70
  fork_exit() at fork_exit+0x85/frame 0xfffffe15a81afab0
  fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe15a81afab0
  --- trap 0, rip =3D 0, rsp =3D 0, rbp =3D 0 ---


This appears to be occurring in /FreeBSD/sys/dev/vt/hw/vga/vt_vga.c at line
648:
  c =3D VTBUF_GET_FIELD(vb, row, col);


It is crashing while trying to extract the column from the array of rows. (=
In
other words, the row points to a NULL value.)


There are 500 rows:
  db> x/lx 0xffffffff80d638c0
  vt_conswindow+0x38:     1f4


The code is trying to access row 383:
  rdx                      0x17f


And, that does indeed point to a NULL column:
  db> x/gx 0xfffff80015886bf8
  0xfffff80015886bf8:     fffffe000493eec0
  db> x/gx 0xfffffe000493eec0
  0xfffffe000493eec0:     0


However, this other thread was running at the same time:
  db> bt 100000
  Tracing pid 0 tid 100000 td 0xffffffff81020020
  cpustop_handler() at cpustop_handler+0x28/frame 0xfffffe1362b62d40
  ipi_nmi_handler() at ipi_nmi_handler+0x4a/frame 0xfffffe1362b62d60
  trap() at trap+0x3a/frame 0xfffffe1362b62f20
  nmi_calltrap() at nmi_calltrap+0x8/frame 0xfffffe1362b62f20
  --- trap 0x13, rip =3D 0xffffffff807f683a, rsp =3D 0xffffffff815369a0, rb=
p =3D
0xffffffff815369a0 ---
  bcopy() at bcopy+0x1a/frame 0xffffffff815369a0
  memmove() at memmove+0x14/frame 0xffffffff815369c0
  vtbuf_grow() at vtbuf_grow+0x2d5/frame 0xffffffff81536a50
  vt_change_font() at vt_change_font+0x1ac/frame 0xffffffff81536ac0
  vt_upgrade() at vt_upgrade+0x66c/frame 0xffffffff81536b50
  mi_startup() at mi_startup+0x118/frame 0xffffffff81536b70
  btext() at btext+0x2c


It looks like there is a race condition between vt_change_font() and
termcn_cnputc().

vt_change_font() calls vtbuf_grow(), which messes around with the vt data
structures. (In fact, vtbuf_grow() was in the middle of re-initializing the=
se
row data structures, which is probably why they were NULL.) vt_change_font()
uses terminal_mute() to keep the terminal from using the vt data structures
during the vtbuf_grow() call.

That is all well and good except that termcn_cnputc() drops the terminal lo=
ck
(and, necessarily, doesn't check if TF_MUTE is set) prior to running
tm->tm_class->tc_done(tm). And, the tc_done function points to vtterm_done(=
),
which calls vt_flush(), which eventually tries to read from those data
structures.

So, some sort of locking change is needed here to prevent the terminal from
using the vt data structures while they are being re-initialized.

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-217282-8>