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

[PATCH] Make object creation in http fetch a bit safer.

From
Junio C Hamano <junkio@cox.net>
Date
Sep 21, 2005, 09:55 UTC
Message-ID
<7vd5n2ycbe.fsf@assigned-by-dhcp.cox.net>

Unlike write_sha1_file() that tries to create the object file in a temporary location and then move it to the final location, fetch_object could have been interrupted in the middle, leaving a corrupt file.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 I think the packfile side is safer -- the index is verified
 with the call to parse_pack_index() which eventually calls
 check_packed_git_idx() to validate it, and the pack file is
 checked when it is first used, just like any pack file we
 originally had.  Ideally, we should validate the pair after
 downloading with git-verify-pack, though.
 http-fetch.c |   29 ++++++++++++++++++++++++-----
 1 files changed, 24 insertions(+), 5 deletions(-)
09d920831edba17fe983269a9d0d85e592dd4bb3
diff --git a/http-fetch.c b/http-fetch.c
--- a/http-fetch.c
+++ b/http-fetch.c
@@ -350,13 +350,18 @@ int fetch_object(struct alt_base *repo, 
 	char *hex = sha1_to_hex(sha1);
 	char *filename = sha1_file_name(sha1);
 	unsigned char real_sha1[20];
+	char tmpfile[PATH_MAX];
+	int ret;
 	char *url;
 	char *posn;
 
-	local = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
+	snprintf(tmpfile, sizeof(tmpfile), "%s/obj_XXXXXX",
+		 get_object_directory());
 
+	local = mkstemp(tmpfile);
 	if (local < 0)
-		return error("Couldn't open local object %s\n", filename);
+		return error("Couldn't create temporary file %s for %s: %s\n",
+			     tmpfile, filename, strerror(errno));
 
 	memset(&stream, 0, sizeof(stream));
 
@@ -386,18 +391,32 @@ int fetch_object(struct alt_base *repo, 
 		return -1;
 	}
 
+	fchmod(local, 0444);
 	close(local);
 	inflateEnd(&stream);
 	SHA1_Final(real_sha1, &c);
 	if (zret != Z_STREAM_END) {
-		unlink(filename);
+		unlink(tmpfile);
 		return error("File %s (%s) corrupt\n", hex, url);
 	}
 	if (memcmp(sha1, real_sha1, 20)) {
-		unlink(filename);
+		unlink(tmpfile);
 		return error("File %s has bad hash\n", hex);
 	}
-	
+	ret = link(tmpfile, filename);
+	if (ret < 0) {
+		/* Same Coda hack as in write_sha1_file(sha1_file.c) */
+		ret = errno;
+		if (ret == EXDEV && !rename(tmpfile, filename))
+			goto out;
+	}
+	unlink(tmpfile);
+	if (ret) {
+		if (ret != EEXIST)
+			return error("unable to write sha1 filename %s: %s",
+				     filename, strerror(ret));
+	}
+ out:
 	pull_say("got %s\n", hex);
 	return 0;
 }
Next: Daniel Barkalow
Message 1 of 2 in “Make object creation in http fetch a bit safer.”
  1. Make object creation in http fetch a bit safer.Junio C Hamano, Sep 21, 2005
  2. Daniel BarkalowSep 21, 2005

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.