Skip to content

Commit e6e6df4

Browse files
committed
TO-UPSTREAM: sub-process: avoid leaking cmd
Under certain circumstances, the `cmd` attribute is set to an `strdup()`ed value. This value needs to be released in the end! These circumstances can be observed easily in the Microsoft Git fork, where the `read-object` hook triggers that code path. Since other users assign a non-`strdup()`ed value, be careful to add _another_ attribute (called `to_free`) that can hold a reference to such a string that needs to be released once the sub process is done. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent 2bec1a0 commit e6e6df4

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

sub-process.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ void subprocess_stop(struct hashmap *hashmap, struct subprocess_entry *entry)
6060
finish_command(&entry->process);
6161

6262
hashmap_remove(hashmap, &entry->ent, NULL);
63+
FREE_AND_NULL(entry->to_free);
64+
entry->cmd = NULL;
6365
}
6466

6567
static void subprocess_exit_handler(struct child_process *process)
@@ -97,6 +99,7 @@ int subprocess_start(struct hashmap *hashmap, struct subprocess_entry *entry, co
9799
process->trace2_child_class = "subprocess";
98100

99101
entry->cmd = process->args.v[0];
102+
entry->to_free = NULL;
100103

101104
err = start_command(process);
102105
if (err) {
@@ -142,11 +145,13 @@ int subprocess_start_strvec(struct hashmap *hashmap,
142145
process->trace2_child_class = "subprocess";
143146

144147
sq_quote_argv_pretty(&quoted, argv->v);
145-
entry->cmd = strbuf_detach(&quoted, NULL);
148+
entry->cmd = entry->to_free = strbuf_detach(&quoted, NULL);
146149

147150
err = start_command(process);
148151
if (err) {
149152
error("cannot fork to run subprocess '%s'", entry->cmd);
153+
FREE_AND_NULL(entry->to_free);
154+
entry->cmd = NULL;
150155
return err;
151156
}
152157

@@ -155,6 +160,8 @@ int subprocess_start_strvec(struct hashmap *hashmap,
155160
err = startfn(entry);
156161
if (err) {
157162
error("initialization for subprocess '%s' failed", entry->cmd);
163+
FREE_AND_NULL(entry->to_free);
164+
entry->cmd = NULL;
158165
subprocess_stop(hashmap, entry);
159166
return err;
160167
}

sub-process.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525
struct subprocess_entry {
2626
struct hashmap_entry ent;
2727
const char *cmd;
28+
/**
29+
* In case `cmd` is a `strdup()`ed value that needs to be released,
30+
* you can assign the pointer to `to_free` so that `subprocess_stop()`
31+
* will release it.
32+
*/
33+
char *to_free;
2834
struct child_process process;
2935
};
3036

0 commit comments

Comments
 (0)