]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
Merge r320602 from stable/11 into releng/11.1:
authorken <ken@FreeBSD.org>
Mon, 3 Jul 2017 18:20:45 +0000 (18:20 +0000)
committerken <ken@FreeBSD.org>
Mon, 3 Jul 2017 18:20:45 +0000 (18:20 +0000)
commitff3a058c4f832f66c1a779cf9bd05f758ad411d8
tree1829e96668a3f98555e55d7a73825593d7c74145
parent1d493faa56da15954ddeb137d269e6ef887b6f6f
Merge r320602 from stable/11 into releng/11.1:
  ------------------------------------------------------------------------
  r320602 | ken | 2017-07-03 09:34:21 -0600 (Mon, 03 Jul 2017) | 45 lines

  MFC r320421:

    ------------------------------------------------------------------------
    r320421 | ken | 2017-06-27 13:26:02 -0600 (Tue, 27 Jun 2017) | 37 lines

    Fix a panic in camperiphfree().

    If a peripheral driver (e.g. da, sa, cd) is added or removed from the
    peripheral driver list while an unrelated peripheral driver instance (e.g.
    da0, sa5, cd2) is going away and is inside camperiphfree(), we could
    dereference an invalid pointer.

    When peripheral drivers are added or removed (see periphdriver_register()
    and periphdriver_unregister()), the peripheral driver array is resized
    and existing entries are moved.

    Although we hold the topology lock while we traverse the peripheral driver
    list, we retain a pointer to the location of the peripheral driver pointer
    and then drop the topology lock.  So we are still vulnerable to the list
    getting moved around while the lock is dropped.

    To solve the problem, cache a copy of the peripheral driver pointer.  If
    its storage location in the list changes while we have the lock dropped, it
    won't have any effect.

    This doesn't solve the issue that peripheral drivers ("da", "cd", as opposed
    to individual instances like "da0", "cd0") are not generally part of a
    reference counting scheme to guard against deregistering them while there
    are instances active.  The caller (generally the person unloading a module)
    has to be aware of active drivers and not unload something that is in use.

    sys/cam/cam_periph.c:
     In camperiphfree(), cache a pointer to the peripheral driver
     instance to avoid holding a pointer to an invalid memory location
     in the event that the peripheral driver list changes while we have
     the topology lock dropped.

    PR: kern/219701
    Submitted by: avg
    Sponsored by: Spectra Logic

    ------------------------------------------------------------------------
  ------------------------------------------------------------------------

Approved by: re (gjb)
sys/cam/cam_periph.c