From c42b48fed60105b4bcd443b9a013548e9e9c43e0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sun, 24 May 2020 13:25:37 -0700 Subject: [PATCH] Make json_object_add_value_string() duplicate its 'value' argument Having some json_object_add_value_string() callers duplicate the 'value' argument others not is dubious because it can lead to dangling pointers, e.g. when passing strings to json_object_add_value_string() that live less long than the created JSON object. See e.g. the 'time_buf' stack array that is passed by fio_client_json_init() to json_object_add_value_string(). Signed-off-by: Bart Van Assche --- client.c | 15 ++++----------- json.h | 2 +- stat.c | 6 +----- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/client.c b/client.c index b7575596..81d23663 100644 --- a/client.c +++ b/client.c @@ -1151,24 +1151,17 @@ static void handle_job_opt(struct fio_client *client, struct fio_net_cmd *cmd) p = malloc(sizeof(*p)); p->name = strdup((char *) pdu->name); - if (pdu->value[0] != '\0') - p->value = strdup((char *) pdu->value); - else - p->value = NULL; if (pdu->global) { - const char *pos = ""; - - if (p->value) - pos = p->value; - - json_object_add_value_string(job_opt_object, p->name, pos); + json_object_add_value_string(job_opt_object, p->name, + (const char *)pdu->value); } else if (client->opt_lists) { struct flist_head *opt_list = &client->opt_lists[pdu->groupid]; + p->value = pdu->value[0] ? strdup((const char *)pdu->value) : + NULL; flist_add_tail(&p->list, opt_list); } else { - free(p->value); free(p->name); free(p); } diff --git a/json.h b/json.h index 1544ed76..d9824263 100644 --- a/json.h +++ b/json.h @@ -82,7 +82,7 @@ static inline int json_object_add_value_string(struct json_object *obj, .type = JSON_TYPE_STRING, }; - arg.string = (char *)val; + arg.string = strdup(val ? : ""); return json_object_add_value_type(obj, name, &arg); } diff --git a/stat.c b/stat.c index 2cf11947..b3951199 100644 --- a/stat.c +++ b/stat.c @@ -1506,12 +1506,8 @@ static void json_add_job_opts(struct json_object *root, const char *name, json_object_add_value_object(root, name, dir_object); flist_for_each(entry, opt_list) { - const char *pos = ""; - p = flist_entry(entry, struct print_option, list); - if (p->value) - pos = p->value; - json_object_add_value_string(dir_object, p->name, pos); + json_object_add_value_string(dir_object, p->name, p->value); } } -- 2.25.1