Subject: Re: [PATCH 6/7] verify_path(): disallow symlinks in .gitattributes and .gitignore

From: Jonathan Nieder <[email-masked]>
Date: Mon, 5 Oct 2020 01:09:30 -0700

Jeff King wrote:

> However, it's still a reasonable idea to forbid symlinks for these
> files:
>
>   - As noted, they can still be used to read out-of-repo files (which is
>     fairly restricted, but in some circumstances you can probe file
>     content by speculatively creating files and seeing if they get
>     ignored)
>
>   - They don't currently behave well in all cases. We sometimes read
>     these files from the index, where we _don't_ follow symlinks (we'd
>     just treat the symlink target as the .gitignore or .gitattributes
>     content, which is actively wrong).
>
> This patch forbids symlinked versions of these files from entering the
> index. We already have helpers for obscured forms of the names from
> e7cb0b4455 (is_ntfs_dotgit: match other .git files, 2018-05-11) and
> 0fc333ba20 (is_hfs_dotgit: match other .git files, 2018-05-02), which
> were done as part of the series touching .gitmodules.
>
> Signed-off-by: Jeff King <[email-masked]>
> ---
> I note that neither these new tests nor the existing .gitmodules ones
> confirm that we catch the obscured ntfs/hfs forms in the actual code
> paths (instead, we feed them to a synthetic test-tool helper in t0060).
> I think that's OK, but if we wanted to be super-paranoid we could beef
> up these tests with trickier names.

I think being exhaustive wouldn't be worth it, but perhaps *one*
example (e.g., ".gitmodules ") would not be a terrible idea.

>  read-cache.c              | 12 +++++++++---
>  t/t7450-bad-meta-files.sh | 29 +++++++++++++++++++++++++++++
>  2 files changed, 38 insertions(+), 3 deletions(-)

Reviewed-by: Jonathan Nieder <[email-masked]>

[...]
> --- a/t/t7450-bad-meta-files.sh
> +++ b/t/t7450-bad-meta-files.sh
> @@ -267,4 +267,33 @@ test_expect_success 'git dirs of sibling submodules must not be nested' '
>  	test_i18ngrep "is inside git dir" err
>  '
>  
> +test_expect_success 'create repo with symlinked .gitattributes file' '
> +	git init symlink-attr &&
> +	target=$(echo target | git -C symlink-attr hash-object -w --stdin) &&
> +	tree=$(
> +		printf "120000 blob $target\t.gitattributes\n" |
> +		git -C symlink-attr mktree
> +	)
> +'
> +
> +test_expect_success 'refuse to load symlinked .gitattributes into index' '
> +	test_must_fail git -C symlink-attr read-tree $tree 2>err &&
> +	test_i18ngrep "invalid path.*gitattributes" err

This tests that it fails but doesn't test that it had no effect.
Would that be straightforward to check as well (e.g. an "ls-files -s"
before and after)?