Skip to content

Commit 18e96ed

Browse files
cli: fix memory leak in volume status detail (#4292)
cli_volume_status_t has seven pointer fields, but they have two different ownership models: Owned (heap-allocated, caller must free): - brick — GF_MALLOC before the loop - pid_str — gf_asprintf each iteration - free, total — gf_uint64_2human_readable inside cli_get_detail_status Borrowed (point into dict internals, released by dict_unref at out:): - fs_name, mount_options, device, inode_size — dict_get_str The status variable is declared once outside the loop with = {0}. Each iteration overwrites the owned pointers with new allocations. Before this fix, only pid_str was freed inside the loop body and only brick was freed at the out: label. The other two owned pointers (free, total) were simply overwritten each iteration — the previous values were lost, leaking two strings per brick. The fix adds three things: 1. GF_FREE for free and total inside the loop, matching what was already done for pid_str. 2. GF_FREE for pid_str, free, and total at the out: label, covering the two goto-out error paths mid-iteration (gf_asprintf failure at line 7592 and cli_get_detail_status failure at line 7597) where the current iteration's allocations have not been freed yet. 3. Explicit NULLing after each in-loop GF_FREE. On the normal path the loop finishes, execution falls through cont: to out:, which calls GF_FREE on the same pointers again. Without NULLing, that would be a double-free. With it, GF_FREE(NULL) is a no-op. Signed-off-by: Thales Antunes de Oliveira Barretto <thales.barretto.git@gmail.com>
1 parent ae1d696 commit 18e96ed

1 file changed

Lines changed: 8 additions & 1 deletion

File tree

cli/src/cli-rpc-ops.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7601,8 +7601,12 @@ gf_cli_status_cbk(struct rpc_req *req, struct iovec *iov, int count,
76017601
cli_print_brick_status(&status);
76027602
}
76037603

7604-
/* Allocatated memory using gf_asprintf*/
76057604
GF_FREE(status.pid_str);
7605+
status.pid_str = NULL;
7606+
GF_FREE(status.free);
7607+
status.free = NULL;
7608+
GF_FREE(status.total);
7609+
status.total = NULL;
76067610
}
76077611
cli_out(" ");
76087612

@@ -7615,6 +7619,9 @@ gf_cli_status_cbk(struct rpc_req *req, struct iovec *iov, int count,
76157619
if (dict)
76167620
dict_unref(dict);
76177621
GF_FREE(status.brick);
7622+
GF_FREE(status.pid_str);
7623+
GF_FREE(status.free);
7624+
GF_FREE(status.total);
76187625
if (local && wipe_local) {
76197626
cli_local_wipe(local);
76207627
}

0 commit comments

Comments
 (0)