Skip to content

Commit e4e6808

Browse files
committed
Sync with 2.29.3
* maint-2.29: Git 2.29.3 Git 2.28.1 Git 2.27.1 Git 2.26.3 Git 2.25.5 Git 2.24.4 Git 2.23.4 Git 2.22.5 Git 2.21.4 Git 2.20.5 Git 2.19.6 Git 2.18.5 Git 2.17.6 unpack_trees(): start with a fresh lstat cache run-command: invalidate lstat cache after a command finished checkout: fix bug that makes checkout follow symlinks in leading path
2 parents 59ec224 + 0628636 commit e4e6808

22 files changed

+284
-4
lines changed

Documentation/RelNotes/2.17.6.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Git v2.17.6 Release Notes
2+
=========================
3+
4+
This release addresses the security issues CVE-2021-21300.
5+
6+
Fixes since v2.17.5
7+
-------------------
8+
9+
* CVE-2021-21300:
10+
On case-insensitive file systems with support for symbolic links,
11+
if Git is configured globally to apply delay-capable clean/smudge
12+
filters (such as Git LFS), Git could be fooled into running
13+
remote code during a clone.
14+
15+
Credit for finding and fixing this vulnerability goes to Matheus
16+
Tavares, helped by Johannes Schindelin.

Documentation/RelNotes/2.18.5.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Git v2.18.5 Release Notes
2+
=========================
3+
4+
This release merges up the fixes that appear in v2.17.6 to address
5+
the security issue CVE-2021-21300; see the release notes for that
6+
version for details.

Documentation/RelNotes/2.19.6.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Git v2.19.6 Release Notes
2+
=========================
3+
4+
This release merges up the fixes that appear in v2.17.6 and
5+
v2.18.5 to address the security issue CVE-2021-21300; see the
6+
release notes for these versions for details.

Documentation/RelNotes/2.20.5.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Git v2.20.5 Release Notes
2+
=========================
3+
4+
This release merges up the fixes that appear in v2.17.6, v2.18.5
5+
and v2.19.6 to address the security issue CVE-2021-21300; see
6+
the release notes for these versions for details.

Documentation/RelNotes/2.21.4.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Git v2.21.4 Release Notes
2+
=========================
3+
4+
This release merges up the fixes that appear in v2.17.6, v2.18.5,
5+
v2.19.6 and v2.20.5 to address the security issue CVE-2021-21300;
6+
see the release notes for these versions for details.

Documentation/RelNotes/2.22.5.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Git v2.22.5 Release Notes
2+
=========================
3+
4+
This release merges up the fixes that appear in v2.17.6,
5+
v2.18.5, v2.19.6, v2.20.5 and v2.21.4 to address the security
6+
issue CVE-2021-21300; see the release notes for these versions
7+
for details.

Documentation/RelNotes/2.23.4.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Git v2.23.4 Release Notes
2+
=========================
3+
4+
This release merges up the fixes that appear in v2.17.6, v2.18.5,
5+
v2.19.6, v2.20.5, v2.21.4 and v2.22.5 to address the security
6+
issue CVE-2021-21300; see the release notes for these versions
7+
for details.

Documentation/RelNotes/2.24.4.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Git v2.24.4 Release Notes
2+
=========================
3+
4+
This release merges up the fixes that appear in v2.17.6, v2.18.5,
5+
v2.19.6, v2.20.5, v2.21.4, v2.22.5 and v2.23.4 to address the
6+
security issue CVE-2021-21300; see the release notes for these
7+
versions for details.

Documentation/RelNotes/2.25.5.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Git v2.25.5 Release Notes
2+
=========================
3+
4+
This release merges up the fixes that appear in v2.17.6, v2.18.5,
5+
v2.19.6, v2.20.5, v2.21.4, v2.22.5, v2.23.4 and v2.24.4 to address
6+
the security issue CVE-2021-21300; see the release notes for
7+
these versions for details.

Documentation/RelNotes/2.26.3.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Git v2.26.3 Release Notes
2+
=========================
3+
4+
This release merges up the fixes that appear in v2.17.6, v2.18.5,
5+
v2.19.6, v2.20.5, v2.21.4, v2.22.5, v2.23.4, v2.24.4 and v2.25.5
6+
to address the security issue CVE-2021-21300; see the release
7+
notes for these versions for details.

Documentation/RelNotes/2.27.1.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Git v2.27.1 Release Notes
2+
=========================
3+
4+
This release merges up the fixes that appear in v2.17.6, v2.18.5,
5+
v2.19.6, v2.20.5, v2.21.4, v2.22.5, v2.23.4, v2.24.4, v2.25.5
6+
and v2.26.3 to address the security issue CVE-2021-21300; see
7+
the release notes for these versions for details.

Documentation/RelNotes/2.28.1.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Git v2.28.1 Release Notes
2+
=========================
3+
4+
This release merges up the fixes that appear in v2.17.6, v2.18.5,
5+
v2.19.6, v2.20.5, v2.21.4, v2.22.5, v2.23.4, v2.24.4, v2.25.5,
6+
v2.26.3 and v2.27.1 to address the security issue CVE-2021-21300;
7+
see the release notes for these versions for details.

Documentation/RelNotes/2.29.3.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Git v2.29.3 Release Notes
2+
=========================
3+
4+
This release merges up the fixes that appear in v2.17.6,
5+
v2.18.5, v2.19.6, v2.20.5, v2.21.4, v2.22.5, v2.23.4, v2.24.4,
6+
v2.25.5, v2.26.3, v2.27.1 and v2.28.1 to address the security
7+
issue CVE-2021-21300; see the release notes for these versions
8+
for details.

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,6 +1657,7 @@ int has_symlink_leading_path(const char *name, int len);
16571657
int threaded_has_symlink_leading_path(struct cache_def *, const char *, int);
16581658
int check_leading_path(const char *name, int len);
16591659
int has_dirs_only_path(const char *name, int len, int prefix_len);
1660+
void invalidate_lstat_cache(void);
16601661
void schedule_dir_for_removal(const char *name, int len);
16611662
void remove_scheduled_dirs(void);
16621663

compat/mingw.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,8 @@ int mingw_rmdir(const char *pathname)
367367
ask_yes_no_if_possible("Deletion of directory '%s' failed. "
368368
"Should I try again?", pathname))
369369
ret = _wrmdir(wpathname);
370+
if (!ret)
371+
invalidate_lstat_cache();
370372
return ret;
371373
}
372374

git-compat-util.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,11 @@ static inline int noop_core_config(const char *var, const char *value, void *cb)
349349
#define platform_core_config noop_core_config
350350
#endif
351351

352+
int lstat_cache_aware_rmdir(const char *path);
353+
#if !defined(__MINGW32__) && !defined(_MSC_VER)
354+
#define rmdir lstat_cache_aware_rmdir
355+
#endif
356+
352357
#ifndef has_dos_drive_prefix
353358
static inline int git_has_dos_drive_prefix(const char *path)
354359
{

run-command.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,7 @@ int finish_command(struct child_process *cmd)
990990
int ret = wait_or_whine(cmd->pid, cmd->argv[0], 0);
991991
trace2_child_exit(cmd, ret);
992992
child_process_clear(cmd);
993+
invalidate_lstat_cache();
993994
return ret;
994995
}
995996

@@ -1291,13 +1292,19 @@ int start_async(struct async *async)
12911292
int finish_async(struct async *async)
12921293
{
12931294
#ifdef NO_PTHREADS
1294-
return wait_or_whine(async->pid, "child process", 0);
1295+
int ret = wait_or_whine(async->pid, "child process", 0);
1296+
1297+
invalidate_lstat_cache();
1298+
1299+
return ret;
12951300
#else
12961301
void *ret = (void *)(intptr_t)(-1);
12971302

12981303
if (pthread_join(async->tid, &ret))
12991304
error("pthread_join failed");
1305+
invalidate_lstat_cache();
13001306
return (int)(intptr_t)ret;
1307+
13011308
#endif
13021309
}
13031310

symlinks.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,13 @@ int has_dirs_only_path(const char *name, int len, int prefix_len)
267267
*/
268268
static int threaded_has_dirs_only_path(struct cache_def *cache, const char *name, int len, int prefix_len)
269269
{
270+
/*
271+
* Note: this function is used by the checkout machinery, which also
272+
* takes care to properly reset the cache when it performs an operation
273+
* that would leave the cache outdated. If this function starts caching
274+
* anything else besides FL_DIR, remember to also invalidate the cache
275+
* when creating or deleting paths that might be in the cache.
276+
*/
270277
return lstat_cache(cache, name, len,
271278
FL_DIR|FL_FULLPATH, prefix_len) &
272279
FL_DIR;
@@ -321,3 +328,20 @@ void remove_scheduled_dirs(void)
321328
{
322329
do_remove_scheduled_dirs(0);
323330
}
331+
332+
void invalidate_lstat_cache(void)
333+
{
334+
reset_lstat_cache(&default_cache);
335+
}
336+
337+
#undef rmdir
338+
int lstat_cache_aware_rmdir(const char *path)
339+
{
340+
/* Any change in this function must be made also in `mingw_rmdir()` */
341+
int ret = rmdir(path);
342+
343+
if (!ret)
344+
invalidate_lstat_cache();
345+
346+
return ret;
347+
}

t/t0021-conversion.sh

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,4 +953,85 @@ test_expect_success PERL 'invalid file in delayed checkout' '
953953
grep "error: external filter .* signaled that .unfiltered. is now available although it has not been delayed earlier" git-stderr.log
954954
'
955955

956+
for mode in 'case' 'utf-8'
957+
do
958+
case "$mode" in
959+
case) dir='A' symlink='a' mode_prereq='CASE_INSENSITIVE_FS' ;;
960+
utf-8)
961+
dir=$(printf "\141\314\210") symlink=$(printf "\303\244")
962+
mode_prereq='UTF8_NFD_TO_NFC' ;;
963+
esac
964+
965+
test_expect_success PERL,SYMLINKS,$mode_prereq \
966+
"delayed checkout with $mode-collision don't write to the wrong place" '
967+
test_config_global filter.delay.process \
968+
"\"$TEST_ROOT/rot13-filter.pl\" --always-delay delayed.log clean smudge delay" &&
969+
test_config_global filter.delay.required true &&
970+
971+
git init $mode-collision &&
972+
(
973+
cd $mode-collision &&
974+
mkdir target-dir &&
975+
976+
empty_oid=$(printf "" | git hash-object -w --stdin) &&
977+
symlink_oid=$(printf "%s" "$PWD/target-dir" | git hash-object -w --stdin) &&
978+
attr_oid=$(echo "$dir/z filter=delay" | git hash-object -w --stdin) &&
979+
980+
cat >objs <<-EOF &&
981+
100644 blob $empty_oid $dir/x
982+
100644 blob $empty_oid $dir/y
983+
100644 blob $empty_oid $dir/z
984+
120000 blob $symlink_oid $symlink
985+
100644 blob $attr_oid .gitattributes
986+
EOF
987+
988+
git update-index --index-info <objs &&
989+
git commit -m "test commit"
990+
) &&
991+
992+
git clone $mode-collision $mode-collision-cloned &&
993+
# Make sure z was really delayed
994+
grep "IN: smudge $dir/z .* \\[DELAYED\\]" $mode-collision-cloned/delayed.log &&
995+
996+
# Should not create $dir/z at $symlink/z
997+
test_path_is_missing $mode-collision/target-dir/z
998+
'
999+
done
1000+
1001+
test_expect_success PERL,SYMLINKS,CASE_INSENSITIVE_FS \
1002+
"delayed checkout with submodule collision don't write to the wrong place" '
1003+
git init collision-with-submodule &&
1004+
(
1005+
cd collision-with-submodule &&
1006+
git config filter.delay.process "\"$TEST_ROOT/rot13-filter.pl\" --always-delay delayed.log clean smudge delay" &&
1007+
git config filter.delay.required true &&
1008+
1009+
# We need Git to treat the submodule "a" and the
1010+
# leading dir "A" as different paths in the index.
1011+
git config --local core.ignoreCase false &&
1012+
1013+
empty_oid=$(printf "" | git hash-object -w --stdin) &&
1014+
attr_oid=$(echo "A/B/y filter=delay" | git hash-object -w --stdin) &&
1015+
cat >objs <<-EOF &&
1016+
100644 blob $empty_oid A/B/x
1017+
100644 blob $empty_oid A/B/y
1018+
100644 blob $attr_oid .gitattributes
1019+
EOF
1020+
git update-index --index-info <objs &&
1021+
1022+
git init a &&
1023+
mkdir target-dir &&
1024+
symlink_oid=$(printf "%s" "$PWD/target-dir" | git -C a hash-object -w --stdin) &&
1025+
echo "120000 blob $symlink_oid b" >objs &&
1026+
git -C a update-index --index-info <objs &&
1027+
git -C a commit -m sub &&
1028+
git submodule add ./a &&
1029+
git commit -m super &&
1030+
1031+
git checkout --recurse-submodules . &&
1032+
grep "IN: smudge A/B/y .* \\[DELAYED\\]" delayed.log &&
1033+
test_path_is_missing target-dir/y
1034+
)
1035+
'
1036+
9561037
test_done

t/t0021/rot13-filter.pl

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@
22
# Example implementation for the Git filter protocol version 2
33
# See Documentation/gitattributes.txt, section "Filter Protocol"
44
#
5-
# The first argument defines a debug log file that the script write to.
6-
# All remaining arguments define a list of supported protocol
7-
# capabilities ("clean", "smudge", etc).
5+
# Usage: rot13-filter.pl [--always-delay] <log path> <capabilities>
6+
#
7+
# Log path defines a debug log file that the script writes to. The
8+
# subsequent arguments define a list of supported protocol capabilities
9+
# ("clean", "smudge", etc).
10+
#
11+
# When --always-delay is given all pathnames with the "can-delay" flag
12+
# that don't appear on the list bellow are delayed with a count of 1
13+
# (see more below).
814
#
915
# This implementation supports special test cases:
1016
# (1) If data with the pathname "clean-write-fail.r" is processed with
@@ -53,6 +59,13 @@ sub gitperllib {
5359
use Git::Packet;
5460

5561
my $MAX_PACKET_CONTENT_SIZE = 65516;
62+
63+
my $always_delay = 0;
64+
if ( $ARGV[0] eq '--always-delay' ) {
65+
$always_delay = 1;
66+
shift @ARGV;
67+
}
68+
5669
my $log_file = shift @ARGV;
5770
my @capabilities = @ARGV;
5871

@@ -134,6 +147,8 @@ sub rot13 {
134147
if ( $buffer eq "can-delay=1" ) {
135148
if ( exists $DELAY{$pathname} and $DELAY{$pathname}{"requested"} == 0 ) {
136149
$DELAY{$pathname}{"requested"} = 1;
150+
} elsif ( !exists $DELAY{$pathname} and $always_delay ) {
151+
$DELAY{$pathname} = { "requested" => 1, "count" => 1 };
137152
}
138153
} elsif ($buffer =~ /^(ref|treeish|blob)=/) {
139154
print $debug " $buffer";

t/t2006-checkout-index-basic.sh

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,50 @@ test_expect_success 'checkout-index reports errors (stdin)' '
3131
test_must_fail git checkout-index --stdin 2>stderr &&
3232
test_i18ngrep not.in.the.cache stderr
3333
'
34+
for mode in 'case' 'utf-8'
35+
do
36+
case "$mode" in
37+
case) dir='A' symlink='a' mode_prereq='CASE_INSENSITIVE_FS' ;;
38+
utf-8)
39+
dir=$(printf "\141\314\210") symlink=$(printf "\303\244")
40+
mode_prereq='UTF8_NFD_TO_NFC' ;;
41+
esac
42+
43+
test_expect_success SYMLINKS,$mode_prereq \
44+
"checkout-index with $mode-collision don't write to the wrong place" '
45+
git init $mode-collision &&
46+
(
47+
cd $mode-collision &&
48+
mkdir target-dir &&
49+
50+
empty_obj_hex=$(git hash-object -w --stdin </dev/null) &&
51+
symlink_hex=$(printf "%s" "$PWD/target-dir" | git hash-object -w --stdin) &&
52+
53+
cat >objs <<-EOF &&
54+
100644 blob ${empty_obj_hex} ${dir}/x
55+
100644 blob ${empty_obj_hex} ${dir}/y
56+
100644 blob ${empty_obj_hex} ${dir}/z
57+
120000 blob ${symlink_hex} ${symlink}
58+
EOF
59+
60+
git update-index --index-info <objs &&
61+
62+
# Note: the order is important here to exercise the
63+
# case where the file at ${dir} has its type changed by
64+
# the time Git tries to check out ${dir}/z.
65+
#
66+
# Also, we use core.precomposeUnicode=false because we
67+
# want Git to treat the UTF-8 paths transparently on
68+
# Mac OS, matching what is in the index.
69+
#
70+
git -c core.precomposeUnicode=false checkout-index -f \
71+
${dir}/x ${dir}/y ${symlink} ${dir}/z &&
72+
73+
# Should not create ${dir}/z at ${symlink}/z
74+
test_path_is_missing target-dir/z
75+
76+
)
77+
'
78+
done
3479

3580
test_done

unpack-trees.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,9 @@ static int check_updates(struct unpack_trees_options *o,
417417

418418
progress = get_progress(o, index);
419419

420+
/* Start with clean cache to avoid using any possibly outdated info. */
421+
invalidate_lstat_cache();
422+
420423
git_attr_set_direction(GIT_ATTR_CHECKOUT);
421424

422425
if (should_update_submodules())

0 commit comments

Comments
 (0)