⬢ DragonFlyBSD Kernel Audit
DF-5117 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/misc/dcons/dcons_crom.c
+++ b/sys/dev/misc/dcons/dcons_crom.c
@@ dmamap_cb(void *arg, bus_dma_segment_t *segments, int seg, int error)
-	if (error)
+	if (error) {
 		kprintf("dcons_dmamap_cb: error=%d\n", error);
+		/* do not touch segments[] (uninitialized on error) and do
+		 * not publish a garbage address into the ConfigROM */
+		sc->load_error = error;
+		return;
+	}
 
 	sc = (struct dcons_crom_softc *)arg;
@@ dcons_crom_attach(device_t dev)
@@ 	struct dcons_crom_softc *sc;
@@ 
@@         sc = (struct dcons_crom_softc *) device_get_softc(dev);
@@ 	sc->fd.fc = device_get_ivars(dev);
@@ 	sc->fd.dev = dev;
@@ 	sc->fd.post_explore = NULL;
@@ 	sc->fd.post_busreset = (void *) dcons_crom_post_busreset;
 
 	/* map dcons buffer */
-	bus_dma_tag_create(
+	if (bus_dma_tag_create(
 		/*parent*/ sc->fd.fc->dmat,
 		/*alignment*/ sizeof(u_int32_t),
 		/*boundary*/ 0,
@@ 		/*flags*/ BUS_DMA_ALLOCNOW,
-		&sc->dma_tag);
-	bus_dmamap_create(sc->dma_tag, 0, &sc->dma_map);
-	bus_dmamap_load(sc->dma_tag, sc->dma_map,
+		&sc->dma_tag) != 0) {
+		device_printf(dev, "cannot create dma tag\n");
+		return (ENXIO);
+	}
+	if (bus_dmamap_create(sc->dma_tag, 0, &sc->dma_map) != 0) {
+		device_printf(dev, "cannot create dma map\n");
+		bus_dma_tag_destroy(sc->dma_tag);
+		return (ENXIO);
+	}
+	bus_dmamap_load(sc->dma_tag, sc->dma_map,
 	    (void *)dcons_conf->buf, dcons_conf->size,
 	    dmamap_cb, sc, 0);
+	if (sc->load_error) {
+		device_printf(dev, "dma map load failed (%d)\n", sc->load_error);
+		bus_dmamap_destroy(sc->dma_tag, sc->dma_map);
+		bus_dma_tag_destroy(sc->dma_tag);
+		return (ENXIO);
+	}
 	return (0);
```
(struct dcons_crom_softc gains `int load_error;`)