summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorariff <ariff@FreeBSD.org>2007-03-15 16:41:27 +0000
committerariff <ariff@FreeBSD.org>2007-03-15 16:41:27 +0000
commit2de8168c3fd8f063e61cd20eda0fdd329a5bd131 (patch)
treed884183f5f2b6415baec7ed56444b465df96b56a
parent48dd70126224a7269bc4cb5c7c3cf730ace40c7b (diff)
downloadFreeBSD-src-2de8168c3fd8f063e61cd20eda0fdd329a5bd131.zip
FreeBSD-src-2de8168c3fd8f063e61cd20eda0fdd329a5bd131.tar.gz
Fix severe out-of-bound mtx "type" pointer, causing WITNESS refcount
confusions and panic provided that the following conditions are met: 1) WITNESS is enabled (watch/trace). 2) Using modules, instead of statically linked (Not a strict requirement, but easier to reproduce this way). 3) 2 or more modules share the same mtx type ("sound softc"). - They might share the same name (strcmp() == 0), but it always point to different address. 4) Repetitive kldunload/load on any module that shares the same mtx type (Not a strict requirement, but easier to reproduce this way). Consider module A and module B: - From enroll() - subr_witness.c: * Load module A. Everything seems fine right now. wA-w_refcount == 1 ; wA-w_name = "sound softc" * Load module B. * w->w_name == description will always fail. ("sound softc" from A and B point to different address). * wA->w_refcount > 0 && strcmp(description, wA->w_name) == 0 * enroll() will return wA instead of returning (possibly unique) wB. wA->w_refcount++ , == 2. * Unload module A, mtx_destroy(), wA->w_name become invalid, but wA->w_refcount-- become 1 instead of 0. wA will not be removed from witness list. * Some other places call mtx_init(), iterating witness list, found wA, failed on wA->w_name == description * wA->w_refcount > 0 && strcmp(description, wA->w_name) * Panic on strcmp() since wA->w_name no longer point to valid address. Note that this could happened in other places as well, not just sound (eg. consider lots of drivers that share simmilar MTX_NETWORK_LOCK). Solutions (for sound case): 1) Provide unique mtx type string for each mutex creation (chosen) or 2) Put "sound softc" global variable somewhere and use it.
-rw-r--r--sys/dev/sound/isa/ad1816.c3
-rw-r--r--sys/dev/sound/isa/mss.c2
-rw-r--r--sys/dev/sound/isa/sbc.c3
-rw-r--r--sys/dev/sound/pci/als4000.c2
-rw-r--r--sys/dev/sound/pci/atiixp.c2
-rw-r--r--sys/dev/sound/pci/cmi.c2
-rw-r--r--sys/dev/sound/pci/ds1.c2
-rw-r--r--sys/dev/sound/pci/emu10k1.c2
-rw-r--r--sys/dev/sound/pci/emu10kx-pcm.c2
-rw-r--r--sys/dev/sound/pci/envy24.c4
-rw-r--r--sys/dev/sound/pci/envy24ht.c5
-rw-r--r--sys/dev/sound/pci/es137x.c2
-rw-r--r--sys/dev/sound/pci/ich.c2
-rw-r--r--sys/dev/sound/pci/maestro.c2
-rw-r--r--sys/dev/sound/pci/maestro3.c7
-rw-r--r--sys/dev/sound/pci/solo.c2
-rw-r--r--sys/dev/sound/pci/t4dwave.c2
-rw-r--r--sys/dev/sound/pci/via8233.c3
-rw-r--r--sys/dev/sound/pci/via82c686.c3
-rw-r--r--sys/dev/sound/sbus/cs4231.c7
20 files changed, 25 insertions, 34 deletions
diff --git a/sys/dev/sound/isa/ad1816.c b/sys/dev/sound/isa/ad1816.c
index 283f66f..eb05e5e 100644
--- a/sys/dev/sound/isa/ad1816.c
+++ b/sys/dev/sound/isa/ad1816.c
@@ -601,7 +601,8 @@ ad1816_attach(device_t dev)
ad1816 = (struct ad1816_info *)malloc(sizeof *ad1816, M_DEVBUF, M_NOWAIT | M_ZERO);
if (!ad1816) return ENXIO;
- ad1816->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
+ ad1816->lock = snd_mtxcreate(device_get_nameunit(dev),
+ "snd_ad1816 softc");
ad1816->io_rid = 2;
ad1816->irq_rid = 0;
ad1816->drq1_rid = 0;
diff --git a/sys/dev/sound/isa/mss.c b/sys/dev/sound/isa/mss.c
index 22af6e7..4820eed 100644
--- a/sys/dev/sound/isa/mss.c
+++ b/sys/dev/sound/isa/mss.c
@@ -1696,7 +1696,7 @@ mss_doattach(device_t dev, struct mss_info *mss)
int pdma, rdma, flags = device_get_flags(dev);
char status[SND_STATUSLEN], status2[SND_STATUSLEN];
- mss->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
+ mss->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_mss softc");
mss->bufsize = pcm_getbuffersize(dev, 4096, MSS_DEFAULT_BUFSZ, 65536);
if (!mss_alloc_resources(mss, dev)) goto no;
mss_init(mss, dev);
diff --git a/sys/dev/sound/isa/sbc.c b/sys/dev/sound/isa/sbc.c
index ef4b119..9cbe523 100644
--- a/sys/dev/sound/isa/sbc.c
+++ b/sys/dev/sound/isa/sbc.c
@@ -120,7 +120,8 @@ static void sb_setmixer(struct resource *io, u_int port, u_int value);
static void
sbc_lockinit(struct sbc_softc *scp)
{
- scp->lock = snd_mtxcreate(device_get_nameunit(scp->dev), "sound softc");
+ scp->lock = snd_mtxcreate(device_get_nameunit(scp->dev),
+ "snd_sbc softc");
}
static void
diff --git a/sys/dev/sound/pci/als4000.c b/sys/dev/sound/pci/als4000.c
index 892b21f..8f2d4ad 100644
--- a/sys/dev/sound/pci/als4000.c
+++ b/sys/dev/sound/pci/als4000.c
@@ -803,7 +803,7 @@ als_pci_attach(device_t dev)
return ENXIO;
}
- sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
+ sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_als4000 softc");
sc->dev = dev;
data = pci_read_config(dev, PCIR_COMMAND, 2);
diff --git a/sys/dev/sound/pci/atiixp.c b/sys/dev/sound/pci/atiixp.c
index 3de48c1..d3e988a 100644
--- a/sys/dev/sound/pci/atiixp.c
+++ b/sys/dev/sound/pci/atiixp.c
@@ -1134,7 +1134,7 @@ atiixp_pci_attach(device_t dev)
return (ENXIO);
}
- sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
+ sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_atiixp softc");
sc->dev = dev;
callout_init(&sc->poll_timer, CALLOUT_MPSAFE);
diff --git a/sys/dev/sound/pci/cmi.c b/sys/dev/sound/pci/cmi.c
index e5f7eb1..589f15a 100644
--- a/sys/dev/sound/pci/cmi.c
+++ b/sys/dev/sound/pci/cmi.c
@@ -929,7 +929,7 @@ cmi_attach(device_t dev)
return ENXIO;
}
- sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
+ sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_cmi softc");
data = pci_read_config(dev, PCIR_COMMAND, 2);
data |= (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN);
pci_write_config(dev, PCIR_COMMAND, data, 2);
diff --git a/sys/dev/sound/pci/ds1.c b/sys/dev/sound/pci/ds1.c
index c9f0428..782a3a5 100644
--- a/sys/dev/sound/pci/ds1.c
+++ b/sys/dev/sound/pci/ds1.c
@@ -948,7 +948,7 @@ ds_pci_attach(device_t dev)
return ENXIO;
}
- sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
+ sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_ds1 softc");
sc->dev = dev;
subdev = (pci_get_subdevice(dev) << 16) | pci_get_subvendor(dev);
sc->type = ds_finddev(pci_get_devid(dev), subdev);
diff --git a/sys/dev/sound/pci/emu10k1.c b/sys/dev/sound/pci/emu10k1.c
index 68b89d8..d3cea09 100644
--- a/sys/dev/sound/pci/emu10k1.c
+++ b/sys/dev/sound/pci/emu10k1.c
@@ -1986,7 +1986,7 @@ emu_pci_attach(device_t dev)
return ENXIO;
}
- sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
+ sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_emu10k1 softc");
sc->dev = dev;
sc->type = pci_get_devid(dev);
sc->rev = pci_get_revid(dev);
diff --git a/sys/dev/sound/pci/emu10kx-pcm.c b/sys/dev/sound/pci/emu10kx-pcm.c
index 2ee69ff..1aab355 100644
--- a/sys/dev/sound/pci/emu10kx-pcm.c
+++ b/sys/dev/sound/pci/emu10kx-pcm.c
@@ -1016,7 +1016,7 @@ emu_pcm_attach(device_t dev)
return (ENXIO);
}
- sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
+ sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_emu10kx softc");
sc->dev = dev;
r = BUS_READ_IVAR(device_get_parent(dev), dev, EMU_VAR_ISEMU10K1, &is_emu10k1);
diff --git a/sys/dev/sound/pci/envy24.c b/sys/dev/sound/pci/envy24.c
index 8de3c3b..b65b491 100644
--- a/sys/dev/sound/pci/envy24.c
+++ b/sys/dev/sound/pci/envy24.c
@@ -2371,7 +2371,6 @@ envy24_pci_attach(device_t dev)
u_int32_t data;
struct sc_info *sc;
char status[SND_STATUSLEN];
- char name[ENVY24_NAMELEN];
int err = 0;
int i;
@@ -2385,8 +2384,7 @@ envy24_pci_attach(device_t dev)
}
bzero(sc, sizeof(*sc));
- snprintf(name, ENVY24_NAMELEN, "%s:envy24", device_get_nameunit(dev));
- sc->lock = snd_mtxcreate(name, name);
+ sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_envy24 softc");
sc->dev = dev;
/* initialize PCI interface */
diff --git a/sys/dev/sound/pci/envy24ht.c b/sys/dev/sound/pci/envy24ht.c
index c2ff685..e11a99b 100644
--- a/sys/dev/sound/pci/envy24ht.c
+++ b/sys/dev/sound/pci/envy24ht.c
@@ -2390,7 +2390,6 @@ envy24ht_pci_attach(device_t dev)
u_int32_t data;
struct sc_info *sc;
char status[SND_STATUSLEN];
- char name[ENVY24HT_NAMELEN];
int err = 0;
int i;
@@ -2404,8 +2403,8 @@ envy24ht_pci_attach(device_t dev)
}
bzero(sc, sizeof(*sc));
- snprintf(name, ENVY24HT_NAMELEN, "%s:envy24ht", device_get_nameunit(dev));
- sc->lock = snd_mtxcreate(name, name);
+ sc->lock = snd_mtxcreate(device_get_nameunit(dev),
+ "snd_envy24ht softc");
sc->dev = dev;
/* initialize PCI interface */
diff --git a/sys/dev/sound/pci/es137x.c b/sys/dev/sound/pci/es137x.c
index 5d2ba37..261e9b7 100644
--- a/sys/dev/sound/pci/es137x.c
+++ b/sys/dev/sound/pci/es137x.c
@@ -1654,7 +1654,7 @@ es_pci_attach(device_t dev)
device_printf(dev, "cannot allocate softc\n");
return (ENXIO);
}
- es->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
+ es->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_es137x softc");
es->dev = dev;
es->escfg = 0;
mapped = 0;
diff --git a/sys/dev/sound/pci/ich.c b/sys/dev/sound/pci/ich.c
index 6d45930..9b07c1f 100644
--- a/sys/dev/sound/pci/ich.c
+++ b/sys/dev/sound/pci/ich.c
@@ -851,7 +851,7 @@ ich_pci_attach(device_t dev)
return (ENXIO);
}
- sc->ich_lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
+ sc->ich_lock = snd_mtxcreate(device_get_nameunit(dev), "snd_ich softc");
sc->dev = dev;
vendor = sc->vendor = pci_get_vendor(dev);
diff --git a/sys/dev/sound/pci/maestro.c b/sys/dev/sound/pci/maestro.c
index 124d98d..d81effe 100644
--- a/sys/dev/sound/pci/maestro.c
+++ b/sys/dev/sound/pci/maestro.c
@@ -1781,7 +1781,7 @@ agg_attach(device_t dev)
ess->dev = dev;
#ifdef USING_MUTEX
- mtx_init(&ess->lock, device_get_desc(dev), "hardware status lock",
+ mtx_init(&ess->lock, device_get_desc(dev), "snd_maestro softc",
MTX_DEF | MTX_RECURSE);
if (!mtx_initialized(&ess->lock)) {
device_printf(dev, "failed to create a mutex.\n");
diff --git a/sys/dev/sound/pci/maestro3.c b/sys/dev/sound/pci/maestro3.c
index e8454f2..3ccfeb7 100644
--- a/sys/dev/sound/pci/maestro3.c
+++ b/sys/dev/sound/pci/maestro3.c
@@ -1267,12 +1267,7 @@ m3_pci_attach(device_t dev)
sc->dev = dev;
sc->type = pci_get_devid(dev);
sc->sc_lock = snd_mtxcreate(device_get_nameunit(dev),
- "sound softc");
- if (sc->sc_lock == NULL) {
- device_printf(dev, "cannot create mutex\n");
- free(sc, M_DEVBUF);
- return (ENXIO);
- }
+ "snd_maestro3 softc");
for (card = m3_card_types ; card->pci_id ; card++) {
if (sc->type == card->pci_id) {
sc->which = card->which;
diff --git a/sys/dev/sound/pci/solo.c b/sys/dev/sound/pci/solo.c
index cb78403..c3de20c 100644
--- a/sys/dev/sound/pci/solo.c
+++ b/sys/dev/sound/pci/solo.c
@@ -897,7 +897,7 @@ ess_alloc_resources(struct ess_info *sc, device_t dev)
RF_ACTIVE | RF_SHAREABLE);
#if ESS18XX_MPSAFE == 1
- sc->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
+ sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_solo softc");
return (sc->irq && sc->io && sc->sb && sc->vc &&
sc->mpu && sc->gp && sc->lock)? 0 : ENXIO;
diff --git a/sys/dev/sound/pci/t4dwave.c b/sys/dev/sound/pci/t4dwave.c
index 76f5867..ff8d4a3 100644
--- a/sys/dev/sound/pci/t4dwave.c
+++ b/sys/dev/sound/pci/t4dwave.c
@@ -821,7 +821,7 @@ tr_pci_attach(device_t dev)
tr->type = pci_get_devid(dev);
tr->rev = pci_get_revid(dev);
- tr->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
+ tr->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_t4dwave softc");
data = pci_read_config(dev, PCIR_COMMAND, 2);
data |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
diff --git a/sys/dev/sound/pci/via8233.c b/sys/dev/sound/pci/via8233.c
index 8667ea1..eca8d11 100644
--- a/sys/dev/sound/pci/via8233.c
+++ b/sys/dev/sound/pci/via8233.c
@@ -1123,7 +1123,8 @@ via_attach(device_t dev)
device_printf(dev, "cannot allocate softc\n");
return (ENXIO);
}
- via->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
+ via->lock = snd_mtxcreate(device_get_nameunit(dev),
+ "snd_via8233 softc");
callout_init(&via->poll_timer, CALLOUT_MPSAFE);
via->poll_ticks = 1;
diff --git a/sys/dev/sound/pci/via82c686.c b/sys/dev/sound/pci/via82c686.c
index 2b73e1f..46800c7 100644
--- a/sys/dev/sound/pci/via82c686.c
+++ b/sys/dev/sound/pci/via82c686.c
@@ -481,7 +481,8 @@ via_attach(device_t dev)
device_printf(dev, "cannot allocate softc\n");
return ENXIO;
}
- via->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
+ via->lock = snd_mtxcreate(device_get_nameunit(dev),
+ "snd_via82c686 softc");
/* Get resources */
data = pci_read_config(dev, PCIR_COMMAND, 2);
diff --git a/sys/dev/sound/sbus/cs4231.c b/sys/dev/sound/sbus/cs4231.c
index d463392..ed070b7 100644
--- a/sys/dev/sound/sbus/cs4231.c
+++ b/sys/dev/sound/sbus/cs4231.c
@@ -375,12 +375,7 @@ cs4231_attach_common(struct cs4231_softc *sc)
int i;
sc->sc_lock = snd_mtxcreate(device_get_nameunit(sc->sc_dev),
- "sound softc");
- if (sc->sc_lock == NULL) {
- device_printf(sc->sc_dev, "cannot create mutex\n");
- free(sc, M_DEVBUF);
- return (ENXIO);
- }
+ "snd_cs4231 softc");
for (i = 0; i < sc->sc_nmres; i++) {
sc->sc_rid[i] = i;
OpenPOWER on IntegriCloud