Make json_object_add_value_string() duplicate its 'value' argument
authorBart Van Assche <bvanassche@acm.org>
Sun, 24 May 2020 20:25:37 +0000 (13:25 -0700)
committerBart Van Assche <bvanassche@acm.org>
Sun, 24 May 2020 21:41:36 +0000 (14:41 -0700)
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 <bvanassche@acm.org>
client.c
json.h
stat.c

index b75755963dcb406146376f3cc1e0121adddab94e..81d23663770c7624297c1a9ed4cd3596b731a226 100644 (file)
--- 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 1544ed765055f9c0e4aabb207b80dd0536bc43ec..d98242638d4a186b13fa6ba2da86639454dc47b8 100644 (file)
--- 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 2cf11947d99adac33ef3195a08f8039d3399492b..b3951199bcc81a28f4728f2c327a30071faa252f 100644 (file)
--- 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);
        }
 }