Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 01 Jun 2017 09:48:22 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-bugs@FreeBSD.org
Subject:   [Bug 219701] crash in camperiphfree()
Message-ID:  <bug-219701-8@https.bugs.freebsd.org/bugzilla/>

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

            Bug ID: 219701
           Summary: crash in camperiphfree()
           Product: Base System
           Version: CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: freebsd-bugs@FreeBSD.org
          Reporter: avg@FreeBSD.org

It seems that camperiphfree() has some unsafe code that can lead to a crash
when a peripheral is freed at the same time as an unrelated peripheral driv=
er
is added.

p_drv is a pointer into periph_drivers.  The pointer is used across
xpt_unlock_buses + xpt_lock_buses.  While the buses lock is dropped
periph_drivers could be pointed to a new memory location and the old memory
location would be freed.  See periphdriver_register() for details.
Thus, p_drv can end up pointing into the freed memory.  That would lead to a
crash or memory corruption while dereferencing the pointer.

I have actually experienced such a crash (happened during the kernel boot):
#3  0xffffffff80651f33 in panic (fmt=3D<unavailable>) at
/usr/src/sys/kern/kern_shutdown.c:594
#4  0xffffffff8085a190 in trap_fatal (frame=3D0xfffffe050536b430, eva=3D0) =
at
/usr/src/sys/amd64/amd64/trap.c:802
#5  0xffffffff80859737 in trap (frame=3D0xfffffe050536b430) at
/usr/src/sys/amd64/amd64/trap.c:198
#6  0xffffffff8085a4ba in trap_check (frame=3D0xfffffe050536b430) at
/usr/src/sys/amd64/amd64/trap.c:603
#7  <signal handler called>
#8  0xffffffff802a9cd8 in camperiphfree (periph=3D0xfffff800224f9300) at
/usr/src/sys/cam/cam_periph.c:712
#9  0xffffffff802a9bb2 in cam_periph_release_locked_buses
(periph=3D0xfffff800224f9300) at /usr/src/sys/cam/cam_periph.c:441
#10 0xffffffff802a9e7b in cam_periph_release_locked (periph=3D0xfffff800224=
f9300)
at /usr/src/sys/cam/cam_periph.c:452
#11 0xffffffff802bfeac in probedone (periph=3D<optimized out>,
done_ccb=3D0xfffff8000bfe1000) at /usr/src/sys/cam/scsi/scsi_xpt.c:1198
#12 0xffffffff802b13c3 in xpt_done_process (ccb_h=3D0xfffff8000bfe1000) at
/usr/src/sys/cam/cam_xpt.c:5452
#13 0xffffffff802b2965 in xpt_done_td (arg=3D0xffffffff80cf3880 <cam_doneqs=
>) at
/usr/src/sys/cam/cam_xpt.c:5479

(kgdb) fr 8
#8  0xffffffff802a9cd8 in camperiphfree (periph=3D0xfffff800224f9300) at
/usr/src/sys/cam/cam_periph.c:712
712             TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links);
(kgdb) p p_drv
$1 =3D (struct periph_driver **) 0xfffff80007330030
(kgdb) p *p_drv
$2 =3D (struct periph_driver *) 0xdeadc0dedeadc0d
(kgdb) p periph_drivers
$9 =3D (struct periph_driver **) 0xfffff800a81f4880

I think that we should cache the actual pointer to the peripheral driver ra=
ther
than the pointer into the array of pointers.

--=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-219701-8>