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

Re: [REGRESSION] git-wrapper to run-commands codepath regression

From
Jeff King <peff@peff.net>
Date
Apr 18, 2011, 21:18 UTC
Message-ID
<20110418211849.GB13566@sigill.intra.peff.net>
In-Reply-To
<20110418211102.GA13566@sigill.intra.peff.net>
On Mon, Apr 18, 2011 at 05:11:02PM -0400, Jeff King wrote:
Show 13 quoted lines
> The good news is that the bug is trivial. It bisects Jonathan's ebec842
> (run-command: prettify -D_FORTIFY_SOURCE workaround, 2011-03-16), which
> introduces:
> 
> -       unused = write(child_err, "fatal: ", 7);
> -       unused = write(child_err, msg, len);
> -       unused = write(child_err, "\n", 1);
> +       if (write(child_err, "fatal: ", 7) ||
> +           write(child_err, msg, len) ||
> +           write(child_err, "\n", 1))
> +               ; /* yes, gcc -D_FORTIFY_SOURCE, we know there was an error. */
> 
> Stare at that for a minute and see if you can guess what's wrong. :)
And here's the fix.
-- >8 --
Subject: [PATCH] run-command: fix broken error messages from child

After we fork, we try to exec the child; if exec fails, we write an error message and exit. We ignore the return value of write, since there's nothing we can do about it.

Commit ebec842 turned this into a conditional to make -D_FORTIFY_SOURCE happy with the ignored return value, but botched the change so that we never write more than "fatal:".

Write will return the number of bytes written, so the conditional as written will always appear as an error. Of course we don't actually do anything for the error, but the short-circuit logic means we never execute the subsequent write()s, giving us a truncated error message.

Signed-off-by: Jeff King <peff@peff.net>
---
 run-command.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/run-command.c b/run-command.c
index 8619c76..508a4c6 100644
--- a/run-command.c
+++ b/run-command.c
@@ -83,9 +83,9 @@ static NORETURN void die_child(const char *err, va_list params)
 	if (len > sizeof(msg))
 		len = sizeof(msg);
 
-	if (write(child_err, "fatal: ", 7) ||
-	    write(child_err, msg, len) ||
-	    write(child_err, "\n", 1))
+	if (write(child_err, "fatal: ", 7) < 0 ||
+	    write(child_err, msg, len) < 0 ||
+	    write(child_err, "\n", 1) < 0)
 		; /* yes, gcc -D_FORTIFY_SOURCE, we know there was an error. */
 	exit(128);
 }
-- 
1.7.5.rc2.3.g728b2
Previous: Jeff KingNext: Junio C Hamano
Message 3 of 20 in “[REGRESSION] git-wrapper to run-commands codepath regression”
  1. Junio C HamanoApr 18, 2011
  2. Jeff KingApr 18, 2011
  3. Jeff KingApr 18, 2011
  4. Junio C HamanoApr 18, 2011
  5. Jeff KingApr 18, 2011
  6. Junio C HamanoApr 18, 2011
  7. Andreas SchwabApr 18, 2011
  8. Junio C HamanoApr 18, 2011
  9. Jonathan NiederApr 18, 2011
  10. run-command: write full error message in die_childJonathan Nieder, Apr 19, 2011
  11. Johannes SixtApr 20, 2011
  12. 0/2 Re: run-command: write full error message in die_childJonathan Nieder, Apr 20, 2011
  13. 1/2 tests: check error message from run_commandJonathan Nieder, Apr 20, 2011
  14. 2/2 run-command: handle short writes and EINTR in die_childJonathan Nieder, Apr 20, 2011
  15. Junio C HamanoApr 19, 2011
  16. report which $PATH entry had trouble running execvp(3)Junio C Hamano, Apr 20, 2011
  17. Jeff KingApr 20, 2011
  18. Junio C HamanoApr 21, 2011
  19. Johannes SixtApr 20, 2011
  20. Jonathan NiederApr 20, 2011

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.