From fa4a7bda4ec3e10d43e96661e7e1fce29fff92ae Mon Sep 17 00:00:00 2001 From: Seppo Ingalsuo Date: Tue, 28 Jul 2020 18:23:49 +0300 Subject: [PATCH] Testbench: Check num_elems in tokens parsing This patch adds check for sane num_elems value. If the calculated array size exceeds the value size an error is returned and topology parsing is aborted. Signed-off-by: Seppo Ingalsuo --- .../include/tplg_parser/topology.h | 24 +++---- tools/tplg_parser/tplg_parser.c | 65 +++++++++++++------ 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/tools/tplg_parser/include/tplg_parser/topology.h b/tools/tplg_parser/include/tplg_parser/topology.h index d98acdb71..64fac8c7d 100644 --- a/tools/tplg_parser/include/tplg_parser/topology.h +++ b/tools/tplg_parser/include/tplg_parser/topology.h @@ -200,18 +200,18 @@ int sof_parse_tokens(void *object, const struct sof_topology_token *tokens, int count, struct snd_soc_tplg_vendor_array *array, int priv_size); -void sof_parse_string_tokens(void *object, - const struct sof_topology_token *tokens, - int count, - struct snd_soc_tplg_vendor_array *array); -void sof_parse_uuid_tokens(void *object, - const struct sof_topology_token *tokens, - int count, - struct snd_soc_tplg_vendor_array *array); -void sof_parse_word_tokens(void *object, - const struct sof_topology_token *tokens, - int count, - struct snd_soc_tplg_vendor_array *array); +int sof_parse_string_tokens(void *object, + const struct sof_topology_token *tokens, + int count, + struct snd_soc_tplg_vendor_array *array); +int sof_parse_uuid_tokens(void *object, + const struct sof_topology_token *tokens, + int count, + struct snd_soc_tplg_vendor_array *array); +int sof_parse_word_tokens(void *object, + const struct sof_topology_token *tokens, + int count, + struct snd_soc_tplg_vendor_array *array); int get_token_dai_type(void *elem, void *object, uint32_t offset, uint32_t size); enum sof_ipc_dai_type find_dai(const char *name); diff --git a/tools/tplg_parser/tplg_parser.c b/tools/tplg_parser/tplg_parser.c index 2ebb22802..1ebdf4e74 100644 --- a/tools/tplg_parser/tplg_parser.c +++ b/tools/tplg_parser/tplg_parser.c @@ -1264,8 +1264,9 @@ int sof_parse_tokens(void *object, const struct sof_topology_token *tokens, int priv_size) { int asize; + int ret = 0; - while (priv_size > 0) { + while (priv_size > 0 && ret == 0) { asize = array->size; /* validate asize */ @@ -1287,19 +1288,16 @@ int sof_parse_tokens(void *object, const struct sof_topology_token *tokens, /* call correct parser depending on type */ switch (array->type) { case SND_SOC_TPLG_TUPLE_TYPE_UUID: - sof_parse_uuid_tokens(object, tokens, count, - array); + ret = sof_parse_uuid_tokens(object, tokens, count, array); break; case SND_SOC_TPLG_TUPLE_TYPE_STRING: - sof_parse_string_tokens(object, tokens, count, - array); + ret = sof_parse_string_tokens(object, tokens, count, array); break; case SND_SOC_TPLG_TUPLE_TYPE_BOOL: case SND_SOC_TPLG_TUPLE_TYPE_BYTE: case SND_SOC_TPLG_TUPLE_TYPE_WORD: case SND_SOC_TPLG_TUPLE_TYPE_SHORT: - sof_parse_word_tokens(object, tokens, count, - array); + ret = sof_parse_word_tokens(object, tokens, count, array); break; default: fprintf(stderr, "error: unknown token type %d\n", @@ -1307,18 +1305,25 @@ int sof_parse_tokens(void *object, const struct sof_topology_token *tokens, return -EINVAL; } } - return 0; + return ret; } /* parse word tokens */ -void sof_parse_word_tokens(void *object, - const struct sof_topology_token *tokens, - int count, - struct snd_soc_tplg_vendor_array *array) +int sof_parse_word_tokens(void *object, + const struct sof_topology_token *tokens, + int count, + struct snd_soc_tplg_vendor_array *array) { struct snd_soc_tplg_vendor_value_elem *elem; int i, j; + if (sizeof(struct snd_soc_tplg_vendor_value_elem) * array->num_elems + + sizeof(struct snd_soc_tplg_vendor_array) > array->size) { + fprintf(stderr, "error: illegal array number of elements %d\n", + array->num_elems); + return -EINVAL; + } + /* parse element by element */ for (i = 0; i < array->num_elems; i++) { elem = &array->value[i]; @@ -1338,17 +1343,26 @@ void sof_parse_word_tokens(void *object, tokens[j].size); } } + + return 0; } /* parse uuid tokens */ -void sof_parse_uuid_tokens(void *object, - const struct sof_topology_token *tokens, - int count, - struct snd_soc_tplg_vendor_array *array) +int sof_parse_uuid_tokens(void *object, + const struct sof_topology_token *tokens, + int count, + struct snd_soc_tplg_vendor_array *array) { struct snd_soc_tplg_vendor_uuid_elem *elem; int i, j; + if (sizeof(struct snd_soc_tplg_vendor_uuid_elem) * array->num_elems + + sizeof(struct snd_soc_tplg_vendor_array) > array->size) { + fprintf(stderr, "error: illegal array number of elements %d\n", + array->num_elems); + return -EINVAL; + } + /* parse element by element */ for (i = 0; i < array->num_elems; i++) { elem = &array->uuid[i]; @@ -1368,17 +1382,26 @@ void sof_parse_uuid_tokens(void *object, tokens[j].size); } } + + return 0; } /* parse string tokens */ -void sof_parse_string_tokens(void *object, - const struct sof_topology_token *tokens, - int count, - struct snd_soc_tplg_vendor_array *array) +int sof_parse_string_tokens(void *object, + const struct sof_topology_token *tokens, + int count, + struct snd_soc_tplg_vendor_array *array) { struct snd_soc_tplg_vendor_string_elem *elem; int i, j; + if (sizeof(struct snd_soc_tplg_vendor_string_elem) * array->num_elems + + sizeof(struct snd_soc_tplg_vendor_array) > array->size) { + fprintf(stderr, "error: illegal array number of elements %d\n", + array->num_elems); + return -EINVAL; + } + /* parse element by element */ for (i = 0; i < array->num_elems; i++) { elem = &array->string[i]; @@ -1398,6 +1421,8 @@ void sof_parse_string_tokens(void *object, tokens[j].size); } } + + return 0; } enum sof_ipc_frame find_format(const char *name)