> 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

Reply via email to