> From: "Theo de Raadt" <dera...@openbsd.org> > Date: Fri, 30 Sep 2016 09:38:30 -0600 > > > Diff below is a possible way to fix this. But in a way we're cheating > > here since we'll still consume more than 2047 bytes of stack space > > when we descend into wskbd_initmute(). So perhaps we should rewrite > > this code to dynamically allocate the mixer_devinfo structs? > > yes, it should be dynamically allocated.
Here's a diff that does that. As far as I can tell (playing "My favourite hacks") this causes bo regressions on my x1 rev 3. ok? Index: dev/audio.c =================================================================== RCS file: /cvs/src/sys/dev/audio.c,v retrieving revision 1.153 diff -u -p -r1.153 audio.c --- dev/audio.c 19 Sep 2016 06:46:43 -0000 1.153 +++ dev/audio.c 2 Oct 2016 17:33:56 -0000 @@ -1786,45 +1786,57 @@ audiopoll(dev_t dev, int events, struct int wskbd_initmute(struct audio_softc *sc, struct mixer_devinfo *vol) { - struct mixer_devinfo mi; + struct mixer_devinfo *mi; + int index = -1; - mi.index = vol->next; - for (mi.index = vol->next; mi.index != -1; mi.index = mi.next) { - if (sc->ops->query_devinfo(sc->arg, &mi) != 0) + mi = malloc(sizeof(struct mixer_devinfo), M_TEMP, M_WAITOK); + + for (mi->index = vol->next; mi->index != -1; mi->index = mi->next) { + if (sc->ops->query_devinfo(sc->arg, mi) != 0) + break; + if (strcmp(mi->label.name, AudioNmute) == 0) { + index = mi->index; break; - if (strcmp(mi.label.name, AudioNmute) == 0) - return mi.index; + } } - return -1; + + free(mi, M_TEMP, sizeof(struct mixer_devinfo)); + return index; } int wskbd_initvol(struct audio_softc *sc, struct wskbd_vol *vol, char *cn, char *dn) { - struct mixer_devinfo dev, cls; + struct mixer_devinfo *dev, *cls; - for (dev.index = 0; ; dev.index++) { - if (sc->ops->query_devinfo(sc->arg, &dev) != 0) + vol->val = vol->mute = -1; + dev = malloc(sizeof(struct mixer_devinfo), M_TEMP, M_WAITOK); + cls = malloc(sizeof(struct mixer_devinfo), M_TEMP, M_WAITOK); + + for (dev->index = 0; ; dev->index++) { + if (sc->ops->query_devinfo(sc->arg, dev) != 0) break; - if (dev.type != AUDIO_MIXER_VALUE) + if (dev->type != AUDIO_MIXER_VALUE) continue; - cls.index = dev.mixer_class; - if (sc->ops->query_devinfo(sc->arg, &cls) != 0) + cls->index = dev->mixer_class; + if (sc->ops->query_devinfo(sc->arg, cls) != 0) continue; - if (strcmp(cls.label.name, cn) == 0 && - strcmp(dev.label.name, dn) == 0) { - vol->val = dev.index; - vol->nch = dev.un.v.num_channels; - vol->step = dev.un.v.delta > 8 ? dev.un.v.delta : 8; - vol->mute = wskbd_initmute(sc, &dev); + if (strcmp(cls->label.name, cn) == 0 && + strcmp(dev->label.name, dn) == 0) { + vol->val = dev->index; + vol->nch = dev->un.v.num_channels; + vol->step = dev->un.v.delta > 8 ? dev->un.v.delta : 8; + vol->mute = wskbd_initmute(sc, dev); vol->val_pending = vol->mute_pending = 0; - DPRINTF("%s: wskbd using %s.%s%s\n", - DEVNAME(sc), cn, dn, vol->mute >= 0 ? ", mute control" : ""); - return 1; + DPRINTF("%s: wskbd using %s.%s%s\n", DEVNAME(sc), + cn, dn, vol->mute >= 0 ? ", mute control" : ""); + break; } } - vol->val = vol->mute = -1; - return 0; + + free(cls, M_TEMP, sizeof(struct mixer_devinfo)); + free(dev, M_TEMP, sizeof(struct mixer_devinfo)); + return (vol->val != -1); } void