[Bug 220032][PATCH] if_alc: Fix possible sleep-under-mutex bugs

Jia-Ju Bai baijiaju1990 at 163.com
Sun Jun 18 09:04:26 UTC 2017


The alc driver may sleep under a mutex, and the function call paths in file
"sys/dev/alc/if_alc.c" are:
alc_resume [acquire the mutex]
  alc_init_locked
    alc_init_rx_ring
      alc_newbuf
        bus_dmamap_load_mbuf_sg(BUS_DMA_WAITOK) --> may sleep
alc_start [acquire the mutex]
  alc_start_locked
    alc_encap
      bus_dmamap_load_mbuf_sg(BUS_DMA_WAITOK) --> may sleep

The possible fix of these bugs is to set the last parameter in
bus_dmamap_load_mbuf_sg to "BUS_DMA_NOWAIT".

This bug is found by a static analysis tool written by myself, and it is
checked by my review of the FreeBSD code.

Signed-off-by: Jia-Ju Bai <baijiaju1990 at 163.com>
---
 sys/dev/alc/if_alc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c
index ca7ae9d17b5..cb0f15e223b 100644
--- a/sys/dev/alc/if_alc.c
+++ b/sys/dev/alc/if_alc.c
@@ -2795,7 +2795,7 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head)
 	map = txd->tx_dmamap;
 
 	error = bus_dmamap_load_mbuf_sg(sc->alc_cdata.alc_tx_tag, map,
-	    *m_head, txsegs, &nsegs, 0);
+	    *m_head, txsegs, &nsegs, BUS_DMA_NOWAIT);
 	if (error == EFBIG) {
 		m = m_collapse(*m_head, M_NOWAIT, ALC_MAXTXSEGS);
 		if (m == NULL) {
@@ -2805,7 +2805,7 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head)
 		}
 		*m_head = m;
 		error = bus_dmamap_load_mbuf_sg(sc->alc_cdata.alc_tx_tag, map,
-		    *m_head, txsegs, &nsegs, 0);
+		    *m_head, txsegs, &nsegs, BUS_DMA_NOWAIT);
 		if (error != 0) {
 			m_freem(*m_head);
 			*m_head = NULL;
@@ -3487,7 +3487,7 @@ alc_newbuf(struct alc_softc *sc, struct alc_rxdesc *rxd)
 #endif
 
 	if (bus_dmamap_load_mbuf_sg(sc->alc_cdata.alc_rx_tag,
-	    sc->alc_cdata.alc_rx_sparemap, m, segs, &nsegs, 0) != 0) {
+	    sc->alc_cdata.alc_rx_sparemap, m, segs, &nsegs, BUS_DMA_NOWAIT) != 0) {
 		m_freem(m);
 		return (ENOBUFS);
 	}
-- 
2.13.0




More information about the freebsd-net mailing list