diff --git a/tools/probes/probes_demux.c b/tools/probes/probes_demux.c index a411eef117b9..28e09a773769 100644 --- a/tools/probes/probes_demux.c +++ b/tools/probes/probes_demux.c @@ -23,6 +23,7 @@ #define APP_NAME "sof-probes" #define PACKET_MAX_SIZE 4096 /**< Size limit for probe data packet */ +#define PACKET_DATA_SIZE_MAX (16 * 1024 * 1024) /**< Sanity limit for packet data size */ #define DATA_READ_LIMIT 4096 /**< Data limit for file read */ #define FILES_LIMIT 32 /**< Maximum num of probe output files */ #define FILE_PATH_LIMIT 128 /**< Path limit for probe output files */ @@ -194,6 +195,12 @@ int process_sync(struct dma_frame_parser *p) { struct probe_data_packet *temp_packet; + if (p->packet->data_size_bytes > PACKET_DATA_SIZE_MAX) { + fprintf(stderr, "error: packet data size %u exceeds maximum %u\n", + p->packet->data_size_bytes, PACKET_DATA_SIZE_MAX); + return -EINVAL; + } + /* request to copy data_size from probe packet and 64-bit checksum */ p->total_data_to_copy = p->packet->data_size_bytes + sizeof(uint64_t); diff --git a/tools/testbench/topology_ipc3.c b/tools/testbench/topology_ipc3.c index b95dc9859e68..331ab2ff1103 100644 --- a/tools/testbench/topology_ipc3.c +++ b/tools/testbench/topology_ipc3.c @@ -98,7 +98,8 @@ static int tb_register_graph(struct tplg_context *ctx, struct tplg_comp_info *te for (i = 0; i < num_connections; i++) { ret = tplg_create_graph(ctx, num_comps, pipeline_id, temp_comp_list, - pipeline_string, &connection, i); + pipeline_string, sizeof(pipeline_string), + &connection, i); if (ret < 0) return ret; diff --git a/tools/tplg_parser/graph.c b/tools/tplg_parser/graph.c index 7bc9f33449bd..ddef730f492d 100644 --- a/tools/tplg_parser/graph.c +++ b/tools/tplg_parser/graph.c @@ -23,6 +23,7 @@ /* load pipeline graph DAPM widget*/ int tplg_create_graph(struct tplg_context *ctx, int count, int pipeline_id, struct tplg_comp_info *temp_comp_list, char *pipeline_string, + size_t pipeline_string_size, struct sof_ipc_pipe_comp_connect *connection, int route_num) { @@ -64,12 +65,22 @@ int tplg_create_graph(struct tplg_context *ctx, int count, int pipeline_id, printf("loading route %s -> %s\n", source, sink); - strcat(pipeline_string, graph_elem->source); - strcat(pipeline_string, "->"); - - if (route_num == (count - 1)) { - strcat(pipeline_string, graph_elem->sink); - strcat(pipeline_string, "\n"); + { + size_t cur_len = strlen(pipeline_string); + size_t remaining = pipeline_string_size > cur_len ? + pipeline_string_size - cur_len : 0; + int written; + + if (route_num == (count - 1)) + written = snprintf(pipeline_string + cur_len, remaining, + "%s->%s\n", graph_elem->source, + graph_elem->sink); + else + written = snprintf(pipeline_string + cur_len, remaining, + "%s->", graph_elem->source); + + if (written < 0 || (size_t)written >= remaining) + fprintf(stderr, "warning: pipeline string truncated\n"); } return 0; diff --git a/tools/tplg_parser/include/tplg_parser/topology.h b/tools/tplg_parser/include/tplg_parser/topology.h index 04988d688082..aec423a354de 100644 --- a/tools/tplg_parser/include/tplg_parser/topology.h +++ b/tools/tplg_parser/include/tplg_parser/topology.h @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -194,8 +196,20 @@ struct tplg_context { #define tplg_get(ctx) ((void *)(ctx->tplg_base + ctx->tplg_offset)) +#define tplg_check_bounds(ctx, advance) \ + do { \ + if ((long)(advance) < 0 || \ + ctx->tplg_offset + (long)(advance) > (long)ctx->tplg_size) { \ + printf("%s %d topology offset %ld + %ld > size %zu\n", \ + __func__, __LINE__, ctx->tplg_offset, \ + (long)(advance), ctx->tplg_size); \ + assert(0); \ + } \ + } while (0) + #define tplg_get_hdr(ctx) \ ({struct snd_soc_tplg_hdr *ptr; \ + tplg_check_bounds(ctx, sizeof(*ptr)); \ ptr = (struct snd_soc_tplg_hdr *)(ctx->tplg_base + ctx->tplg_offset); \ if (ptr->size != sizeof(*ptr)) { \ printf("%s %d hdr size mismatch 0x%x:0x%zx at offset %ld\n", \ @@ -206,30 +220,40 @@ struct tplg_context { #define tplg_skip_hdr_payload(ctx) \ ({struct snd_soc_tplg_hdr *ptr; \ + tplg_check_bounds(ctx, hdr->payload_size); \ ptr = (struct snd_soc_tplg_hdr *)(ctx->tplg_base + ctx->tplg_offset); \ ctx->tplg_offset += hdr->payload_size; (void *)ptr; }) #define tplg_get_object(ctx, obj) \ - ({void *ptr; ptr = ctx->tplg_base + ctx->tplg_offset; \ + ({void *ptr; \ + tplg_check_bounds(ctx, sizeof(*(obj))); \ + ptr = ctx->tplg_base + ctx->tplg_offset; \ ctx->tplg_offset += sizeof(*(obj)); ptr; }) #define tplg_get_object_priv(ctx, obj, priv_size) \ - ({void *ptr; ptr = ctx->tplg_base + ctx->tplg_offset; \ + ({void *ptr; \ + tplg_check_bounds(ctx, sizeof(*(obj)) + (priv_size)); \ + ptr = ctx->tplg_base + ctx->tplg_offset; \ ctx->tplg_offset += sizeof(*(obj)) + priv_size; ptr; }) #define tplg_get_widget(ctx) \ ({struct snd_soc_tplg_dapm_widget *w; \ + tplg_check_bounds(ctx, sizeof(*w)); \ w = (struct snd_soc_tplg_dapm_widget *)(ctx->tplg_base + ctx->tplg_offset); \ + tplg_check_bounds(ctx, sizeof(*w) + w->priv.size); \ ctx->tplg_offset += sizeof(*w) + w->priv.size; w; }) #define tplg_get_graph(ctx) \ ({struct snd_soc_tplg_dapm_graph_elem *w; \ + tplg_check_bounds(ctx, sizeof(*w)); \ w = (struct snd_soc_tplg_dapm_graph_elem *)(ctx->tplg_base + ctx->tplg_offset); \ ctx->tplg_offset += sizeof(*w); w; }) #define tplg_get_pcm(ctx) \ ({struct snd_soc_tplg_pcm *pcm; \ + tplg_check_bounds(ctx, sizeof(*pcm)); \ pcm = (struct snd_soc_tplg_pcm *)(ctx->tplg_base + ctx->tplg_offset); \ + tplg_check_bounds(ctx, sizeof(*pcm) + pcm->priv.size); \ ctx->tplg_offset += sizeof(*pcm) + pcm->priv.size; pcm; }) static inline int tplg_valid_widget(struct snd_soc_tplg_dapm_widget *widget) @@ -314,6 +338,7 @@ int tplg_new_process(struct tplg_context *ctx, void *process, size_t process_siz int tplg_create_graph(struct tplg_context *ctx, int count, int pipeline_id, struct tplg_comp_info *temp_comp_list, char *pipeline_string, + size_t pipeline_string_size, struct sof_ipc_pipe_comp_connect *connection, int route_num);