Skip to content

Commit 37abfec

Browse files
cli: fix memory leak in volume status detail (#4292)
gf_cli_status_cbk() never freed the heap strings status.free and status.total returned by gf_uint64_2human_readable() via gf_asprintf(). Each invocation of `gluster volume status all detail` leaked two strings per brick reported. The reporter's ASan trace confirms 144 bytes leaked in 4 allocations (2 calls x 2 bricks). The other string fields in cli_volume_status_t (fs_name, mount_options, device, inode_size) are borrowed pointers from dict_get_str() — they are released by dict_unref() at the out: label and must NOT be freed per-field. Also fix a pre-existing leak of status.pid_str on the cli_get_detail_status() error path: if cli_get_detail_status() fails (goto out after line 7597), pid_str is already allocated via gf_asprintf() but the out: label never freed it. The gf_asprintf failure path at line 7592 cannot leak pid_str because gf_vasprintf() does not write *string_ptr on allocation failure — the pointer stays NULL from the {0} initializer. Since GF_FREE() does not NULL the freed pointer, all per-iteration pointers are explicitly NULLed after freeing to prevent double-free when the normal path falls through to out:. Fixes: #4292 Signed-off-by: Thales Antunes de Oliveira Barretto <thales.barretto.git@gmail.com>
1 parent ae1d696 commit 37abfec

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)