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

[PATCH v2] read-cache: fix index corruption with index v4

From
Thomas Gummerer <t.gummerer@gmail.com>
Date
Sep 7, 2017, 19:24 UTC
Message-ID
<20170907192412.8085-1-t.gummerer@gmail.com>
In-Reply-To
<CALgYhfNYgmCJqptNQLKaQpCs9mAgqZHUrDS3BVEqCv_f+WX-qg@mail.gmail.com>

ce012deb98 ("read-cache: avoid allocating every ondisk entry when writing", 2017-08-21) changed the way cache entries are written to the index file. While previously it wrote the name to an struct that was allocated using xcalloc(), it now uses ce_write() directly. Previously ce_namelen - common bytes were written to the cache entry, which would automatically make it nul terminated, as it was allocated using calloc.

Now we are writing ce_namelen - common + 1 bytes directly from the ce->name to the index. If CE_STRIP_NAME however gets set in the split index case ce->ce_namelen is set to 0 without changing the actual ce->name buffer. When index-v4, this results in the first character of ce->name being written out instead of just a terminating nul charcter.

As index-v4 requires the terminating nul character as terminator of the name when reading it back, this results in a corrupted index.

Fix that by only writing ce_namelen - common bytes directly from ce->name to the index, and adding the nul terminator in an extra call to ce_write.

This bug was turned up by setting TEST_GIT_INDEX_VERSION = 4 in config.mak and running the test suite (t1700 specifically broke).

Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
---
> Will send an updated patch in a bit.
In a bit was a lie, I didn't get to it anymore yesterday, but here it is :)
 read-cache.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/read-cache.c b/read-cache.c
index 40da87ea71..c6c69cf027 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -2103,7 +2103,9 @@ static int ce_write_entry(git_SHA_CTX *c, int fd, struct cache_entry *ce,
 		if (!result)
 			result = ce_write(c, fd, to_remove_vi, prefix_size);
 		if (!result)
-			result = ce_write(c, fd, ce->name + common, ce_namelen(ce) - common + 1);
+			result = ce_write(c, fd, ce->name + common, ce_namelen(ce) - common);
+		if (!result)
+			result = ce_write(c, fd, padding, 1);
 
 		strbuf_splice(previous_name, common, to_remove,
 			      ce->name + common, ce_namelen(ce) - common);
-- 
2.14.1.480.gb18f417b89
Previous: Thomas Gummerer
Message 4 of 4 in “read-cache: fix index corruption with index v4”
  1. read-cache: fix index corruption with index v4Thomas Gummerer, Sep 4, 2017
  2. Kevin WillfordSep 5, 2017
  3. Thomas GummererSep 6, 2017
  4. read-cache: fix index corruption with index v4Thomas Gummerer, Sep 7, 2017

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.