> From: "Theo de Raadt" <[email protected]>
> 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