git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] run-command: do not pass child process data into callbacks

From
Stefan Beller <sbeller@google.com>
Date
Feb 29, 2016, 21:57 UTC
Message-ID
<1456783026-3328-1-git-send-email-sbeller@google.com>

The expected way to pass data into the callback is to pass them via the customizable callback pointer. The error reporting in default_{start_failure, task_finished} is not user friendly enough, that we want to encourage using the child data for such purposes.

Furthermore the struct child data is cleaned by the run-command API, before we access them in the callbacks, leading to use-after-free situations.

Signed-off-by: Stefan Beller <sbeller@google.com>
---
 This is the proper fix to not access memory after freeing.
 run-command.c      | 24 +++---------------------
 run-command.h      |  4 +---
 submodule.c        |  7 +++----
 test-run-command.c |  1 -
 4 files changed, 7 insertions(+), 29 deletions(-)
diff --git a/run-command.c b/run-command.c
index 863dad5..c726010 100644
--- a/run-command.c
+++ b/run-command.c
@@ -902,35 +902,18 @@ struct parallel_processes {
 	struct strbuf buffered_output; /* of finished children */
 };
 
-static int default_start_failure(struct child_process *cp,
-				 struct strbuf *err,
+static int default_start_failure(struct strbuf *err,
 				 void *pp_cb,
 				 void *pp_task_cb)
 {
-	int i;
-
-	strbuf_addstr(err, "Starting a child failed:");
-	for (i = 0; cp->argv[i]; i++)
-		strbuf_addf(err, " %s", cp->argv[i]);
-
 	return 0;
 }
 
 static int default_task_finished(int result,
-				 struct child_process *cp,
 				 struct strbuf *err,
 				 void *pp_cb,
 				 void *pp_task_cb)
 {
-	int i;
-
-	if (!result)
-		return 0;
-
-	strbuf_addf(err, "A child failed with return code %d:", result);
-	for (i = 0; cp->argv[i]; i++)
-		strbuf_addf(err, " %s", cp->argv[i]);
-
 	return 0;
 }
 
@@ -1048,8 +1031,7 @@ static int pp_start_one(struct parallel_processes *pp)
 	pp->children[i].process.no_stdin = 1;
 
 	if (start_command(&pp->children[i].process)) {
-		code = pp->start_failure(&pp->children[i].process,
-					 &pp->children[i].err,
+		code = pp->start_failure(&pp->children[i].err,
 					 pp->data,
 					 &pp->children[i].data);
 		strbuf_addbuf(&pp->buffered_output, &pp->children[i].err);
@@ -1117,7 +1099,7 @@ static int pp_collect_finished(struct parallel_processes *pp)
 
 		code = finish_command(&pp->children[i].process);
 
-		code = pp->task_finished(code, &pp->children[i].process,
+		code = pp->task_finished(code,
 					 &pp->children[i].err, pp->data,
 					 &pp->children[i].data);
 
diff --git a/run-command.h b/run-command.h
index 42917e8..c6a3e42 100644
--- a/run-command.h
+++ b/run-command.h
@@ -159,8 +159,7 @@ typedef int (*get_next_task_fn)(struct child_process *cp,
  * To send a signal to other child processes for abortion, return
  * the negative signal number.
  */
-typedef int (*start_failure_fn)(struct child_process *cp,
-				struct strbuf *err,
+typedef int (*start_failure_fn)(struct strbuf *err,
 				void *pp_cb,
 				void *pp_task_cb);
 
@@ -179,7 +178,6 @@ typedef int (*start_failure_fn)(struct child_process *cp,
  * the negative signal number.
  */
 typedef int (*task_finished_fn)(int result,
-				struct child_process *cp,
 				struct strbuf *err,
 				void *pp_cb,
 				void *pp_task_cb);
diff --git a/submodule.c b/submodule.c
index 24fb81a..62c4356 100644
--- a/submodule.c
+++ b/submodule.c
@@ -705,8 +705,7 @@ static int get_next_submodule(struct child_process *cp,
 	return 0;
 }
 
-static int fetch_start_failure(struct child_process *cp,
-			       struct strbuf *err,
+static int fetch_start_failure(struct strbuf *err,
 			       void *cb, void *task_cb)
 {
 	struct submodule_parallel_fetch *spf = cb;
@@ -716,8 +715,8 @@ static int fetch_start_failure(struct child_process *cp,
 	return 0;
 }
 
-static int fetch_finish(int retvalue, struct child_process *cp,
-			struct strbuf *err, void *cb, void *task_cb)
+static int fetch_finish(int retvalue, struct strbuf *err,
+			void *cb, void *task_cb)
 {
 	struct submodule_parallel_fetch *spf = cb;
 
diff --git a/test-run-command.c b/test-run-command.c
index fbe0a27..30a64a9 100644
--- a/test-run-command.c
+++ b/test-run-command.c
@@ -41,7 +41,6 @@ static int no_job(struct child_process *cp,
 }
 
 static int task_finished(int result,
-			 struct child_process *cp,
 			 struct strbuf *err,
 			 void *pp_cb,
 			 void *pp_task_cb)
-- 
2.8.0.rc0.1.g68b4e3f
Next: Stefan Beller
Message 1 of 6 in “run-command: do not pass child process data into callbacks”
  1. run-command: do not pass child process data into callbacksStefan Beller, Feb 29, 2016
  2. Stefan BellerFeb 29, 2016
  3. Junio C HamanoFeb 29, 2016
  4. Johannes SixtMar 1, 2016
  5. Junio C HamanoMar 1, 2016
  6. [PATCHv2] run-command: do not pass child process data into callbacksStefan Beller, Mar 1, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.