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.
This commit is contained in:
parent
8d5162b9da
commit
4582b3a100
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user