Currently, when fw_cfg_add_file_callback() is invoked with a duplicate file name, it gets to insert the data blob at the next available selector, but exit (signalling the error via a call to the trace_fw_cfg_add_file_dupe() function) before incrementing the next available selector as soon as it finds the requested file name to be a dupe.
As a consequence, the immediately following invocation of fw_cfg_add_file_callback() will cause the data blob pointer at the current selector to be overwritten, and therefore leak the old data blob inserted during the previous failed call (or, instead, trigger the newly added assertion which guards against leaking data blobs by overwriting their pointers). This patch modifies fw_cfg_add_file_callback() to exit qemu with an error whenever a duplicate fw_cfg file name insertion is requested. Signed-off-by: Gabriel Somlo <so...@cmu.edu> --- hw/nvram/fw_cfg.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index 5501a97..86f120e 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -481,17 +481,18 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename, index = be32_to_cpu(s->files->count); assert(index < FW_CFG_FILE_SLOTS); + for (i = 0; i < index; i++) { + if (strcmp(filename, s->files->f[i].name) == 0) { + error_report("duplicate fw_cfg file name: %s", filename); + exit(1); + } + } + fw_cfg_add_bytes_read_callback(s, FW_CFG_FILE_FIRST + index, callback, callback_opaque, data, len); pstrcpy(s->files->f[index].name, sizeof(s->files->f[index].name), filename); - for (i = 0; i < index; i++) { - if (strcmp(s->files->f[index].name, s->files->f[i].name) == 0) { - trace_fw_cfg_add_file_dupe(s, s->files->f[index].name); - return; - } - } s->files->f[index].size = cpu_to_be32(len); s->files->f[index].select = cpu_to_be16(FW_CFG_FILE_FIRST + index); -- 2.1.0