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

[PATCH] git-apply: Do not free the wrong buffer when we convert the data for writeout

From
Junio C Hamano <junkio@cox.net>
Date
Mar 22, 2007, 20:31 UTC
Message-ID
<7virctt3yi.fsf_-_@assigned-by-dhcp.cox.net>
In-Reply-To
<Pine.LNX.4.64.0703220931120.6730@woody.linux-foundation.org>

When we write out the result of patch application, we sometimes need to munge the data (e.g. under core.autocrlf). After doing so, what we should free is the temporary buffer that holds the converted data returned from convert_to_working_tree(), not the original one.

This patch also moves the call to open() up in the function, as the caller expects us to fail cheaply if leading directories need to be created (and then the caller creates them and calls us again). For that calling pattern, attempting conversion before opening the file adds unnecessary overhead.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
  Linus Torvalds <torvalds@linux-foundation.org> writes:
  > In "try_create_file()", we do:
  >
  > 	...
  >         if (convert_to_working_tree(path, &nbuf, &nsize)) {
  >                 free((char *) buf);
  >                 buf = nbuf;
  >                 size = nsize;
  >         }
  > 	...
  >
  > but the thing is, the *caller* still uses the old "buf/nsize", so when you 
  > free it, the caller will now use the free'd data structure, and if it gets 
  > re-used by - for example - the zlib deflate() buffers, you'll get a 
  > corrupt object (if it gets re-used *before*, you'll get the *wrong* 
  > object!). Exactly Alexander's patterns.
  >
  > Alexander - sorry for all the trouble, this was definitely our bad.
  I concur.  Sorry for this, Alexander.
  git-apply in general is quite leaky (e.g. it never frees a
  finished patch, and freeing a patch is quite difficult as some
  strings like filenames are shared without refcounting), but
  this part deals with a large amount of data and I would rather
  not add a new one.
 builtin-apply.c |   17 ++++++++++-------
 1 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/builtin-apply.c b/builtin-apply.c
index dfa1716..27a182b 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -2355,7 +2355,7 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned
 
 static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size)
 {
-	int fd;
+	int fd, converted;
 	char *nbuf;
 	unsigned long nsize;
 
@@ -2364,17 +2364,18 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
 		 * terminated.
 		 */
 		return symlink(buf, path);
+
+	fd = open(path, O_CREAT | O_EXCL | O_WRONLY, (mode & 0100) ? 0777 : 0666);
+	if (fd < 0)
+		return -1;
+
 	nsize = size;
 	nbuf = (char *) buf;
-	if (convert_to_working_tree(path, &nbuf, &nsize)) {
-		free((char *) buf);
+	converted = convert_to_working_tree(path, &nbuf, &nsize);
+	if (converted) {
 		buf = nbuf;
 		size = nsize;
 	}
-
-	fd = open(path, O_CREAT | O_EXCL | O_WRONLY, (mode & 0100) ? 0777 : 0666);
-	if (fd < 0)
-		return -1;
 	while (size) {
 		int written = xwrite(fd, buf, size);
 		if (written < 0)
@@ -2386,6 +2387,8 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
 	}
 	if (close(fd) < 0)
 		die("closing file %s: %s", path, strerror(errno));
+	if (converted)
+		free(nbuf);
 	return 0;
 }
 
Previous: Jeff KingNext: Linus Torvalds
Message 24 of 28 in “My git repo is broken, how to fix it ?”
  1. Alexander LitvinovFeb 28, 2007
  2. Linus TorvaldsFeb 28, 2007
  3. Alexander LitvinovFeb 28, 2007
  4. Linus TorvaldsFeb 28, 2007
  5. Alex RiesenFeb 28, 2007
  6. Alexander LitvinovMar 19, 2007
  7. Linus TorvaldsMar 19, 2007
  8. Linus TorvaldsMar 20, 2007
  9. Alexander LitvinovMar 20, 2007
  10. Junio C HamanoMar 20, 2007
  11. Nicolas PitreMar 20, 2007
  12. Linus TorvaldsMar 22, 2007
  13. Nicolas PitreMar 22, 2007
  14. Linus TorvaldsMar 22, 2007
  15. Linus TorvaldsMar 22, 2007
  16. Linus TorvaldsMar 22, 2007
  17. Nicolas PitreMar 22, 2007
  18. Linus TorvaldsMar 22, 2007
  19. Nicolas PitreMar 22, 2007
  20. Jeff KingMar 22, 2007
  21. Linus TorvaldsMar 23, 2007
  22. Bill LearMar 23, 2007
  23. Jeff KingMar 23, 2007
  24. git-apply: Do not free the wrong buffer when we convert the data for writeoutJunio C Hamano, Mar 22, 2007
  25. Linus TorvaldsMar 22, 2007
  26. Alexander LitvinovMar 23, 2007
  27. Alexander LitvinovMar 23, 2007
  28. Johannes SixtMar 22, 2007

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.