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);
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");
{
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)
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);
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");
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) {
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;
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;
}
}
_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;
{
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;
err = parse_array_defs(n, input, skip, override);
endchr = ']';
}
+ if (err < 0)
+ goto __end;
c = get_nonwhite(input);
if (c < 0) {
err = c;
#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); \
#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); \
}
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;
} 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)
}
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];
}
{
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)
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;
return 0;
_err:
- close(sock);
+ if (sock >= 0)
+ close(sock);
if (ctrl)
shmdt(ctrl);
free(shm);
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;
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);
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;
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;
if (err != -ENOMEM && optional)
err = 0; /* ignore the error */
}
- if (conf)
- snd_config_delete(conf);
+ snd_config_delete(conf);
return err;
}
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)
snd_mixer_class_free(class);
return err;
}
- if (top)
- snd_config_delete(top);
+ snd_config_delete(top);
if (classp)
*classp = class;
return 0;
err = selem_write_main(elem);
if (err < 0)
- selem_read(elem);
+ (void)selem_read(elem);
return err;
}
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 &
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;
}
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;
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)
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;
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;
*
*/
-#ifndef DOC_HIDDEN
+#if !defined(DOC_HIDDEN) && !defined(__COVERITY__)
#ifdef USE_VERSIONED_SYMBOLS
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)
{
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) {
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);
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);
}
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;
}
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);
{
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);
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)
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)
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;
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;
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;
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;
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;
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);
*/
{
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
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);
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);
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)
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,
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)
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);
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);
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);
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;
_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);
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;
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++) {
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++;
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);
}
err = snd_pcm_route_load_ttable(tt, ttable, csize, ssize, &cused, &sused, -1);
if (err < 0) {
+ free(ttable);
snd_config_delete(sconf);
return err;
}
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)
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;
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 */
continue;
}
snd_error(PCM, "Unknown field %s", id);
+ snd_pcm_free_chmaps(chmaps);
return -EINVAL;
}
if (!slave) {
err = determine_chmap(tt, &tt_chmap);
if (err < 0) {
- free(ttable);
+ snd_config_delete(sconf);
+ snd_pcm_free_chmaps(chmaps);
return err;
}
snd_config_delete(sconf);
if (err < 0) {
free(tt_chmap);
- free(ttable);
snd_pcm_free_chmaps(chmaps);
return err;
}
update_poll:
if (ready != share->ready) {
- char buf[1];
+ char buf[1] = {0};
while (1) {
if (pcm->stream == SND_PCM_STREAM_PLAYBACK) {
if (ready)
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");
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;
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);
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;
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)
ctrl->u.sw_params = *params;
err = snd_pcm_shm_action(pcm);
*params = ctrl->u.sw_params;
- if (err < 0)
- return err;
return err;
}
int err;
ctrl->cmd = SND_PCM_IOCTL_AVAIL_UPDATE;
err = snd_pcm_shm_action(pcm);
- if (err < 0)
- return err;
return err;
}
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) {
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;
}
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;
return 0;
_err:
- close(sock);
+ if (sock >= 0)
+ close(sock);
if (ctrl)
shmdt(ctrl);
free(shm);
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);
}
*/
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];
}
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;
}
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;
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);
}
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;
}
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;
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;
}
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;
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;
}
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;
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;
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;
}
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);
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)
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);
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)
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)
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) {
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';