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

Re: [PATCH] fast-import: disallow more path components

From
Jeff King <peff@peff.net>
Date
Nov 28, 2024, 16:12 UTC
Message-ID
<20241128161232.GA11476@coredump.intra.peff.net>
In-Reply-To
<pull.1832.git.1732740464398.gitgitgadget@gmail.com>
On Wed, Nov 27, 2024 at 08:47:44PM +0000, Elijah Newren via GitGitGadget wrote:
Show 10 quoted lines
> Instead of just disallowing '.' and '..', make use of verify_path() to
> ensure that fast-import will disallow anything we wouldn't allow into
> the index, such as anything under .git/, .gitmodules as a symlink, or
> a dos drive prefix on Windows.
> 
> Since a few fast-export and fast-import tests that tried to stress-test
> the correct handling of quoting relied on filenames that fail
> is_valid_win32_path(), such as spaces or periods at the end of filenames
> or backslashes within the filename, turn off core.protectNTFS for those
> tests to ensure they keep passing.

Great, thanks for following up on this. I think it will work as advertised, though...

Show 6 quoted lines
> @@ -1413,6 +1414,8 @@ static int tree_content_set(
>  		die("Empty path component found in input");
>  	if (!*slash1 && !S_ISDIR(mode) && subtree)
>  		die("Non-directories cannot have subtrees");
> +	if (!verify_path(p, mode))
> +		die("invalid path '%s'", p);

This spot is over-verifying, I think, because it's recursive. Given the path foo/bar/baz, it will see "foo/bar/baz", then "bar/baz", then "baz". But just the first one should be sufficient to feed to verify_path().

I'd have expected the check when we parse the path in file_change_m(). That would also require touching other callers, too. One option would be to put a non-recursive wrapper around tree_content_set(), and add the check there.

But looking at those other callers, I think it's really just file_change_cr() that maters. The other call in do_change_note_fanout() is using a notes path that we've constructed ourselves (so it's not wrong to check, but probably pointless).

The patch below passes your tests (though perhaps it would be worth adding an explicit check of a copy/rename). Is it worth worrying about the efficiency of the extra calls? I'm not sure, and I didn't measure. But this just seems less surprising to me overall.

(Both your patch and what I've shown below do not verify deletions from the tree, but I think that's fine; such a name would not exist in the tree in the first place).

-Peff
---
diff --git a/builtin/fast-import.c b/builtin/fast-import.c
index bb4b769c7c..265d1b7d52 100644
--- a/builtin/fast-import.c
+++ b/builtin/fast-import.c
@@ -1414,8 +1414,6 @@ static int tree_content_set(
 		die("Empty path component found in input");
 	if (!*slash1 && !S_ISDIR(mode) && subtree)
 		die("Non-directories cannot have subtrees");
-	if (!verify_path(p, mode))
-		die("invalid path '%s'", p);
 
 	if (!root->tree)
 		load_tree(root);
@@ -2417,6 +2415,9 @@ static void file_change_m(const char *p, struct branch *b)
 		tree_content_replace(&b->branch_tree, &oid, mode, NULL);
 		return;
 	}
+
+	if (!verify_path(path.buf, mode))
+		die("invalid path '%s'", path.buf);
 	tree_content_set(&b->branch_tree, path.buf, &oid, mode, NULL);
 }
 
@@ -2454,6 +2455,8 @@ static void file_change_cr(const char *p, struct branch *b, int rename)
 			leaf.tree);
 		return;
 	}
+	if (!verify_path(dest.buf, leaf.versions[1].mode))
+		die("invalid path '%s'", dest.buf);
 	tree_content_set(&b->branch_tree, dest.buf,
 		&leaf.versions[1].oid,
 		leaf.versions[1].mode,
Previous: Junio C HamanoNext: Elijah Newren via GitGitGadget
Message 3 of 11 in “fast-import: disallow more path components”
  1. fast-import: disallow more path componentsElijah Newren via GitGitGadget, Nov 27, 2024
  2. Junio C HamanoNov 28, 2024
  3. Jeff KingNov 28, 2024
  4. fast-import: disallow more path componentsElijah Newren via GitGitGadget, Nov 30, 2024
  5. Jeff KingDec 1, 2024
  6. Elijah NewrenDec 3, 2024
  7. 2/1 t9300: test verification of renamed pathsJeff King, Dec 3, 2024
  8. Elijah NewrenDec 3, 2024
  9. Junio C HamanoDec 4, 2024
  10. Junio C HamanoDec 3, 2024
  11. Junio C HamanoDec 2, 2024

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.