]> git.alsa-project.org Git - alsa-lib.git/commitdiff
coverity.com fixes - initial round
authorJaroslav Kysela <perex@perex.cz>
Mon, 10 Nov 2025 16:56:27 +0000 (17:56 +0100)
committerJaroslav Kysela <perex@perex.cz>
Wed, 12 Nov 2025 14:36:29 +0000 (15:36 +0100)
This commit tries to fix a bunch of issues found
by coverity.com.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
40 files changed:
aserver/aserver.c
src/async.c
src/conf.c
src/control/control_remap.c
src/control/control_shm.c
src/control/namehint.c
src/control/setup.c
src/error.c
src/mixer/simple_abst.c
src/mixer/simple_none.c
src/pcm/pcm.c
src/pcm/pcm_direct.c
src/pcm/pcm_dmix_x86_64.c
src/pcm/pcm_dshare.c
src/pcm/pcm_dsnoop.c
src/pcm/pcm_file.c
src/pcm/pcm_hw.c
src/pcm/pcm_ladspa.c
src/pcm/pcm_meter.c
src/pcm/pcm_misc.c
src/pcm/pcm_mulaw.c
src/pcm/pcm_multi.c
src/pcm/pcm_params.c
src/pcm/pcm_plug.c
src/pcm/pcm_rate.c
src/pcm/pcm_route.c
src/pcm/pcm_share.c
src/pcm/pcm_shm.c
src/rawmidi/rawmidi_virt.c
src/rawmidi/ump.c
src/seq/seqmid.c
src/topology/builder.c
src/topology/ctl.c
src/topology/dapm.c
src/topology/data.c
src/topology/ops.c
src/ucm/main.c
src/ucm/ucm_cond.c
src/ucm/ucm_regex.c
src/ucm/ucm_subs.c

index 823b345c6f13a696996bc7fdac946dcf3ed865f1..1ef6ef5677f3d73bde99c28120802ea759e0413f 100644 (file)
@@ -221,7 +221,7 @@ LIST_HEAD(inet_pendings);
 static int pcm_handler(waiter_t *waiter, unsigned short events)
 {
        client_t *client = waiter->private_data;
-       char buf[1];
+       char buf[1] = {0};
        ssize_t n;
        if (events & POLLIN) {
                n = write(client->poll_fd, buf, 1);
@@ -321,17 +321,19 @@ static int pcm_shm_open(client_t *client, int *cookie)
 
 static int pcm_shm_close(client_t *client)
 {
+       snd_pcm_shm_ctrl_t *ctrl;
        int err;
-       snd_pcm_shm_ctrl_t *ctrl = client->transport.shm.ctrl;
+
        if (client->polling) {
                del_waiter(client->device.pcm.fd);
                client->polling = 0;
        }
        err = snd_pcm_close(client->device.pcm.handle);
-       ctrl->result = err;
        if (err < 0)
                ERROR("snd_pcm_close");
-       if (client->transport.shm.ctrl) {
+       ctrl = client->transport.shm.ctrl;
+       if (ctrl) {
+               ctrl->result = err;
                err = shmdt((void *)client->transport.shm.ctrl);
                if (err < 0)
                        SYSERROR("shmdt failed");
@@ -348,7 +350,7 @@ static int shm_ack(client_t *client)
 {
        struct pollfd pfd;
        int err;
-       char buf[1];
+       char buf[1] = {0};
        pfd.fd = client->ctrl_fd;
        pfd.events = POLLHUP;
        if (poll(&pfd, 1, 0) == 1)
@@ -531,7 +533,7 @@ transport_ops_t pcm_shm_ops = {
 static int ctl_handler(waiter_t *waiter, unsigned short events)
 {
        client_t *client = waiter->private_data;
-       char buf[1] = "";
+       char buf[1] = {0};
        ssize_t n;
        if (events & POLLIN) {
                n = write(client->poll_fd, buf, 1);
@@ -585,16 +587,17 @@ static int ctl_shm_open(client_t *client, int *cookie)
 static int ctl_shm_close(client_t *client)
 {
        int err;
-       snd_ctl_shm_ctrl_t *ctrl = client->transport.shm.ctrl;
+       snd_ctl_shm_ctrl_t *ctrl;
        if (client->polling) {
                del_waiter(client->device.ctl.fd);
                client->polling = 0;
        }
        err = snd_ctl_close(client->device.ctl.handle);
-       ctrl->result = err;
        if (err < 0)
                ERROR("snd_ctl_close");
-       if (client->transport.shm.ctrl) {
+       ctrl = client->transport.shm.ctrl;
+       if (ctrl) {
+               ctrl->result = err;
                err = shmdt((void *)client->transport.shm.ctrl);
                if (err < 0)
                        SYSERROR("shmdt failed");
@@ -738,6 +741,10 @@ static int snd_client_open(client_t *client)
                ans.result = -EINVAL;
                goto _answer;
        }
+       if (sizeof(client->name) < (size_t)(req.namelen + 1)) {
+               ans.result = -EINVAL;
+               goto _answer;
+       }
        name = alloca(req.namelen + 1);
        err = read(client->ctrl_fd, name, req.namelen);
        if (err < 0) {
@@ -779,7 +786,7 @@ static int snd_client_open(client_t *client)
                ans.result = -ENOMEM;
                goto _answer;
        }
-       strcpy(client->name, name);
+       snd_strlcpy(client->name, name, sizeof(client->name));
        client->stream = req.stream;
        client->mode = req.mode;
 
index f85980faec36844bf9ac7e9800e66247c25b0e44..989738ec57087bd63804610571fd45bbb17520a8 100644 (file)
@@ -150,7 +150,6 @@ int snd_async_add_handler(snd_async_handler_t **handler, int fd,
 int snd_async_del_handler(snd_async_handler_t *handler)
 {
        int err = 0, err2 = 0;
-       int was_empty;
        assert(handler);
        if (handler->type != SND_ASYNC_HANDLER_GENERIC) {
                struct list_head *alist;
@@ -184,15 +183,16 @@ int snd_async_del_handler(snd_async_handler_t *handler)
                }
        }
  _glist:
-       was_empty = list_empty(&snd_async_handlers);
-       list_del(&handler->glist);
-       if (!was_empty && list_empty(&snd_async_handlers)) {
-               err = sigaction(snd_async_signo, &previous_action, NULL);
-               if (err < 0) {
-                       snd_errornum(CORE, "sigaction");
-                       return -errno;
+       if (!list_empty(&snd_async_handlers)) {
+               list_del(&handler->glist);
+               if (list_empty(&snd_async_handlers)) {
+                       err = sigaction(snd_async_signo, &previous_action, NULL);
+                       if (err < 0) {
+                               snd_errornum(CORE, "sigaction");
+                               return -errno;
+                       }
+                       memset(&previous_action, 0, sizeof(previous_action));
                }
-               memset(&previous_action, 0, sizeof(previous_action));
        }
        free(handler);
        return err ? err : err2;
index 0f3dc6d6a569c39e0ef154bc39acffb18f9e3c8b..49499ecdfc3c840e9b76af44c348097822c58329 100644 (file)
@@ -1299,13 +1299,18 @@ static int parse_array_def(snd_config_t *parent, input_t *input, int *idx, int s
        {
                char endchr;
                if (!skip) {
+#if 0 /* n is always NULL for this moment */
                        if (n) {
                                if (n->type != SND_CONFIG_TYPE_COMPOUND) {
                                        snd_error(CORE, "%s is not a compound", id);
                                        err = -EINVAL;
                                        goto __end;
                                }
-                       } else {
+                       } else
+#else
+                       assert(n == NULL);
+#endif
+                              {
                                err = _snd_config_make_add(&n, &id, SND_CONFIG_TYPE_COMPOUND, parent);
                                if (err < 0)
                                        goto __end;
@@ -1318,6 +1323,8 @@ static int parse_array_def(snd_config_t *parent, input_t *input, int *idx, int s
                        err = parse_array_defs(n, input, skip, override);
                        endchr = ']';
                }
+               if (err < 0)
+                       goto __end;
                c = get_nonwhite(input);
                if (c < 0) {
                        err = c;
@@ -3493,7 +3500,7 @@ int snd_config_save(snd_config_t *config, snd_output_t *out)
 
 #define SND_CONFIG_SEARCHV(config, result, fcn) \
 { \
-       snd_config_t *n; \
+       snd_config_t *n = NULL; \
        va_list arg; \
        assert(config); \
        va_start(arg, result); \
@@ -3517,7 +3524,7 @@ int snd_config_save(snd_config_t *config, snd_output_t *out)
 
 #define SND_CONFIG_SEARCHVA(root, config, result, fcn) \
 { \
-       snd_config_t *n; \
+       snd_config_t *n = NULL; \
        va_list arg; \
        assert(config); \
        va_start(arg, result); \
@@ -4565,7 +4572,10 @@ int snd_config_update_r(snd_config_t **_top, snd_config_update_t **_update, cons
        }
        for (k = 0; k < local->count; ++k) {
                struct stat64 st;
-               struct finfo *lf = &local->finfo[k];
+               struct finfo *lf;
+
+_nextf:
+               lf = &local->finfo[k];
                if (stat64(lf->name, &st) >= 0) {
                        lf->dev = st.st_dev;
                        lf->ino = st.st_ino;
@@ -4573,9 +4583,13 @@ int snd_config_update_r(snd_config_t **_top, snd_config_update_t **_update, cons
                } else {
                        snd_error(CORE, "Cannot access file %s", lf->name);
                        free(lf->name);
-                       memmove(&local->finfo[k], &local->finfo[k+1], sizeof(struct finfo) * (local->count - k - 1));
-                       k--;
                        local->count--;
+                       if (k < local->count) {
+                               memmove(&local->finfo[k], &local->finfo[k+1], sizeof(struct finfo) * (local->count - k));
+                               goto _nextf;
+                       } else {
+                               break;
+                       }
                }
        }
        if (!update)
index 2ed97d2346bf120112f75b8d934235fbc192fbca..7d90d7ad0f8118dd83994447b2b8ecc018c8c560 100644 (file)
@@ -770,7 +770,7 @@ static int remap_map_elem_write(snd_ctl_remap_t *priv, snd_ctl_elem_value_t *con
                                }
                                for (src_index = 1; src_index < mctl->src_channels; src_index++) {
                                        dst = mctl->channel_map[base_idx + src_index];
-                                       if ((unsigned long)dst < ARRAY_SIZE(control->value.integer.value)) {
+                                       if ((unsigned long)dst < ARRAY_SIZE(control->value.integer64.value)) {
                                                changes |= control2.value.integer64.value[dst] != control->value.integer64.value[index];
                                                control2.value.integer64.value[dst] = control->value.integer64.value[index];
                                        }
index abf8174a7cc0b880ac2bb6d68ba236d1788f7bca..44f0a7bcdba96aadaa2ac7a892bd4f41a973d00c 100644 (file)
@@ -70,7 +70,7 @@ static int snd_ctl_shm_action_fd(snd_ctl_t *ctl, int *fd)
 {
        snd_ctl_shm_t *shm = ctl->private_data;
        int err;
-       char buf[1];
+       char buf[1] = {0};
        volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
        err = write(shm->socket, buf, 1);
        if (err != 1)
@@ -483,6 +483,11 @@ int snd_ctl_shm_open(snd_ctl_t **handlep, const char *name, const char *sockname
                result = -EINVAL;
                goto _err;
        }
+       if (ans.result < INT_MIN || ans.result > INT_MAX) {
+               snd_error(CONTROL, "invalid data error");
+               result = -EINVAL;
+               goto _err;
+       }
        result = ans.result;
        if (result < 0)
                goto _err;
@@ -519,7 +524,8 @@ int snd_ctl_shm_open(snd_ctl_t **handlep, const char *name, const char *sockname
        return 0;
 
  _err:
-       close(sock);
+       if (sock >= 0)
+               close(sock);
        if (ctrl)
                shmdt(ctrl);
        free(shm);
index 4b2f98b69dfb67b73f3d630ba2be5cdff0e613b9..6ce033cc0e7d5af15034d01c54e6ace467ab551d 100644 (file)
@@ -587,7 +587,7 @@ int snd_device_name_hint(int card, const char *iface, void ***hints)
        struct hint_list list;
        char ehints[24];
        const char *str;
-       snd_config_t *conf, *local_config = NULL, *local_config_rw = NULL;
+       snd_config_t *conf, *local_config = NULL, *local_config_rw;
        snd_config_update_t *local_config_update = NULL;
        snd_config_iterator_t i, next;
        int err;
@@ -628,6 +628,8 @@ int snd_device_name_hint(int card, const char *iface, void ***hints)
                err = get_card_name(&list, card);
                if (err >= 0)
                        err = add_card(local_config, local_config_rw, &list, card);
+               if (err < 0)
+                       goto __error;
        } else {
                add_software_devices(local_config, local_config_rw, &list);
                err = snd_card_next(&card);
@@ -669,10 +671,8 @@ int snd_device_name_hint(int card, const char *iface, void ***hints)
        else
                *hints = (void **)list.list;
        free(list.cardname);
-       if (local_config_rw)
-               snd_config_delete(local_config_rw);
-       if (local_config)
-               snd_config_delete(local_config);
+       snd_config_delete(local_config_rw);
+       snd_config_delete(local_config);
        if (local_config_update)
                snd_config_update_free(local_config_update);
        return err;
index 7ae7b3e917c0de4bc6f5469e625290b77c2ea46f..669e5fcb77d950d324677184fdc1c5445909d03a 100644 (file)
@@ -221,10 +221,12 @@ static int snd_config_get_ctl_elem_enumerated(snd_config_t *n, snd_ctl_t *ctl,
        unsigned int idx, items;
        switch (snd_config_get_type(n)) {
        case SND_CONFIG_TYPE_INTEGER:
-               snd_config_get_integer(n, &val);
+               if (snd_config_get_integer(n, &val) < 0)
+                       return -1;
                return val;
        case SND_CONFIG_TYPE_STRING:
-               snd_config_get_string(n, &str);
+               if (snd_config_get_string(n, &str) < 0)
+                       return -1;
                break;
        default:
                return -1;
@@ -586,8 +588,7 @@ static int add_elem(snd_sctl_t *h, snd_config_t *_conf, snd_config_t *private_da
                if (err != -ENOMEM && optional)
                        err = 0; /* ignore the error */
        }
-       if (conf)
-               snd_config_delete(conf);
+       snd_config_delete(conf);
        return err;
 }
 
index e6ed6abb035e059880da44016c6f06dc020253c2..e575f2ebd0e12c180ffd112f58420d4579fb4d9d 100644 (file)
@@ -368,8 +368,8 @@ void snd_lib_log(int prio, int interface, const char *file, int line, const char
 void snd_lib_check(int interface, const char *file, int line, const char *function, int errcode, const char *fmt, ...)
 {
        const char *verbose;
-
        va_list arg;
+
        va_start(arg, fmt);
        verbose = getenv("LIBASOUND_DEBUG");
        if (! verbose || ! *verbose)
index b60c0eefb57dc236c9b74847905b3c61d0941559..4dd21e907fbb52e549240374ee493793e1df8e92 100644 (file)
@@ -352,8 +352,7 @@ int snd_mixer_simple_basic_register(snd_mixer_t *mixer,
                        snd_mixer_class_free(class);
                return err;
        }
-       if (top)
-               snd_config_delete(top);
+       snd_config_delete(top);
        if (classp)
                *classp = class;
        return 0;
index 4c47b1688db7f62b34f7de54cb236541ef001e78..e0945602656f8325efb1bef2d537cbf977a793fe 100644 (file)
@@ -652,7 +652,7 @@ static int selem_write(snd_mixer_elem_t *elem)
 
        err = selem_write_main(elem);
        if (err < 0)
-               selem_read(elem);
+               (void)selem_read(elem);
        return err;
 }
 
@@ -984,6 +984,8 @@ static int _snd_mixer_selem_set_volume(snd_mixer_elem_t *elem, int dir, snd_mixe
 static int _snd_mixer_selem_set_switch(snd_mixer_elem_t *elem, int dir, snd_mixer_selem_channel_id_t channel, int value)
 {
        selem_none_t *s = snd_mixer_elem_get_private(elem);
+       if (channel < 0 || channel > 31)
+               return 0;
        if ((unsigned int) channel >= s->str[dir].channels)
                return 0;
        if (s->selem.caps &
@@ -1247,6 +1249,8 @@ static int get_switch_ops(snd_mixer_elem_t *elem, int dir,
                dir = SM_PLAY;
        if ((unsigned int) channel >= s->str[dir].channels)
                return -EINVAL;
+       if (channel < 0 || channel > 31)
+               return -EINVAL;
        *value = !!(s->str[dir].sw & (1 << channel));
        return 0;
 }
index a6f500cb526154f087b850d9c5d97d0de455a504..11b15100cd796612e2c482aa3d897e24f49c66ee 100644 (file)
@@ -2580,8 +2580,8 @@ static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
                char *val;
                if (snd_config_get_id(pcm_conf, &id) < 0)
                        id = NULL;
-               val = NULL;
-               snd_config_get_ascii(pcm_conf, &val);
+               if (snd_config_get_ascii(pcm_conf, &val) < 0)
+                       val = NULL;
                snd_error(PCM, "Invalid type for PCM %s%sdefinition (id: %s, value: %s)", name ? name : "", name ? " " : "", id, val);
                free(val);
                return -EINVAL;
@@ -3126,7 +3126,7 @@ int snd_pcm_avail_delay(snd_pcm_t *pcm,
        while (1) {
                sf = __snd_pcm_avail_update(pcm);
                if (sf < 0) {
-                       err = (int)sf;
+                       err = sf < INT_MIN ? -EOVERFLOW : (int)sf;
                        goto unlock;
                }
                if (ok && sf == *availp)
@@ -3335,6 +3335,8 @@ int snd_pcm_area_copy(const snd_pcm_channel_area_t *dst_area, snd_pcm_uframes_t
                return 0;
        dst = snd_pcm_channel_area_addr(dst_area, dst_offset);
        width = snd_pcm_format_physical_width(format);
+       if (width < 0)
+               return width;
        if (src_area->step == (unsigned int) width &&
            dst_area->step == (unsigned int) width) {
                size_t bytes = samples * width / 8;
@@ -7682,8 +7684,7 @@ snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_
                frames = size;
                if (frames > (snd_pcm_uframes_t) avail)
                        frames = avail;
-               if (! frames)
-                       break;
+               /* frames must be at least 1 here (see while condition) */
                err = func(pcm, areas, offset, frames);
                if (err < 0)
                        break;
@@ -8059,7 +8060,7 @@ void snd_pcm_unlink_appl_ptr(snd_pcm_t *pcm, snd_pcm_t *slave)
  *
  */
 
-#ifndef DOC_HIDDEN
+#if !defined(DOC_HIDDEN) && !defined(__COVERITY__)
 
 #ifdef USE_VERSIONED_SYMBOLS
 
@@ -8295,7 +8296,7 @@ OBSOLETE1(snd_pcm_sw_params_get_stop_threshold, ALSA_0.9, ALSA_0.9.0rc4);
 OBSOLETE1(snd_pcm_sw_params_get_silence_threshold, ALSA_0.9, ALSA_0.9.0rc4);
 OBSOLETE1(snd_pcm_sw_params_get_silence_size, ALSA_0.9, ALSA_0.9.0rc4);
 
-#endif /* DOC_HIDDEN */
+#endif /* DOC_HIDDEN/COVERITY */
 
 static int chmap_equal(const snd_pcm_chmap_t *a, const snd_pcm_chmap_t *b)
 {
@@ -8794,7 +8795,7 @@ int snd_pcm_recover(snd_pcm_t *pcm, int err, int silent)
        if (err == -ESTRPIPE) {
                while ((err = snd_pcm_resume(pcm)) == -EAGAIN)
                        /* wait until suspend flag is released */
-                       poll(NULL, 0, 1000);
+                       (void)poll(NULL, 0, 1000);
                if (err < 0) {
                        err = snd_pcm_prepare(pcm);
                        if (err < 0) {
index 304c1883bbf0db4a0caecdd9e6a65a7ff32e8c27..a08bbe6d93471745be5765afc3f5632d283a3f8c 100644 (file)
@@ -1763,7 +1763,11 @@ int snd_pcm_direct_parse_bindings(snd_pcm_direct_t *dmix,
                long cchannel, schannel;
                if (snd_config_get_id(n, &id) < 0)
                        continue;
-               safe_strtol(id, &cchannel);
+               err = safe_strtol(id, &cchannel);
+               if (err < 0) {
+                       free(bindings);
+                       return -EINVAL;
+               }
                if (snd_config_get_integer(n, &schannel) < 0) {
                        snd_error(PCM, "unable to get slave channel (should be integer type) in binding: %s", id);
                        free(bindings);
@@ -1907,6 +1911,14 @@ static int _snd_pcm_direct_get_slave_ipc_offset(snd_config_t *root,
                device = 0;
        if (subdevice < 0)
                subdevice = 0;
+       if (card < 0 || card >= (1 << (31 - 12 - 1)))
+               return -EOVERFLOW;
+       if (device >= (1 << 6))
+               return -EOVERFLOW;
+       if (subdevice >= (1 << 4))
+               return -EOVERFLOW;
+       if (direction < 0 || direction > 1)
+               return -EOVERFLOW;
        return (direction << 1) + (device << 2) + (subdevice << 8) + (card << 12);
 }
 
index 84eb68f15838ce4af7c7b413033ca4ea103da11a..92619a7dc411c12351c29d572628164bd3557b68 100644 (file)
 static void mix_select_callbacks(snd_pcm_direct_t *dmix)
 {
        static int smp = 0;
+       unsigned int format = dmix->shmptr->s.format;
 
        if (!dmix->direct_memory_access) {
                generic_mix_select_callbacks(dmix);
                return;
        }
 
-       if (!((1ULL<< dmix->shmptr->s.format) & x86_64_dmix_supported_format)) {
+       if (format > 31) {
+               generic_mix_select_callbacks(dmix);
+               return;
+       }
+
+       if (!((1U << format) & x86_64_dmix_supported_format)) {
                generic_mix_select_callbacks(dmix);
                return;
        }
index 65da72a9d80086f173e12ed0cc89373fc0f24a56..4ef158c09286032779f14631861dbe13103cde19 100644 (file)
@@ -87,7 +87,12 @@ static void share_areas(snd_pcm_direct_t *dshare,
        channels = dshare->channels;
        format = dshare->shmptr->s.format;
        if (dshare->interleaved) {
-               unsigned int fbytes = snd_pcm_format_physical_width(format) / 8;
+               int width = snd_pcm_format_physical_width(format);
+               unsigned int fbytes;
+
+               if (width < 0)
+                       return;
+               fbytes = width / 8;
                memcpy(((char *)dst_areas[0].addr) + (dst_ofs * channels * fbytes),
                       ((char *)src_areas[0].addr) + (src_ofs * channels * fbytes),
                       size * channels * fbytes);
index 8c3b53ae3133af8cc5c3a6762341b6ba17081fc8..6a803b2cd080a191d4a5b0b88d5c0a4f5d59c1c9 100644 (file)
@@ -81,11 +81,16 @@ static void snoop_areas(snd_pcm_direct_t *dsnoop,
 {
        unsigned int chn, schn, channels;
        snd_pcm_format_t format;
+       unsigned int fbytes;
+       int pwidth;
 
        channels = dsnoop->channels;
        format = dsnoop->shmptr->s.format;
        if (dsnoop->interleaved) {
-               unsigned int fbytes = snd_pcm_format_physical_width(format) / 8;
+               pwidth = snd_pcm_format_physical_width(format);
+               if (pwidth < 0)
+                       return;
+               fbytes = pwidth / 8;
                memcpy(((char *)dst_areas[0].addr) + (dst_ofs * channels * fbytes),
                       ((char *)src_areas[0].addr) + (src_ofs * channels * fbytes),
                       size * channels * fbytes);
index f2c73163e5db73ba94b7f70cf355ec45d0bf2d22..ad8cb0dbaaf30890bddc3c443013a93205c44437 100644 (file)
@@ -467,7 +467,12 @@ static int snd_pcm_file_add_frames(snd_pcm_t *pcm,
                int err = 0;
                snd_pcm_uframes_t n = frames;
                snd_pcm_uframes_t cont = file->wbuf_size - file->appl_ptr;
-               snd_pcm_uframes_t avail = file->wbuf_size - snd_pcm_bytes_to_frames(pcm, file->wbuf_used_bytes);
+               snd_pcm_sframes_t used = snd_pcm_bytes_to_frames(pcm, file->wbuf_used_bytes);
+               snd_pcm_uframes_t avail;
+
+               if (used < 0)
+                       return used;
+               avail = file->wbuf_size - used;
                if (n > cont)
                        n = cont;
                if (n > avail)
@@ -475,12 +480,15 @@ static int snd_pcm_file_add_frames(snd_pcm_t *pcm,
                snd_pcm_areas_copy(file->wbuf_areas, file->appl_ptr,
                                   areas, offset,
                                   pcm->channels, n, pcm->format);
+               used = snd_pcm_frames_to_bytes(pcm, n);
+               if (used < 0)
+                       return used;
                frames -= n;
                offset += n;
                file->appl_ptr += n;
                if (file->appl_ptr == file->wbuf_size)
                        file->appl_ptr = 0;
-               file->wbuf_used_bytes += snd_pcm_frames_to_bytes(pcm, n);
+               file->wbuf_used_bytes += used;
                if (file->wbuf_used_bytes > file->buffer_bytes) {
                        err = snd_pcm_file_write_bytes(pcm, file->wbuf_used_bytes - file->buffer_bytes);
                        if (err < 0)
@@ -562,16 +570,23 @@ static snd_pcm_sframes_t snd_pcm_file_rewindable(snd_pcm_t *pcm)
 static snd_pcm_sframes_t snd_pcm_file_rewind(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
        snd_pcm_file_t *file = pcm->private_data;
-       snd_pcm_sframes_t err;
-       snd_pcm_uframes_t n;
+       snd_pcm_sframes_t err, n;
 
        n = snd_pcm_frames_to_bytes(pcm, frames);
-       if (n > file->wbuf_used_bytes)
-               frames = snd_pcm_bytes_to_frames(pcm, file->wbuf_used_bytes);
+       if (n < 0)
+               return n;
+       if ((size_t)n > file->wbuf_used_bytes) {
+               err = snd_pcm_bytes_to_frames(pcm, file->wbuf_used_bytes);
+               if (err < 0)
+                       return err;
+               frames = err;
+       }
        err = snd_pcm_rewind(file->gen.slave, frames);
        if (err > 0) {
-               file->appl_ptr = (file->appl_ptr - err + file->wbuf_size) % file->wbuf_size;
                n = snd_pcm_frames_to_bytes(pcm, err);
+               if (n < 0)
+                       return n;
+               file->appl_ptr = (file->appl_ptr - err + file->wbuf_size) % file->wbuf_size;
                file->wbuf_used_bytes -= n;
        }
        return err;
@@ -582,6 +597,8 @@ static snd_pcm_sframes_t snd_pcm_file_forwardable(snd_pcm_t *pcm)
        snd_pcm_file_t *file = pcm->private_data;
        snd_pcm_sframes_t res = snd_pcm_forwardable(file->gen.slave);
        snd_pcm_sframes_t n = snd_pcm_bytes_to_frames(pcm, file->wbuf_size_bytes - file->wbuf_used_bytes);
+       if (n < 0)
+               return n;
        if (res > n)
                res = n;
        return res;
@@ -590,16 +607,23 @@ static snd_pcm_sframes_t snd_pcm_file_forwardable(snd_pcm_t *pcm)
 static snd_pcm_sframes_t snd_pcm_file_forward(snd_pcm_t *pcm, snd_pcm_uframes_t frames)
 {
        snd_pcm_file_t *file = pcm->private_data;
-       snd_pcm_sframes_t err;
-       snd_pcm_uframes_t n;
+       snd_pcm_sframes_t err, n;
 
        n = snd_pcm_frames_to_bytes(pcm, frames);
-       if (file->wbuf_used_bytes + n > file->wbuf_size_bytes)
-               frames = snd_pcm_bytes_to_frames(pcm, file->wbuf_size_bytes - file->wbuf_used_bytes);
+       if (n < 0)
+               return n;
+       if (file->wbuf_used_bytes + n > file->wbuf_size_bytes) {
+               err = snd_pcm_bytes_to_frames(pcm, file->wbuf_size_bytes - file->wbuf_used_bytes);
+               if (err < 0)
+                       return err;
+               frames = err;
+       }
        err = INTERNAL(snd_pcm_forward)(file->gen.slave, frames);
        if (err > 0) {
-               file->appl_ptr = (file->appl_ptr + err) % file->wbuf_size;
                n = snd_pcm_frames_to_bytes(pcm, err);
+               if (n < 0)
+                       return err;
+               file->appl_ptr = (file->appl_ptr + err) % file->wbuf_size;
                file->wbuf_used_bytes += n;
        }
        return err;
@@ -755,10 +779,14 @@ static int snd_pcm_file_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        snd_pcm_file_t *file = pcm->private_data;
        unsigned int channel;
        snd_pcm_t *slave = file->gen.slave;
+       snd_pcm_sframes_t bsize;
        int err = _snd_pcm_hw_params_internal(slave, params);
        if (err < 0)
                return err;
-       file->buffer_bytes = snd_pcm_frames_to_bytes(slave, slave->buffer_size);
+       bsize = snd_pcm_frames_to_bytes(slave, slave->buffer_size);
+       if (bsize < 0)
+               return bsize;
+       file->buffer_bytes = bsize;
        file->wbuf_size = slave->buffer_size * 2;
        file->wbuf_size_bytes = snd_pcm_frames_to_bytes(slave, file->wbuf_size);
        file->wbuf_used_bytes = 0;
@@ -932,14 +960,21 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
        file->perm = perm;
 
        if (ifname && (stream == SND_PCM_STREAM_CAPTURE)) {
-               ifd = open(ifname, O_RDONLY);   /* TODO: mind blocking mode */
-               if (ifd < 0) {
+               file->ifname = strdup(ifname);
+               if (file->ifname)
+                       ifd = open(ifname, O_RDONLY);   /* TODO: mind blocking mode */
+               else
+                       ifd = -1;
+               if (ifd < 0 || file->ifname == NULL) {
+                       if (ifd >= 0)
+                               close(ifd);
+                       err = -errno;
                        snd_errornum(PCM, "open %s for reading failed", ifname);
+                       free(file->ifname);
                        free(file->fname);
                        free(file);
-                       return -errno;
+                       return err;
                }
-               file->ifname = strdup(ifname);
        }
        file->fd = fd;
        file->ifd = ifd;
@@ -949,6 +984,8 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
 
        err = snd_pcm_new(&pcm, SND_PCM_TYPE_FILE, name, slave->stream, slave->mode);
        if (err < 0) {
+               if (file->ifname && file->ifd >= 0)
+                       close(file->ifd);
                free(file->fname);
                free(file->ifname);
                free(file);
index efd838d33dbb2892d729c065c486b4f17183b26e..c9fca93c5d65099b64dc02091fd5bd5f5da2b1b7 100644 (file)
@@ -469,8 +469,8 @@ static int snd_pcm_hw_change_timer(snd_pcm_t *pcm, int enable)
                 */
                {
                        int ver = 0;
-                       ioctl(hw->period_timer_pfd.fd,
-                             SNDRV_TIMER_IOCTL_PVERSION, &ver);
+                       if (ioctl(hw->period_timer_pfd.fd, SNDRV_TIMER_IOCTL_PVERSION, &ver))
+                               snd_warn(PCM, "unable to get protocol version");
                        /*
                         * In older versions, check via poll before read() is
                         * needed because of the confliction between
index 0397219b12608cc8e73e591ba3e06ffa545beff9..fb0f5bec081785f9e594ef451013453e62496db7 100644 (file)
@@ -891,7 +891,7 @@ snd_pcm_ladspa_write_areas(snd_pcm_t *pcm,
                                        chn = instance->output.channels.array[idx];
                                        data = instance->output.data[idx];
                                        if (data == NULL) {
-                                               data = (LADSPA_Data *)((char *)slave_areas[chn].addr + (areas[chn].first / 8));
+                                               data = (LADSPA_Data *)((char *)slave_areas[chn].addr + (slave_areas[chn].first / 8));
                                                data += slave_offset;
                                        }
                                        instance->desc->connect_port(instance->handle, instance->output.ports.array[idx], data);
@@ -943,7 +943,7 @@ snd_pcm_ladspa_read_areas(snd_pcm_t *pcm,
                                        chn = instance->input.channels.array[idx];
                                        data = instance->input.data[idx];
                                        if (data == NULL) {
-                                               data = (LADSPA_Data *)((char *)slave_areas[chn].addr + (areas[chn].first / 8));
+                                               data = (LADSPA_Data *)((char *)slave_areas[chn].addr + (slave_areas[chn].first / 8));
                                                data += slave_offset;
                                        }
                                        instance->desc->connect_port(instance->handle, instance->input.ports.array[idx], data);
@@ -1759,7 +1759,9 @@ int _snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
                        continue;
                }
                if (strcmp(id, "channels") == 0) {
-                       snd_config_get_integer(n, &channels);
+                       err = snd_config_get_integer(n, &channels);
+                       if (err < 0)
+                               return err;
                        if (channels > 1024)
                                channels = 1024;
                        if (channels < 0)
index c027194d3cf3fc3123e727220800c07fc9f452da..8fc5c15dec99e657b02e09a100d8db0d5affb15e 100644 (file)
@@ -443,7 +443,7 @@ static int snd_pcm_meter_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        snd_pcm_meter_t *meter = pcm->private_data;
        unsigned int channel;
        snd_pcm_t *slave = meter->gen.slave;
-       size_t buf_size_bytes;
+       ssize_t buf_size_bytes;
        int err;
        err = snd_pcm_hw_params_slave(pcm, params,
                                      snd_pcm_meter_hw_refine_cchange,
@@ -457,6 +457,8 @@ static int snd_pcm_meter_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
        while (meter->buf_size < slave->rate)
                meter->buf_size *= 2;
        buf_size_bytes = snd_pcm_frames_to_bytes(slave, meter->buf_size);
+       if (buf_size_bytes < 0)
+               return buf_size_bytes;
        assert(!meter->buf);
        meter->buf = malloc(buf_size_bytes);
        if (!meter->buf)
index 570ecd97f7bf6154f4b89aec585abb5994d78b1c..d611f6a6caabc7fff1d7a78c1b7b5b5baa071b76 100644 (file)
@@ -619,12 +619,12 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
                break;
        }
        case 8: {
-               uint8_t silence = snd_pcm_format_silence_64(format);
+               uint8_t silence = snd_pcm_format_silence(format);
                memset(data, silence, samples);
                break;
        }
        case 16: {
-               uint16_t silence = snd_pcm_format_silence_64(format);
+               uint16_t silence = snd_pcm_format_silence_16(format);
                uint16_t *pdata = (uint16_t *)data;
                if (! silence)
                        memset(data, 0, samples * 2);
@@ -635,7 +635,7 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
                break;
        }
        case 24: {
-               uint32_t silence = snd_pcm_format_silence_64(format);
+               uint32_t silence = snd_pcm_format_silence_32(format);
                uint8_t *pdata = (uint8_t *)data;
                if (! silence)
                        memset(data, 0, samples * 3);
@@ -655,7 +655,7 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
                break;
        }
        case 32: {
-               uint32_t silence = snd_pcm_format_silence_64(format);
+               uint32_t silence = snd_pcm_format_silence_32(format);
                uint32_t *pdata = (uint32_t *)data;
                if (! silence)
                        memset(data, 0, samples * 4);
index c6705b2d587f298d5def037cda7dcbe4fe5fa1ae..5ee72366aab428e9da96a2a5ecc2da316e455cc8 100644 (file)
@@ -251,6 +251,8 @@ static int snd_pcm_mulaw_hw_refine_cprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t
                err = _snd_pcm_hw_params_set_format(params,
                                                   SND_PCM_FORMAT_MU_LAW);
        }
+       if (err < 0)
+               return err;
        err = _snd_pcm_hw_params_set_subformat(params, SND_PCM_SUBFORMAT_STD);
        if (err < 0)
                return err;
index 7a6017632f348fc4d6df00aee981e0b0f0d44498..121c4c2070a38ec41fa368d3eb2aa011d2d14633 100644 (file)
@@ -1439,13 +1439,13 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
 _free:
        if (err < 0) {
                for (idx = 0; idx < slaves_count; ++idx) {
-                       if (slaves_pcm[idx])
+                       if (slaves_pcm && slaves_pcm[idx])
                                snd_pcm_close(slaves_pcm[idx]);
                }
        }
        if (slaves_conf) {
                for (idx = 0; idx < slaves_count; ++idx) {
-                       if (slaves_conf[idx])
+                       if (slaves_conf && slaves_conf[idx])
                                snd_config_delete(slaves_conf[idx]);
                }
                free(slaves_conf);
index 833d0dc9575aeb8f6cc352cefa60e56e80a66724..0536252e7eb1f9be0129cda246d21fd4eae9eeea 100644 (file)
@@ -967,6 +967,8 @@ static int snd_pcm_hw_param_set_near_minmax(snd_pcm_t *pcm,
        if (boundary_lt(min, *mindir, max, *maxdir)) {
                tmp = *params;
                err = snd_pcm_hw_param_set_near(pcm, &tmp, var, &max, maxdir);
+               if (err < 0)
+                       return err;
        } else {
                max = min;
                *maxdir = *mindir;
index 5172a7d2f86127b6e9524165a8bdfda3b0aac261..ddda92cade132a39454e66a6470c2db827d9d95e 100644 (file)
@@ -235,6 +235,8 @@ static const char linear_format_widths[32] = {
 static int check_linear_format(const snd_pcm_format_mask_t *format_mask, int wid, int sgn, int ed)
 {
        int e, s;
+       if (wid < 1 || wid > 32)
+               return SND_PCM_FORMAT_UNKNOWN;
        if (! linear_format_widths[wid - 1])
                return SND_PCM_FORMAT_UNKNOWN;
        for (e = 0; e < 2; e++) {
@@ -450,13 +452,15 @@ static int snd_pcm_plug_change_channels(snd_pcm_t *pcm, snd_pcm_t **new, snd_pcm
                                snd_pcm_route_ttable_entry_t v = SND_PCM_PLUGIN_ROUTE_FULL;
                                if (rpolicy == PLUG_ROUTE_POLICY_AVERAGE) {
                                        if (pcm->stream == SND_PCM_STREAM_PLAYBACK &&
-                                           clt->channels > slv->channels) {
+                                           clt->channels > slv->channels &&
+                                           slv->channels > 0) {
                                                int srcs = clt->channels / slv->channels;
                                                if (s < clt->channels % slv->channels)
                                                        srcs++;
                                                v /= srcs;
                                        } else if (pcm->stream == SND_PCM_STREAM_CAPTURE &&
-                                                  slv->channels > clt->channels) {
+                                                  slv->channels > clt->channels &&
+                                                  clt->channels > 0) {
                                                        int srcs = slv->channels / clt->channels;
                                                if (s < slv->channels % clt->channels)
                                                        srcs++;
@@ -1338,6 +1342,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
                                 SND_PCM_HW_PARAM_RATE, SCONF_UNCHANGED, &srate);
        if (err < 0)
                return err;
+       csize = ssize = cused = sused = 0;
 #ifdef BUILD_PCM_PLUGIN_ROUTE
        if (tt) {
                err = snd_pcm_route_determine_ttable(tt, &csize, &ssize);
@@ -1352,6 +1357,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
                }
                err = snd_pcm_route_load_ttable(tt, ttable, csize, ssize, &cused, &sused, -1);
                if (err < 0) {
+                       free(ttable);
                        snd_config_delete(sconf);
                        return err;
                }
@@ -1365,8 +1371,10 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
 
        err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode, conf);
        snd_config_delete(sconf);
-       if (err < 0)
+       if (err < 0) {
+               free(ttable);
                return err;
+       }
        err = snd_pcm_plug_open(pcmp, name, sformat, schannels, srate, rate_converter,
                                route_policy, ttable, ssize, cused, sused, spcm, 1);
        if (err < 0)
index 3847a82b0c2e6a2e4350d25d073ab0919772a4ee..d54be3c2250ee59ea2743707b96bfc0f06398bc0 100644 (file)
@@ -88,6 +88,12 @@ rate_alloc_tmp_buf(snd_pcm_format_t format,
        int width = snd_pcm_format_physical_width(format);
        unsigned int i;
 
+       if (width < 0 || width > 128)
+               return NULL;
+       if (channels > 1024)
+               return NULL;
+       if (frames > 10*1024*1024)
+               return NULL;
        ap = malloc(sizeof(*ap) * channels);
        if (!ap)
                return NULL;
@@ -320,6 +326,9 @@ static int choose_preferred_format(snd_pcm_rate_t *rate)
        if (!in_mask || !out_mask)
                return 0;
 
+       if (rate->orig_in_format < 0 || rate->orig_in_format > 63)
+               return -EINVAL;
+
        if (rate->orig_in_format == rate->orig_out_format)
                if (in_mask & out_mask & (1ULL << rate->orig_in_format))
                        return 0; /* nothing changed */
index 29fb51e97b7faee7e79ad1057993e9aa3698cdf4..3836dcc3a4fa78c7d2641fc1887d7dacf72f64ce 100644 (file)
@@ -1339,6 +1339,7 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
                        continue;
                }
                snd_error(PCM, "Unknown field %s", id);
+               snd_pcm_free_chmaps(chmaps);
                return -EINVAL;
        }
        if (!slave) {
@@ -1368,7 +1369,8 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
 
        err = determine_chmap(tt, &tt_chmap);
        if (err < 0) {
-               free(ttable);
+               snd_config_delete(sconf);
+               snd_pcm_free_chmaps(chmaps);
                return err;
        }
 
@@ -1376,7 +1378,6 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
        snd_config_delete(sconf);
        if (err < 0) {
                free(tt_chmap);
-               free(ttable);
                snd_pcm_free_chmaps(chmaps);
                return err;
        }
index 7927b646b57e086c72ca88f3232464688bb900df..12205fe1e97292ca289165e6c882cad4a04b789e 100644 (file)
@@ -288,7 +288,7 @@ static snd_pcm_uframes_t _snd_pcm_share_missing(snd_pcm_t *pcm)
 
  update_poll:
        if (ready != share->ready) {
-               char buf[1];
+               char buf[1] = {0};
                while (1) {
                        if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
                                if (ready)
@@ -366,14 +366,15 @@ static void *snd_pcm_share_thread(void *data)
        struct pollfd pfd[2];
        int err;
 
+       Pthread_mutex_lock(&slave->mutex);
        pfd[0].fd = slave->poll[0];
        pfd[0].events = POLLIN;
        err = snd_pcm_poll_descriptors(spcm, &pfd[1], 1);
        if (err != 1) {
                snd_error(PCM, "invalid poll descriptors %d", err);
+               Pthread_mutex_unlock(&slave->mutex);
                return NULL;
        }
-       Pthread_mutex_lock(&slave->mutex);
        err = pipe(slave->poll);
        if (err < 0) {
                snd_errornum(PCM, "can't create a pipe");
@@ -412,9 +413,9 @@ static void *snd_pcm_share_thread(void *data)
                        Pthread_mutex_unlock(&slave->mutex);
                        err = poll(pfd, 2, -1);
                        Pthread_mutex_lock(&slave->mutex);
-                       if (pfd[0].revents & POLLIN) {
+                       if (err > 0 && (pfd[0].revents & POLLIN) != 0) {
                                char buf[1];
-                               read(pfd[0].fd, buf, 1);
+                               (void)read(pfd[0].fd, buf, 1);
                        }
                } else {
                        slave->polling = 0;
@@ -931,9 +932,12 @@ static int snd_pcm_share_start(snd_pcm_t *pcm)
        snd_pcm_share_slave_t *slave = share->slave;
        snd_pcm_t *spcm = slave->pcm;
        int err = 0;
-       if (share->state != SND_PCM_STATE_PREPARED)
-               return -EBADFD;
+
        Pthread_mutex_lock(&slave->mutex);
+       if (share->state != SND_PCM_STATE_PREPARED) {
+               err = -EBADFD;
+               goto _end;
+       }
        share->state = SND_PCM_STATE_RUNNING;
        if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
                snd_pcm_uframes_t hw_avail = snd_pcm_mmap_playback_hw_avail(pcm);
@@ -1152,8 +1156,13 @@ static void _snd_pcm_share_stop(snd_pcm_t *pcm, snd_pcm_state_t state)
                snd_pcm_areas_silence(pcm->running_areas, 0, pcm->channels,
                                      pcm->buffer_size, pcm->format);
                err = snd_pcm_delay(slave->pcm, &delay);
-               if (err >= 0 && delay > 0)
-                       snd_pcm_rewind(slave->pcm, delay);
+               if (err >= 0 && delay > 0) {
+                       int err = snd_pcm_rewind(slave->pcm, delay);
+                       if (err < 0) {
+                               errno = -err;
+                               snd_errornum(PCM, "rewind failed");
+                       }
+               }
                share->drain_silenced = 0;
        }
        share->state = state;
@@ -1444,7 +1453,7 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
                        pfd.fd = sd[0];
                        pfd.events = POLLOUT;
                        while ((err = poll(&pfd, 1, 0)) == 1) {
-                               char buf[1];
+                               char buf[1] = {0};
                                err = write(sd[0], buf, 1);
                                assert(err != 0);
                                if (err != 1)
index c0f904eb2f30e32351ecf291aac0a4cee45686d8..4b176c8373874768c5fe2a0920e724cdd8c94e7d 100644 (file)
@@ -323,8 +323,6 @@ static int snd_pcm_shm_sw_params(snd_pcm_t *pcm, snd_pcm_sw_params_t * params)
        ctrl->u.sw_params = *params;
        err = snd_pcm_shm_action(pcm);
        *params = ctrl->u.sw_params;
-       if (err < 0)
-               return err;
        return err;
 }
 
@@ -437,8 +435,6 @@ static snd_pcm_sframes_t snd_pcm_shm_avail_update(snd_pcm_t *pcm)
        int err;
        ctrl->cmd = SND_PCM_IOCTL_AVAIL_UPDATE;
        err = snd_pcm_shm_action(pcm);
-       if (err < 0)
-               return err;
        return err;
 }
 
@@ -637,7 +633,7 @@ static int make_local_socket(const char *filename)
        size_t l = strlen(filename);
        size_t size = offsetof(struct sockaddr_un, sun_path) + l;
        struct sockaddr_un *addr = alloca(size);
-       int sock;
+       int sock, err;
 
        sock = socket(PF_LOCAL, SOCK_STREAM, 0);
        if (sock < 0) {
@@ -649,8 +645,10 @@ static int make_local_socket(const char *filename)
        memcpy(addr->sun_path, filename, l);
 
        if (connect(sock, (struct sockaddr *) addr, size) < 0) {
+               err = -errno;
                snd_errornum(PCM, "connect failed");
-               return -errno;
+               close(sock);
+               return err;
        }
        return sock;
 }
@@ -722,6 +720,11 @@ int snd_pcm_shm_open(snd_pcm_t **pcmp, const char *name,
                result = -EINVAL;
                goto _err;
        }
+       if (ans.result < INT_MIN || ans.result > INT_MAX) {
+               snd_error(PCM, "invalid read");
+               result = -EINVAL;
+               goto _err;
+       }
        result = ans.result;
        if (result < 0)
                goto _err;
@@ -764,7 +767,8 @@ int snd_pcm_shm_open(snd_pcm_t **pcmp, const char *name,
        return 0;
 
  _err:
-       close(sock);
+       if (sock >= 0)
+               close(sock);
        if (ctrl)
                shmdt(ctrl);
        free(shm);
index 75330fd1346f57e911f92bbacc0839c675702725..09b7617948ff58ec021a9d32abfff35d4d27e664 100644 (file)
@@ -181,7 +181,7 @@ static int snd_rawmidi_virtual_drain(snd_rawmidi_t *rmidi)
                        virt->pending = 0;
                }
                snd_seq_drain_output(virt->handle);
-               snd_seq_sync_output_queue(virt->handle);
+               (void)snd_seq_sync_output_queue(virt->handle);
        }
        return snd_rawmidi_virtual_drop(rmidi);
 }
index 3ff5fc591f6a1789897f27775f174c1a75b19b73..ad252e2418d7083e8b65fad036a227d8301c87a2 100644 (file)
@@ -1099,11 +1099,11 @@ int snd_ump_msg_sysex_expand(const uint32_t *ump, uint8_t *buf, size_t maxlen,
  */
 int snd_ump_packet_length(unsigned int type)
 {
-       static int packet_length[16] = {
+       static unsigned char packet_length[16] = {
                1, 1, 1, 2, 2, 4, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4
        };
 
-       if (type > 16)
+       if (type >= sizeof(packet_length))
                return 0;
        return packet_length[type];
 }
index 604aa2dd5a48b910b55b0372e0d1b8714ff9fe66..280a27bde028e1d10abbf1853e04d5b8421eb565 100644 (file)
@@ -476,6 +476,8 @@ int snd_seq_parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, const char *arg)
                        if (!strncmp(arg, cinfo.name, len)) {
                                if (strlen(cinfo.name) == (size_t)len) {
                                        /* exact match */
+                                       if (cinfo.client < 0)
+                                               return -EIO;
                                        addr->client = cinfo.client;
                                        return 0;
                                }
index 8d91b8ef67b8611eaab1429079ee00a3aaef5460..148c1ab058484fb44197cb0abcc84b67037795dd 100644 (file)
@@ -220,13 +220,10 @@ static ssize_t write_manifest_data(snd_tplg_t *tplg)
                return ret;
        }
 
-       tplg_log(tplg, 'B', tplg->bin_pos, "manifest: write %d bytes",
-                sizeof(tplg->manifest));
+       tplg_log(tplg, 'B', tplg->bin_pos, "manifest: write %zu bytes", sizeof(tplg->manifest));
        ret = twrite(tplg, &tplg->manifest, sizeof(tplg->manifest));
        if (ret >= 0) {
-               tplg_log(tplg, 'B', tplg->bin_pos,
-                        "manifest: write %d priv bytes",
-                        tplg->manifest.priv.size);
+               tplg_log(tplg, 'B', tplg->bin_pos, "manifest: write %d priv bytes", tplg->manifest.priv.size);
                ret = twrite(tplg, tplg->manifest_pdata, tplg->manifest.priv.size);
        }
        return ret;
index 8a84450c9590f93828218e3ab827b1af133b1daf..a0c245185bc761e080c65d5f659992c7ca4acbfd 100644 (file)
@@ -1111,7 +1111,7 @@ int tplg_add_enum(snd_tplg_t *tplg, struct snd_tplg_enum_template *enum_ctl,
                        if (enum_ctl->values[i] == NULL)
                                continue;
 
-                       memcpy(&ec->values[i * sizeof(int) * ENUM_VAL_SIZE],
+                       memcpy(&ec->values[i * ENUM_VAL_SIZE],
                                enum_ctl->values[i],
                                sizeof(int) * ENUM_VAL_SIZE);
                }
index ac4d6085ee73794ef90e975dcf8583e864a47e25..d261b15b4ac0275182648ae0af86d831ac0eac0a 100644 (file)
@@ -329,9 +329,9 @@ done:
        buf[i] = 0;
        source = &buf[i + 2];
 
-       strcpy(line->source, source);
-       strcpy(line->control, control);
-       strcpy(line->sink, sink);
+       snd_strlcpy(line->source, source, sizeof(line->source));
+       snd_strlcpy(line->control, control, sizeof(line->source));
+       snd_strlcpy(line->sink, sink, sizeof(line->source));
        return 0;
 }
 
index 6869e3eb3eb1b0154c9b407d0e6e3548398e8e5d..1753d0c7ae18868730c8a45c0540f2cfa09e530a 100644 (file)
@@ -461,8 +461,7 @@ static int copy_data_hex(char *data, int off, const char *str, int width)
        return 0;
 }
 
-static int tplg_parse_data_hex(snd_config_t *cfg, struct tplg_elem *elem,
-       int width)
+static int tplg_parse_data_hex(snd_config_t *cfg, struct tplg_elem *elem, unsigned int width)
 {
        struct snd_soc_tplg_private *priv;
        const char *value = NULL;
@@ -471,11 +470,14 @@ static int tplg_parse_data_hex(snd_config_t *cfg, struct tplg_elem *elem,
 
        tplg_dbg(" data: %s", elem->id);
 
+       if (width > 4)
+               return -EINVAL;
+
        if (snd_config_get_string(cfg, &value) < 0)
                return -EINVAL;
 
        num = get_hex_num(value);
-       if (num <= 0) {
+       if (num <= 0 || num > 16384) {
                snd_error(TOPOLOGY, "malformed hex variable list %s", value);
                return -EINVAL;
        }
@@ -483,14 +485,16 @@ static int tplg_parse_data_hex(snd_config_t *cfg, struct tplg_elem *elem,
        size = num * width;
        priv = elem->data;
 
-       if (size > TPLG_MAX_PRIV_SIZE) {
-               snd_error(TOPOLOGY, "data too big %d", size);
+       if (size < 0 || size > TPLG_MAX_PRIV_SIZE) {
+               snd_error(TOPOLOGY, "data too big %u", (unsigned int)size);
                return -EINVAL;
        }
 
        if (priv != NULL) {
                off = priv->size;
-               esize = elem->size + size;
+               if (off > 1024*1024)
+                       return -ENOMEM;
+               esize = off + size;
                priv = realloc(priv, esize);
        } else {
                off = 0;
@@ -1696,7 +1700,7 @@ static int tplg_verify_tuple_set(snd_tplg_t *tplg, size_t pos,
        j = tplg_get_tuple_size(va->type) * va->num_elems;
        if (j + sizeof(*va) != va->size) {
                tplg_log(tplg, 'A', pos, "tuple set verify: wrong vendor array size %d "
-                        "(expected %d for %d count %d)",
+                        "(expected %zu for %d count %d)",
                         va->size, j + sizeof(*va), va->type, va->num_elems);
                return -EINVAL;
        }
index b56f6868e7da8305e8242fd57aef74c5304ea031..13b4719e3efdb67c44d7f5d29e3483749f74d170 100644 (file)
@@ -91,6 +91,8 @@ int tplg_parse_ops(snd_tplg_t *tplg ATTRIBUTE_UNUSED, snd_config_t *cfg,
                        if (snd_config_get_string(n, &value) < 0)
                                continue;
                        ival = lookup_ops(value);
+                       if (ival < 0)
+                               return ival;
                } else {
                        if (tplg_get_integer(n, &ival, 0))
                                continue;
@@ -176,6 +178,8 @@ int tplg_parse_ext_ops(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
                        if (snd_config_get_string(n, &value) < 0)
                                continue;
                        ival = lookup_ops(value);
+                       if (ival < 0)
+                               return ival;
                } else {
                        if (tplg_get_integer(n, &ival, 0))
                                continue;
index 9790565d9edaf7ea72e07c8bbcb479948eaaa135..fbe71f3e7e09e64a06656186f7053fb710a41a51 100644 (file)
@@ -189,21 +189,21 @@ static int read_tlv_file(unsigned int **res,
                goto __fail;
        }
        *res = malloc(sz);
-       if (res == NULL) {
+       if (*res == NULL) {
                err = -ENOMEM;
                goto __fail;
        }
        sz_read = read(fd, *res, sz);
        if (sz_read < 0 || (size_t)sz_read != sz) {
                err = -EIO;
-               free(*res);
-               *res = NULL;
+               goto __fail_res;
        }
        /* Check if the tlv file specifies valid size. */
        tlv = (struct snd_ctl_tlv *)(*res);
        if (tlv->length + 2 * sizeof(unsigned int) != sz) {
                snd_error(UCM, "Invalid tlv size: %d", tlv->length);
                err = -EINVAL;
+__fail_res:
                free(*res);
                *res = NULL;
        }
@@ -715,13 +715,13 @@ static int run_device_all_sequence(snd_use_case_mgr_t *uc_mgr, struct use_case_v
        struct list_head *pos;
        int err;
 
-       snd_trace(UCM, "disable all devices sequence for '%s'", verb->name);
-
        if (verb == NULL) {
                snd_error(UCM, "disdevall must be executed inside the verb context");
                return -ENOENT;
        }
 
+       snd_trace(UCM, "disable all devices sequence for '%s'", verb->name);
+
        list_for_each(pos, &verb->device_list) {
                device = list_entry(pos, struct use_case_device, list);
 
@@ -1533,6 +1533,9 @@ int snd_use_case_mgr_open(snd_use_case_mgr_t **uc_mgr,
 
        snd_trace(UCM, "{API call} open '%s'", card_name);
 
+       if (card_name == NULL)
+               return -EINVAL;
+
        /* create a new UCM */
        mgr = calloc(1, sizeof(snd_use_case_mgr_t));
        if (mgr == NULL)
@@ -1548,12 +1551,12 @@ int snd_use_case_mgr_open(snd_use_case_mgr_t **uc_mgr,
        INIT_LIST_HEAD(&mgr->variable_list);
        pthread_mutex_init(&mgr->mutex, NULL);
 
-       if (card_name && *card_name == '-') {
+       if (*card_name == '-') {
                card_name++;
                mgr->suppress_nodev_errors = 1;
        }
 
-       if (card_name && card_name[0] == '<' && card_name[1] == '<' && card_name[2] == '<')
+       if (card_name[0] == '<' && card_name[1] == '<' && card_name[2] == '<')
                card_name = parse_open_variables(mgr, card_name);
 
        err = uc_mgr_card_open(mgr);
@@ -2566,7 +2569,9 @@ static int set_verb_user(snd_use_case_mgr_t *uc_mgr,
                verb = NULL;
        }
        if (uc_mgr->active_verb) {
-               err = handle_transition_verb(uc_mgr, verb);
+               err = 0;
+               if (verb != NULL)
+                       err = handle_transition_verb(uc_mgr, verb);
                if (err == 0) {
                        err = dismantle_use_case(uc_mgr);
                        if (err < 0)
index 5db25d2da3dc8280f3f8b8e1640a7f2bc2408a41..b86d8f045e149e9732f9c96db8be40585cb83b4f 100644 (file)
@@ -310,7 +310,8 @@ static int if_eval_path(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval)
                amode = X_OK;
        } else {
                snd_error(UCM, "Path unknown mode '%s' (If.Condition.Mode)", s);
-               free(s);
+               if (s != mode)
+                       free(s);
                return -EINVAL;
        }
        if (s != mode)
index 1f5b84ced32e20d398c207d7946e1084ffdeecb5..cef23626b785e8fb8e2dbfd95e3ea63b1822bc03 100644 (file)
@@ -152,11 +152,12 @@ int uc_mgr_define_regex(snd_use_case_mgr_t *uc_mgr, const char *name,
        if (err < 0)
                return err;
        err = regcomp(&re, s, options);
-       free(s);
        if (err) {
                snd_error(UCM, "Regex '%s' compilation failed (code %d)", s, err);
+               free(s);
                return -EINVAL;
        }
+       free(s);
 
        err = uc_mgr_get_substituted_value(uc_mgr, &s, string);
        if (err < 0) {
index 639dd7a2bffb679ac45a46bd6da9a55b14c5d753..73230a2a94fe55903c218c7ff54b59d1ef82cdfa 100644 (file)
@@ -612,7 +612,7 @@ static char *rval_sysfs_main(snd_use_case_mgr_t *uc_mgr, const char *top_path, c
                if (s == NULL)
                        return NULL;
                len = s - id - 1;
-               if ((size_t)(len - 1) > sizeof(link) - 1)
+               if ((size_t)len > sizeof(link) - 1)
                        return NULL;
                strncpy(link, id + 1, len);
                link[len] = '\0';