[Bug 219701] crash in camperiphfree()
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Thu Jun 1 09:48:22 UTC 2017
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=219701
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 at FreeBSD.org
Reporter: avg at 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 driver
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=<unavailable>) at
/usr/src/sys/kern/kern_shutdown.c:594
#4 0xffffffff8085a190 in trap_fatal (frame=0xfffffe050536b430, eva=0) at
/usr/src/sys/amd64/amd64/trap.c:802
#5 0xffffffff80859737 in trap (frame=0xfffffe050536b430) at
/usr/src/sys/amd64/amd64/trap.c:198
#6 0xffffffff8085a4ba in trap_check (frame=0xfffffe050536b430) at
/usr/src/sys/amd64/amd64/trap.c:603
#7 <signal handler called>
#8 0xffffffff802a9cd8 in camperiphfree (periph=0xfffff800224f9300) at
/usr/src/sys/cam/cam_periph.c:712
#9 0xffffffff802a9bb2 in cam_periph_release_locked_buses
(periph=0xfffff800224f9300) at /usr/src/sys/cam/cam_periph.c:441
#10 0xffffffff802a9e7b in cam_periph_release_locked (periph=0xfffff800224f9300)
at /usr/src/sys/cam/cam_periph.c:452
#11 0xffffffff802bfeac in probedone (periph=<optimized out>,
done_ccb=0xfffff8000bfe1000) at /usr/src/sys/cam/scsi/scsi_xpt.c:1198
#12 0xffffffff802b13c3 in xpt_done_process (ccb_h=0xfffff8000bfe1000) at
/usr/src/sys/cam/cam_xpt.c:5452
#13 0xffffffff802b2965 in xpt_done_td (arg=0xffffffff80cf3880 <cam_doneqs>) at
/usr/src/sys/cam/cam_xpt.c:5479
(kgdb) fr 8
#8 0xffffffff802a9cd8 in camperiphfree (periph=0xfffff800224f9300) at
/usr/src/sys/cam/cam_periph.c:712
712 TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links);
(kgdb) p p_drv
$1 = (struct periph_driver **) 0xfffff80007330030
(kgdb) p *p_drv
$2 = (struct periph_driver *) 0xdeadc0dedeadc0d
(kgdb) p periph_drivers
$9 = (struct periph_driver **) 0xfffff800a81f4880
I think that we should cache the actual pointer to the peripheral driver rather
than the pointer into the array of pointers.
--
You are receiving this mail because:
You are the assignee for the bug.
More information about the freebsd-bugs
mailing list