From f4ee45366faca0e0e8a964434d7c8a7fbdbac228 Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Fri, 21 Aug 2020 20:27:25 +0530 Subject: mixer: Fix invalid size check in mixer_ctl_set/get_array For TLV based mixer controls, mixer_ctl_set/get_array adds TLV headers in the API itself. Size check for count need not include tlv header size addition. Remove it to fix size check. --- src/mixer.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/mixer.c b/src/mixer.c index 94aa019..6a104fe 100644 --- a/src/mixer.c +++ b/src/mixer.c @@ -936,21 +936,13 @@ int mixer_ctl_get_array(const struct mixer_ctl *ctl, void *array, size_t count) int ret = 0; size_t size; void *source; - size_t total_count; if (!ctl || !count || !array) return -EINVAL; grp = ctl->grp; - total_count = ctl->info.count; - if ((ctl->info.type == SNDRV_CTL_ELEM_TYPE_BYTES) && - (mixer_ctl_is_access_tlv_rw(ctl))) { - /* Additional two words is for the TLV header */ - total_count += TLV_HEADER_SIZE; - } - - if (count > total_count) + if (count > ctl->info.count) return -EINVAL; memset(&ev, 0, sizeof(ev)); @@ -974,9 +966,11 @@ int mixer_ctl_get_array(const struct mixer_ctl *ctl, void *array, size_t count) if (count > SIZE_MAX - sizeof(*tlv)) return -EINVAL; + tlv = calloc(1, sizeof(*tlv) + count); if (!tlv) return -ENOMEM; + tlv->numid = ctl->info.id.numid; tlv->length = count; ret = grp->ops->ioctl(grp->data, SNDRV_CTL_IOCTL_TLV_READ, tlv); @@ -1076,21 +1070,13 @@ int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count) struct snd_ctl_elem_value ev; size_t size; void *dest; - size_t total_count; if ((!ctl) || !count || !array) return -EINVAL; grp = ctl->grp; - total_count = ctl->info.count; - if ((ctl->info.type == SNDRV_CTL_ELEM_TYPE_BYTES) && - (mixer_ctl_is_access_tlv_rw(ctl))) { - /* Additional TLV header */ - total_count += TLV_HEADER_SIZE; - } - - if (count > total_count) + if (count > ctl->info.count) return -EINVAL; memset(&ev, 0, sizeof(ev)); @@ -1108,11 +1094,14 @@ int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count) if (mixer_ctl_is_access_tlv_rw(ctl)) { struct snd_ctl_tlv *tlv; int ret = 0; + if (count > SIZE_MAX - sizeof(*tlv)) return -EINVAL; + tlv = calloc(1, sizeof(*tlv) + count); if (!tlv) return -ENOMEM; + tlv->numid = ctl->info.id.numid; tlv->length = count; memcpy(tlv->tlv, array, count); -- cgit v1.2.3 From 6125aaf4f7af3ba73c3b3695ccdccb6cf8e3dd82 Mon Sep 17 00:00:00 2001 From: Rohit kumar Date: Fri, 4 Sep 2020 14:58:39 +0530 Subject: tinymix: Fix get/set for tlv based mixer controls TLV header is added by tinyalsa library. Remove tlv header addition from tinymix to avoid adding it twice. --- utils/tinymix.c | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/utils/tinymix.c b/utils/tinymix.c index a47005c..fdb774c 100644 --- a/utils/tinymix.c +++ b/utils/tinymix.c @@ -200,7 +200,6 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control) int min, max; int ret; char *buf = NULL; - unsigned int tlv_header_size = 0; if (isdigit(control[0])) ctl = mixer_get_ctl(mixer, atoi(control)); @@ -216,16 +215,13 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control) num_values = mixer_ctl_get_num_values(ctl); if ((type == MIXER_CTL_TYPE_BYTE) && (num_values > 0)) { - if (mixer_ctl_is_access_tlv_rw(ctl) != 0) { - tlv_header_size = TLV_HEADER_SIZE; - } - buf = calloc(1, num_values + tlv_header_size); + buf = calloc(1, num_values); if (buf == NULL) { fprintf(stderr, "Failed to alloc mem for bytes %u\n", num_values); return; } - ret = mixer_ctl_get_array(ctl, buf, num_values + tlv_header_size); + ret = mixer_ctl_get_array(ctl, buf, num_values); if (ret < 0) { fprintf(stderr, "Failed to mixer_ctl_get_array\n"); free(buf); @@ -246,8 +242,7 @@ static void tinymix_detail_control(struct mixer *mixer, const char *control) tinymix_print_enum(ctl); break; case MIXER_CTL_TYPE_BYTE: - /* skip printing TLV header if exists */ - printf(" %02x", buf[i + tlv_header_size]); + printf(" %02x", buf[i]); break; default: printf("unknown"); @@ -275,25 +270,13 @@ static void tinymix_set_byte_ctl(struct mixer_ctl *ctl, char *end; unsigned int i; long n; - unsigned int *tlv, tlv_size; - unsigned int tlv_header_size = 0; - - if (mixer_ctl_is_access_tlv_rw(ctl) != 0) { - tlv_header_size = TLV_HEADER_SIZE; - } - tlv_size = num_values + tlv_header_size; - - buf = calloc(1, tlv_size); + buf = calloc(1, num_values); if (buf == NULL) { fprintf(stderr, "set_byte_ctl: Failed to alloc mem for bytes %u\n", num_values); exit(EXIT_FAILURE); } - tlv = (unsigned int *)buf; - tlv[0] = 0; - tlv[1] = num_values; - for (i = 0; i < num_values; i++) { errno = 0; n = strtol(values[i], &end, 0); @@ -311,11 +294,10 @@ static void tinymix_set_byte_ctl(struct mixer_ctl *ctl, values[i]); goto fail; } - /* start filling after tlv header */ - buf[i + tlv_header_size] = n; + buf[i] = n; } - ret = mixer_ctl_set_array(ctl, buf, tlv_size); + ret = mixer_ctl_set_array(ctl, buf, num_values); if (ret < 0) { fprintf(stderr, "Failed to set binary control\n"); goto fail; -- cgit v1.2.3