mesh: Fix segfault related to idle config write 04/234204/1
authorInga Stotland <inga.stotland@intel.com>
Thu, 2 Apr 2020 00:04:36 +0000 (17:04 -0700)
committerAbhay Agarwal <ay.agarwal@samsung.com>
Fri, 22 May 2020 04:23:42 +0000 (09:53 +0530)
If node configuration is completely removed from the system,
remove all pending writes to the configuration file.

Fixes the segfault below:

mesh/cfgmod-server.c:node_reset() Node Reset
mesh/mesh-config-json.c:mesh_config_destroy() Delete node config /var/lib/bluetooth/mesh/02040d0a060e0a08090b0103070f050c
mesh/util.c:del_fobject() RM /var/lib/bluetooth/mesh/02040d0a060e0a08090b0103070f050c/rpl/00000000/0001
mesh/util.c:del_fobject() RMDIR /var/lib/bluetooth/mesh/02040d0a060e0a08090b0103070f050c/rpl/00000000
mesh/util.c:del_fobject() RMDIR /var/lib/bluetooth/mesh/02040d0a060e0a08090b0103070f050c/rpl
mesh/util.c:del_fobject() RM /var/lib/bluetooth/mesh/02040d0a060e0a08090b0103070f050c/node.json.bak
mesh/util.c:del_fobject() RM /var/lib/bluetooth/mesh/02040d0a060e0a08090b0103070f050c/node.json
mesh/util.c:del_fobject() RMDIR /var/lib/bluetooth/mesh/02040d0a060e0a08090b0103070f050c
Segmentation fault

Program terminated with signal SIGSEGV, Segmentation fault.

  0x0000563a35df2ed0 in ?? ()
  0x00007fd6b131689f in json_object_to_json_string_length (jso=jso@entry=0x563a35dd8d30, flags=flags@entry=2,

Change-Id: Id92320eb3f05f4bda52cff1b6e41c5345bf1df2f
Signed-off-by: Abhay Agarwal <ay.agarwal@samsung.com>
mesh/mesh-config-json.c

index 66f6d27..ad1a355 100644 (file)
@@ -55,6 +55,7 @@ struct mesh_config {
        uint8_t uuid[16];
        uint32_t write_seq;
        struct timeval write_time;
+       struct l_queue *idles;
 };
 
 struct write_info {
@@ -1678,6 +1679,7 @@ static struct mesh_config *create_config(const char *cfg_path,
        memcpy(cfg->uuid, uuid, 16);
        cfg->node_dir_path = l_strdup(cfg_path);
        cfg->write_seq = node->seq_number;
+       cfg->idles = l_queue_new();
        gettimeofday(&cfg->write_time, NULL);
 
        return cfg;
@@ -2105,6 +2107,7 @@ static bool load_node(const char *fname, const uint8_t uuid[16],
                memcpy(cfg->uuid, uuid, 16);
                cfg->node_dir_path = l_strdup(fname);
                cfg->write_seq = node.seq_number;
+               cfg->idles = l_queue_new();
                gettimeofday(&cfg->write_time, NULL);
 
                result = cb(&node, uuid, cfg, user_data);
@@ -2131,17 +2134,26 @@ done:
        return result;
 }
 
+static void release_idle(void *data)
+{
+       struct l_idle *idle = data;
+
+       l_idle_remove(idle);
+}
+
 void mesh_config_release(struct mesh_config *cfg)
 {
        if (!cfg)
                return;
 
+       l_queue_destroy(cfg->idles, release_idle);
+
        l_free(cfg->node_dir_path);
        json_object_put(cfg->jnode);
        l_free(cfg);
 }
 
-static void idle_save_config(void *user_data)
+static void idle_save_config(struct l_idle *idle, void *user_data)
 {
        struct write_info *info = user_data;
        char *fname_tmp, *fname_bak, *fname_cfg;
@@ -2170,6 +2182,11 @@ static void idle_save_config(void *user_data)
        if (info->cb)
                info->cb(info->user_data, result);
 
+       if (idle) {
+               l_queue_remove(info->cfg->idles, idle);
+               l_idle_remove(idle);
+       }
+
        l_free(info);
 
 }
@@ -2187,10 +2204,14 @@ bool mesh_config_save(struct mesh_config *cfg, bool no_wait,
        info->cb = cb;
        info->user_data = user_data;
 
-       if (no_wait)
-               idle_save_config(info);
-       else
-               l_idle_oneshot(idle_save_config, info, NULL);
+       if (no_wait) {
+               idle_save_config(NULL, info);
+       } else {
+               struct l_idle *idle;
+
+               idle = l_idle_create(idle_save_config, info, NULL);
+               l_queue_push_tail(cfg->idles, idle);
+       }
 
        return true;
 }