Compare commits
6 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e50591a09 | ||
|
|
a958e0ad2a | ||
|
|
f7391883e6 | ||
|
|
b1b17a63f3 | ||
|
|
663c11a548 | ||
|
|
5a8bcd3824 |
7 changed files with 865 additions and 8 deletions
|
|
@ -0,0 +1,33 @@
|
|||
From 45eb1ba86022558d71a9946ccbe173ba5d8f1e37 Mon Sep 17 00:00:00 2001
|
||||
From: Petr Stodulka <pstodulk@redhat.com>
|
||||
Date: Thu, 13 Oct 2016 13:23:47 +0200
|
||||
Subject: [PATCH 1/2] Add test for ls-tree with broken symlink under refs/heads
|
||||
|
||||
git ls-tree goes into an infinite loop while serving pretty vanilla requests,
|
||||
if the refs/heads/ directory contains a symlink that's broken. Added test
|
||||
which check if git ends with expected exit code or timeout expires.
|
||||
---
|
||||
t/t3103-ls-tree-misc.sh | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/t/t3103-ls-tree-misc.sh b/t/t3103-ls-tree-misc.sh
|
||||
index 09dcf04..faf79c4 100755
|
||||
--- a/t/t3103-ls-tree-misc.sh
|
||||
+++ b/t/t3103-ls-tree-misc.sh
|
||||
@@ -21,4 +21,13 @@ test_expect_success 'ls-tree fails with non-zero exit code on broken tree' '
|
||||
test_must_fail git ls-tree -r HEAD
|
||||
'
|
||||
|
||||
+test_expect_success 'ls-tree fails due to broken symlink instead of infinite loop' '
|
||||
+ mkdir foo_infinit &&
|
||||
+ cd foo_infinit &&
|
||||
+ git init testrepo &&
|
||||
+ cd testrepo &&
|
||||
+ mkdir -p .git/refs/remotes &&
|
||||
+ ln -s ../remotes/foo .git/refs/heads/bar &&
|
||||
+ test_expect_code 128 timeout 2 git ls-tree bar
|
||||
+'
|
||||
test_done
|
||||
--
|
||||
2.5.5
|
||||
|
||||
63
0001-blame-fix-segfault-on-untracked-files.patch
Normal file
63
0001-blame-fix-segfault-on-untracked-files.patch
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
From bc6b13a7d2300e982dd3a3aeef2f3ad4d39cf149 Mon Sep 17 00:00:00 2001
|
||||
From: Thomas Gummerer <t.gummerer@gmail.com>
|
||||
Date: Sat, 27 Aug 2016 21:01:50 +0100
|
||||
Subject: [PATCH] blame: fix segfault on untracked files
|
||||
|
||||
Since 3b75ee9 ("blame: allow to blame paths freshly added to the index",
|
||||
2016-07-16) git blame also looks at the index to determine if there is a
|
||||
file that was freshly added to the index.
|
||||
|
||||
cache_name_pos returns -pos - 1 in case there is no match is found, or
|
||||
if the name matches, but the entry has a stage other than 0. As git
|
||||
blame should work for unmerged files, it uses strcmp to determine
|
||||
whether the name of the returned position matches, in which case the
|
||||
file exists, but is merely unmerged, or if the file actually doesn't
|
||||
exist in the index.
|
||||
|
||||
If the repository is empty, or if the file would lexicographically be
|
||||
sorted as the last file in the repository, -cache_name_pos - 1 is
|
||||
outside of the length of the active_cache array, causing git blame to
|
||||
segfault. Guard against that, and die() normally to restore the old
|
||||
behaviour.
|
||||
|
||||
Reported-by: Simon Ruderich <simon@ruderich.org>
|
||||
Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
|
||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
||||
---
|
||||
builtin/blame.c | 3 ++-
|
||||
t/t8002-blame.sh | 5 +++++
|
||||
2 files changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/builtin/blame.c b/builtin/blame.c
|
||||
index 12c765acfe..4d52f9602e 100644
|
||||
--- a/builtin/blame.c
|
||||
+++ b/builtin/blame.c
|
||||
@@ -2245,7 +2245,8 @@ static void verify_working_tree_path(struct commit *work_tree, const char *path)
|
||||
pos = cache_name_pos(path, strlen(path));
|
||||
if (pos >= 0)
|
||||
; /* path is in the index */
|
||||
- else if (!strcmp(active_cache[-1 - pos]->name, path))
|
||||
+ else if (-1 - pos < active_nr &&
|
||||
+ !strcmp(active_cache[-1 - pos]->name, path))
|
||||
; /* path is in the index, unmerged */
|
||||
else
|
||||
die("no such path '%s' in HEAD", path);
|
||||
diff --git a/t/t8002-blame.sh b/t/t8002-blame.sh
|
||||
index ff09aced68..ab79de9544 100755
|
||||
--- a/t/t8002-blame.sh
|
||||
+++ b/t/t8002-blame.sh
|
||||
@@ -6,6 +6,11 @@ test_description='git blame'
|
||||
PROG='git blame -c'
|
||||
. "$TEST_DIRECTORY"/annotate-tests.sh
|
||||
|
||||
+test_expect_success 'blame untracked file in empty repo' '
|
||||
+ >untracked &&
|
||||
+ test_must_fail git blame untracked
|
||||
+'
|
||||
+
|
||||
PROG='git blame -c -e'
|
||||
test_expect_success 'blame --show-email' '
|
||||
check_count \
|
||||
--
|
||||
2.11.0
|
||||
|
||||
129
0001-revision-quit-pruning-diff-more-quickly-when-possibl.patch
Normal file
129
0001-revision-quit-pruning-diff-more-quickly-when-possibl.patch
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
From 0523d90a901e5cb6116e725f02c7f80a444405b6 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff King <peff@peff.net>
|
||||
Date: Fri, 13 Oct 2017 11:27:45 -0400
|
||||
Subject: [PATCH] revision: quit pruning diff more quickly when possible
|
||||
|
||||
When the revision traversal machinery is given a pathspec,
|
||||
we must compute the parent-diff for each commit to determine
|
||||
which ones are TREESAME. We set the QUICK diff flag to avoid
|
||||
looking at more entries than we need; we really just care
|
||||
whether there are any changes at all.
|
||||
|
||||
But there is one case where we want to know a bit more: if
|
||||
--remove-empty is set, we care about finding cases where the
|
||||
change consists only of added entries (in which case we may
|
||||
prune the parent in try_to_simplify_commit()). To cover that
|
||||
case, our file_add_remove() callback does not quit the diff
|
||||
upon seeing an added entry; it keeps looking for other types
|
||||
of entries.
|
||||
|
||||
But this means when --remove-empty is not set (and it is not
|
||||
by default), we compute more of the diff than is necessary.
|
||||
You can see this in a pathological case where a commit adds
|
||||
a very large number of entries, and we limit based on a
|
||||
broad pathspec. E.g.:
|
||||
|
||||
perl -e '
|
||||
chomp(my $blob = `git hash-object -w --stdin </dev/null`);
|
||||
for my $a (1..1000) {
|
||||
for my $b (1..1000) {
|
||||
print "100644 $blob\t$a/$b\n";
|
||||
}
|
||||
}
|
||||
' | git update-index --index-info
|
||||
git commit -qm add
|
||||
|
||||
git rev-list HEAD -- .
|
||||
|
||||
This case takes about 100ms now, but after this patch only
|
||||
needs 6ms. That's not a huge improvement, but it's easy to
|
||||
get and it protects us against even more pathological cases
|
||||
(e.g., going from 1 million to 10 million files would take
|
||||
ten times as long with the current code, but not increase at
|
||||
all after this patch).
|
||||
|
||||
This is reported to minorly speed-up pathspec limiting in
|
||||
real world repositories (like the 100-million-file Windows
|
||||
repository), but probably won't make a noticeable difference
|
||||
outside of pathological setups.
|
||||
|
||||
This patch actually covers the case without --remove-empty,
|
||||
and the case where we see only deletions. See the in-code
|
||||
comment for details.
|
||||
|
||||
Note that we have to add a new member to the diff_options
|
||||
struct so that our callback can see the value of
|
||||
revs->remove_empty_trees. This callback parameter could be
|
||||
passed to the "add_remove" and "change" callbacks, but
|
||||
there's not much point. They already receive the
|
||||
diff_options struct, and doing it this way avoids having to
|
||||
update the function signature of the other callbacks
|
||||
(arguably the format_callback and output_prefix functions
|
||||
could benefit from the same simplification).
|
||||
|
||||
Signed-off-by: Jeff King <peff@peff.net>
|
||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
||||
(cherry picked from commit a937b37e766479c8e780b17cce9c4b252fd97e40)
|
||||
---
|
||||
diff.h | 1 +
|
||||
revision.c | 16 +++++++++++++---
|
||||
2 files changed, 14 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/diff.h b/diff.h
|
||||
index 125447be09..e37d93ec0a 100644
|
||||
--- a/diff.h
|
||||
+++ b/diff.h
|
||||
@@ -171,6 +171,7 @@ struct diff_options {
|
||||
pathchange_fn_t pathchange;
|
||||
change_fn_t change;
|
||||
add_remove_fn_t add_remove;
|
||||
+ void *change_fn_data;
|
||||
diff_format_fn_t format_callback;
|
||||
void *format_callback_data;
|
||||
diff_prefix_fn_t output_prefix;
|
||||
diff --git a/revision.c b/revision.c
|
||||
index fe0f3a4f41..361ae5eb16 100644
|
||||
--- a/revision.c
|
||||
+++ b/revision.c
|
||||
@@ -394,8 +394,16 @@ static struct commit *one_relevant_parent(const struct rev_info *revs,
|
||||
* if the whole diff is removal of old data, and otherwise
|
||||
* REV_TREE_DIFFERENT (of course if the trees are the same we
|
||||
* want REV_TREE_SAME).
|
||||
- * That means that once we get to REV_TREE_DIFFERENT, we do not
|
||||
- * have to look any further.
|
||||
+ *
|
||||
+ * The only time we care about the distinction is when
|
||||
+ * remove_empty_trees is in effect, in which case we care only about
|
||||
+ * whether the whole change is REV_TREE_NEW, or if there's another type
|
||||
+ * of change. Which means we can stop the diff early in either of these
|
||||
+ * cases:
|
||||
+ *
|
||||
+ * 1. We're not using remove_empty_trees at all.
|
||||
+ *
|
||||
+ * 2. We saw anything except REV_TREE_NEW.
|
||||
*/
|
||||
static int tree_difference = REV_TREE_SAME;
|
||||
|
||||
@@ -406,9 +414,10 @@ static void file_add_remove(struct diff_options *options,
|
||||
const char *fullpath, unsigned dirty_submodule)
|
||||
{
|
||||
int diff = addremove == '+' ? REV_TREE_NEW : REV_TREE_OLD;
|
||||
+ struct rev_info *revs = options->change_fn_data;
|
||||
|
||||
tree_difference |= diff;
|
||||
- if (tree_difference == REV_TREE_DIFFERENT)
|
||||
+ if (!revs->remove_empty_trees || tree_difference != REV_TREE_NEW)
|
||||
DIFF_OPT_SET(options, HAS_CHANGES);
|
||||
}
|
||||
|
||||
@@ -1348,6 +1357,7 @@ void init_revisions(struct rev_info *revs, const char *prefix)
|
||||
DIFF_OPT_SET(&revs->pruning, QUICK);
|
||||
revs->pruning.add_remove = file_add_remove;
|
||||
revs->pruning.change = file_change;
|
||||
+ revs->pruning.change_fn_data = revs;
|
||||
revs->sort_order = REV_SORT_IN_GRAPH_ORDER;
|
||||
revs->dense = 1;
|
||||
revs->prefix = prefix;
|
||||
--
|
||||
2.15.0
|
||||
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
From 5bc590cd3ce202243cd1c3ee22104bcb4f3b6c4e Mon Sep 17 00:00:00 2001
|
||||
From: Michael Haggerty <mhagger@alum.mit.edu>
|
||||
Date: Wed, 25 Mar 2015 22:33:11 +0100
|
||||
Subject: [PATCH 2/2] resolve_ref_unsafe(): limit the number of "stat_ref"
|
||||
retries
|
||||
|
||||
If there is a broken symlink where a loose reference file is expected,
|
||||
then the attempt to open() it fails with ENOENT. This error is
|
||||
misinterpreted to mean that the loose reference file itself has
|
||||
disappeared due to a race, causing the lookup to be retried. But in
|
||||
this scenario, the retries all suffer from the same problem, causing
|
||||
an infinite loop.
|
||||
|
||||
So put a limit (of 5) on the number of times that the stat_ref step
|
||||
can be retried.
|
||||
|
||||
Based-on-patch-by: Petr Stodulka <pstodulk@redhat.com>
|
||||
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
|
||||
---
|
||||
refs/files-backend.c | 6 ++++--
|
||||
refs/refs-internal.h | 6 ++++++
|
||||
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/refs/files-backend.c b/refs/files-backend.c
|
||||
index d16feb1..245a0b5 100644
|
||||
--- a/refs/files-backend.c
|
||||
+++ b/refs/files-backend.c
|
||||
@@ -1353,6 +1353,7 @@ static int files_read_raw_ref(struct ref_store *ref_store,
|
||||
int fd;
|
||||
int ret = -1;
|
||||
int save_errno;
|
||||
+ int retries = 0;
|
||||
|
||||
strbuf_reset(&sb_path);
|
||||
strbuf_git_path(&sb_path, "%s", refname);
|
||||
@@ -1390,7 +1391,8 @@ static int files_read_raw_ref(struct ref_store *ref_store,
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
strbuf_reset(&sb_contents);
|
||||
if (strbuf_readlink(&sb_contents, path, 0) < 0) {
|
||||
- if (errno == ENOENT || errno == EINVAL)
|
||||
+ if ((errno == ENOENT || errno == EINVAL) &&
|
||||
+ retries++ < MAXRETRIES)
|
||||
/* inconsistent with lstat; retry */
|
||||
goto stat_ref;
|
||||
else
|
||||
@@ -1426,7 +1428,7 @@ static int files_read_raw_ref(struct ref_store *ref_store,
|
||||
*/
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
- if (errno == ENOENT)
|
||||
+ if (errno == ENOENT && retries++ < MAXRETRIES)
|
||||
/* inconsistent with lstat; retry */
|
||||
goto stat_ref;
|
||||
else
|
||||
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
|
||||
index 708b260..37e6b99 100644
|
||||
--- a/refs/refs-internal.h
|
||||
+++ b/refs/refs-internal.h
|
||||
@@ -255,6 +255,12 @@ int rename_ref_available(const char *old_refname, const char *new_refname);
|
||||
/* We allow "recursive" symbolic refs. Only within reason, though */
|
||||
#define SYMREF_MAXDEPTH 5
|
||||
|
||||
+/*
|
||||
+ * We allow only MAXRETRIES tries to jump on stat_ref, because of possible
|
||||
+ * infinite loop
|
||||
+ */
|
||||
+#define MAXRETRIES 5
|
||||
+
|
||||
/* Include broken references in a do_for_each_ref*() iteration: */
|
||||
#define DO_FOR_EACH_INCLUDE_BROKEN 0x01
|
||||
|
||||
--
|
||||
2.5.5
|
||||
|
||||
518
git-2.9.5-git-shell-and-cvsserver-hardening.patch
Normal file
518
git-2.9.5-git-shell-and-cvsserver-hardening.patch
Normal file
|
|
@ -0,0 +1,518 @@
|
|||
From 9a1c497f7f3fbbd21673a6023871b891a6225ebe Mon Sep 17 00:00:00 2001
|
||||
From: Junio C Hamano <gitster@pobox.com>
|
||||
Date: Mon, 11 Sep 2017 14:44:24 +0900
|
||||
Subject: [PATCH 1/6] cvsserver: move safe_pipe_capture() to the main package
|
||||
|
||||
As a preparation for replacing `command` with a call to this
|
||||
function from outside GITCVS::updater package, move it to the main
|
||||
package.
|
||||
|
||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
||||
(cherry picked from commit fce13af5d20cad8dcb2d0e47bcf01b6960f08e55)
|
||||
---
|
||||
git-cvsserver.perl | 47 ++++++++++++++++++++++-------------------------
|
||||
1 file changed, 22 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/git-cvsserver.perl b/git-cvsserver.perl
|
||||
index d50c85ed7b..8229d9d198 100755
|
||||
--- a/git-cvsserver.perl
|
||||
+++ b/git-cvsserver.perl
|
||||
@@ -3406,6 +3406,22 @@ sub refHashEqual
|
||||
return $out;
|
||||
}
|
||||
|
||||
+# an alternative to `command` that allows input to be passed as an array
|
||||
+# to work around shell problems with weird characters in arguments
|
||||
+
|
||||
+sub safe_pipe_capture {
|
||||
+
|
||||
+ my @output;
|
||||
+
|
||||
+ if (my $pid = open my $child, '-|') {
|
||||
+ @output = (<$child>);
|
||||
+ close $child or die join(' ',@_).": $! $?";
|
||||
+ } else {
|
||||
+ exec(@_) or die "$! $?"; # exec() can fail the executable can't be found
|
||||
+ }
|
||||
+ return wantarray ? @output : join('',@output);
|
||||
+}
|
||||
+
|
||||
|
||||
package GITCVS::log;
|
||||
|
||||
@@ -3882,7 +3898,7 @@ sub update
|
||||
# several candidate merge bases. let's assume
|
||||
# that the first one is the best one.
|
||||
my $base = eval {
|
||||
- safe_pipe_capture('git', 'merge-base',
|
||||
+ ::safe_pipe_capture('git', 'merge-base',
|
||||
$lastpicked, $parent);
|
||||
};
|
||||
# The two branches may not be related at all,
|
||||
@@ -4749,7 +4765,7 @@ sub getMetaFromCommithash
|
||||
return $retVal;
|
||||
}
|
||||
|
||||
- my($fileHash)=safe_pipe_capture("git","rev-parse","$revCommit:$filename");
|
||||
+ my($fileHash) = ::safe_pipe_capture("git","rev-parse","$revCommit:$filename");
|
||||
chomp $fileHash;
|
||||
if(!($fileHash=~/^[0-9a-f]{40}$/))
|
||||
{
|
||||
@@ -4844,8 +4860,8 @@ sub lookupCommitRef
|
||||
return $commitHash;
|
||||
}
|
||||
|
||||
- $commitHash=safe_pipe_capture("git","rev-parse","--verify","--quiet",
|
||||
- $self->unescapeRefName($ref));
|
||||
+ $commitHash = ::safe_pipe_capture("git","rev-parse","--verify","--quiet",
|
||||
+ $self->unescapeRefName($ref));
|
||||
$commitHash=~s/\s*$//;
|
||||
if(!($commitHash=~/^[0-9a-f]{40}$/))
|
||||
{
|
||||
@@ -4854,7 +4870,7 @@ sub lookupCommitRef
|
||||
|
||||
if( defined($commitHash) )
|
||||
{
|
||||
- my $type=safe_pipe_capture("git","cat-file","-t",$commitHash);
|
||||
+ my $type = ::safe_pipe_capture("git","cat-file","-t",$commitHash);
|
||||
if( ! ($type=~/^commit\s*$/ ) )
|
||||
{
|
||||
$commitHash=undef;
|
||||
@@ -4907,7 +4923,7 @@ sub commitmessage
|
||||
return $message;
|
||||
}
|
||||
|
||||
- my @lines = safe_pipe_capture("git", "cat-file", "commit", $commithash);
|
||||
+ my @lines = ::safe_pipe_capture("git", "cat-file", "commit", $commithash);
|
||||
shift @lines while ( $lines[0] =~ /\S/ );
|
||||
$message = join("",@lines);
|
||||
$message .= " " if ( $message =~ /\n$/ );
|
||||
@@ -5056,25 +5072,6 @@ sub in_array
|
||||
return $retval;
|
||||
}
|
||||
|
||||
-=head2 safe_pipe_capture
|
||||
-
|
||||
-an alternative to `command` that allows input to be passed as an array
|
||||
-to work around shell problems with weird characters in arguments
|
||||
-
|
||||
-=cut
|
||||
-sub safe_pipe_capture {
|
||||
-
|
||||
- my @output;
|
||||
-
|
||||
- if (my $pid = open my $child, '-|') {
|
||||
- @output = (<$child>);
|
||||
- close $child or die join(' ',@_).": $! $?";
|
||||
- } else {
|
||||
- exec(@_) or die "$! $?"; # exec() can fail the executable can't be found
|
||||
- }
|
||||
- return wantarray ? @output : join('',@output);
|
||||
-}
|
||||
-
|
||||
=head2 mangle_dirname
|
||||
|
||||
create a string from a directory name that is suitable to use as
|
||||
--
|
||||
2.14.1
|
||||
|
||||
|
||||
From a871ec30ae5d7b472b35641a2a1b35685b6d41bb Mon Sep 17 00:00:00 2001
|
||||
From: joernchen <joernchen@phenoelit.de>
|
||||
Date: Mon, 11 Sep 2017 14:45:09 +0900
|
||||
Subject: [PATCH 2/6] cvsserver: use safe_pipe_capture instead of backticks
|
||||
|
||||
This makes the script pass arguments that are derived from end-user
|
||||
input in safer way when invoking subcommands.
|
||||
|
||||
Reported-by: joernchen <joernchen@phenoelit.de>
|
||||
Signed-off-by: joernchen <joernchen@phenoelit.de>
|
||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
||||
(cherry picked from commit 27dd73871f814062737c327103ee43f1eb7f30d9)
|
||||
---
|
||||
git-cvsserver.perl | 22 +++++++++++-----------
|
||||
1 file changed, 11 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/git-cvsserver.perl b/git-cvsserver.perl
|
||||
index 8229d9d198..bd29b26cc2 100755
|
||||
--- a/git-cvsserver.perl
|
||||
+++ b/git-cvsserver.perl
|
||||
@@ -841,7 +841,7 @@ sub req_Modified
|
||||
# Save the file data in $state
|
||||
$state->{entries}{$state->{directory}.$data}{modified_filename} = $filename;
|
||||
$state->{entries}{$state->{directory}.$data}{modified_mode} = $mode;
|
||||
- $state->{entries}{$state->{directory}.$data}{modified_hash} = `git hash-object $filename`;
|
||||
+ $state->{entries}{$state->{directory}.$data}{modified_hash} = safe_pipe_capture('git','hash-object',$filename);
|
||||
$state->{entries}{$state->{directory}.$data}{modified_hash} =~ s/\s.*$//s;
|
||||
|
||||
#$log->debug("req_Modified : file=$data mode=$mode size=$size");
|
||||
@@ -1463,7 +1463,7 @@ sub req_update
|
||||
# transmit file, format is single integer on a line by itself (file
|
||||
# size) followed by the file contents
|
||||
# TODO : we should copy files in blocks
|
||||
- my $data = `cat $mergedFile`;
|
||||
+ my $data = safe_pipe_capture('cat', $mergedFile);
|
||||
$log->debug("File size : " . length($data));
|
||||
print length($data) . "\n";
|
||||
print $data;
|
||||
@@ -1579,7 +1579,7 @@ sub req_ci
|
||||
$branchRef = "refs/heads/$stickyInfo->{tag}";
|
||||
}
|
||||
|
||||
- $parenthash = `git show-ref -s $branchRef`;
|
||||
+ $parenthash = safe_pipe_capture('git', 'show-ref', '-s', $branchRef);
|
||||
chomp $parenthash;
|
||||
if ($parenthash !~ /^[0-9a-f]{40}$/)
|
||||
{
|
||||
@@ -1704,7 +1704,7 @@ sub req_ci
|
||||
}
|
||||
close $msg_fh;
|
||||
|
||||
- my $commithash = `git commit-tree $treehash -p $parenthash < $msg_filename`;
|
||||
+ my $commithash = safe_pipe_capture('git', 'commit-tree', $treehash, '-p', $parenthash, '-F', $msg_filename);
|
||||
chomp($commithash);
|
||||
$log->info("Commit hash : $commithash");
|
||||
|
||||
@@ -2854,12 +2854,12 @@ sub transmitfile
|
||||
|
||||
die "Need filehash" unless ( defined ( $filehash ) and $filehash =~ /^[a-zA-Z0-9]{40}$/ );
|
||||
|
||||
- my $type = `git cat-file -t $filehash`;
|
||||
+ my $type = safe_pipe_capture('git', 'cat-file', '-t', $filehash);
|
||||
chomp $type;
|
||||
|
||||
die ( "Invalid type '$type' (expected 'blob')" ) unless ( defined ( $type ) and $type eq "blob" );
|
||||
|
||||
- my $size = `git cat-file -s $filehash`;
|
||||
+ my $size = safe_pipe_capture('git', 'cat-file', '-s', $filehash);
|
||||
chomp $size;
|
||||
|
||||
$log->debug("transmitfile($filehash) size=$size, type=$type");
|
||||
@@ -3040,7 +3040,7 @@ sub ensureWorkTree
|
||||
chdir $work->{emptyDir} or
|
||||
die "Unable to chdir to $work->{emptyDir}\n";
|
||||
|
||||
- my $ver = `git show-ref -s refs/heads/$state->{module}`;
|
||||
+ my $ver = safe_pipe_capture('git', 'show-ref', '-s', "refs/heads/$state->{module}");
|
||||
chomp $ver;
|
||||
if ($ver !~ /^[0-9a-f]{40}$/)
|
||||
{
|
||||
@@ -3287,7 +3287,7 @@ sub open_blob_or_die
|
||||
die "Need filehash\n";
|
||||
}
|
||||
|
||||
- my $type = `git cat-file -t $name`;
|
||||
+ my $type = safe_pipe_capture('git', 'cat-file', '-t', $name);
|
||||
chomp $type;
|
||||
|
||||
unless ( defined ( $type ) and $type eq "blob" )
|
||||
@@ -3296,7 +3296,7 @@ sub open_blob_or_die
|
||||
die ( "Invalid type '$type' (expected 'blob')" )
|
||||
}
|
||||
|
||||
- my $size = `git cat-file -s $name`;
|
||||
+ my $size = safe_pipe_capture('git', 'cat-file', '-s', $name);
|
||||
chomp $size;
|
||||
|
||||
$log->debug("open_blob_or_die($name) size=$size, type=$type");
|
||||
@@ -3813,10 +3813,10 @@ sub update
|
||||
# first lets get the commit list
|
||||
$ENV{GIT_DIR} = $self->{git_path};
|
||||
|
||||
- my $commitsha1 = `git rev-parse $self->{module}`;
|
||||
+ my $commitsha1 = ::safe_pipe_capture('git', 'rev-parse', $self->{module});
|
||||
chomp $commitsha1;
|
||||
|
||||
- my $commitinfo = `git cat-file commit $self->{module} 2>&1`;
|
||||
+ my $commitinfo = ::safe_pipe_capture('git', 'cat-file', 'commit', $self->{module});
|
||||
unless ( $commitinfo =~ /tree\s+[a-zA-Z0-9]{40}/ )
|
||||
{
|
||||
die("Invalid module '$self->{module}'");
|
||||
--
|
||||
2.14.1
|
||||
|
||||
|
||||
From d213a1c065b12601e3147363f6e0b11d85f5d514 Mon Sep 17 00:00:00 2001
|
||||
From: Junio C Hamano <gitster@pobox.com>
|
||||
Date: Mon, 11 Sep 2017 14:45:54 +0900
|
||||
Subject: [PATCH 3/6] cvsserver: use safe_pipe_capture for `constant commands`
|
||||
as well
|
||||
|
||||
This is not strictly necessary, but it is a good code hygiene.
|
||||
|
||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
||||
(cherry picked from commit 46203ac24dc7e6b5a8d4f1b024ed93591705d47b)
|
||||
---
|
||||
git-cvsserver.perl | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/git-cvsserver.perl b/git-cvsserver.perl
|
||||
index bd29b26cc2..ae1044273d 100755
|
||||
--- a/git-cvsserver.perl
|
||||
+++ b/git-cvsserver.perl
|
||||
@@ -356,7 +356,7 @@ sub req_Root
|
||||
return 0;
|
||||
}
|
||||
|
||||
- my @gitvars = `git config -l`;
|
||||
+ my @gitvars = safe_pipe_capture(qw(git config -l));
|
||||
if ($?) {
|
||||
print "E problems executing git-config on the server -- this is not a git repository or the PATH is not set correctly.\n";
|
||||
print "E \n";
|
||||
@@ -943,7 +943,7 @@ sub req_co
|
||||
|
||||
# Provide list of modules, if -c was used.
|
||||
if (exists $state->{opt}{c}) {
|
||||
- my $showref = `git show-ref --heads`;
|
||||
+ my $showref = safe_pipe_capture(qw(git show-ref --heads));
|
||||
for my $line (split '\n', $showref) {
|
||||
if ( $line =~ m% refs/heads/(.*)$% ) {
|
||||
print "M $1\t$1\n";
|
||||
@@ -1181,7 +1181,7 @@ sub req_update
|
||||
# projects (heads in this case) to checkout.
|
||||
#
|
||||
if ($state->{module} eq '') {
|
||||
- my $showref = `git show-ref --heads`;
|
||||
+ my $showref = safe_pipe_capture(qw(git show-ref --heads));
|
||||
print "E cvs update: Updating .\n";
|
||||
for my $line (split '\n', $showref) {
|
||||
if ( $line =~ m% refs/heads/(.*)$% ) {
|
||||
@@ -1687,7 +1687,7 @@ sub req_ci
|
||||
return;
|
||||
}
|
||||
|
||||
- my $treehash = `git write-tree`;
|
||||
+ my $treehash = safe_pipe_capture(qw(git write-tree));
|
||||
chomp $treehash;
|
||||
|
||||
$log->debug("Treehash : $treehash, Parenthash : $parenthash");
|
||||
--
|
||||
2.14.1
|
||||
|
||||
|
||||
From 7b1cfcc88d29d28133f6864c9ef7173d1edffa60 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff King <peff@peff.net>
|
||||
Date: Mon, 11 Sep 2017 11:27:51 -0400
|
||||
Subject: [PATCH 4/6] shell: drop git-cvsserver support by default
|
||||
|
||||
The git-cvsserver script is old and largely unmaintained
|
||||
these days. But git-shell allows untrusted users to run it
|
||||
out of the box, significantly increasing its attack surface.
|
||||
|
||||
Let's drop it from git-shell's list of internal handlers so
|
||||
that it cannot be run by default. This is not backwards
|
||||
compatible. But given the age and development activity on
|
||||
CVS-related parts of Git, this is likely to impact very few
|
||||
users, while helping many more (i.e., anybody who runs
|
||||
git-shell and had no intention of supporting CVS).
|
||||
|
||||
There's no configuration mechanism in git-shell for us to
|
||||
add a boolean and flip it to "off". But there is a mechanism
|
||||
for adding custom commands, and adding CVS support here is
|
||||
fairly trivial. Let's document it to give guidance to
|
||||
anybody who really is still running cvsserver.
|
||||
|
||||
Signed-off-by: Jeff King <peff@peff.net>
|
||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
||||
(cherry picked from commit 9a42c03cb71eaa9d41ba67275de38c997a791c32)
|
||||
---
|
||||
Documentation/git-shell.txt | 16 ++++++++++++++
|
||||
shell.c | 14 ------------
|
||||
t/t9400-git-cvsserver-server.sh | 48 +++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 64 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/Documentation/git-shell.txt b/Documentation/git-shell.txt
|
||||
index 2e30a3e42d..54cf2560be 100644
|
||||
--- a/Documentation/git-shell.txt
|
||||
+++ b/Documentation/git-shell.txt
|
||||
@@ -79,6 +79,22 @@ EOF
|
||||
$ chmod +x $HOME/git-shell-commands/no-interactive-login
|
||||
----------------
|
||||
|
||||
+To enable git-cvsserver access (which should generally have the
|
||||
+`no-interactive-login` example above as a prerequisite, as creating
|
||||
+the git-shell-commands directory allows interactive logins):
|
||||
+
|
||||
+----------------
|
||||
+$ cat >$HOME/git-shell-commands/cvs <<\EOF
|
||||
+if ! test $# = 1 && test "$1" = "server"
|
||||
+then
|
||||
+ echo >&2 "git-cvsserver only handles \"server\""
|
||||
+ exit 1
|
||||
+fi
|
||||
+exec git cvsserver server
|
||||
+EOF
|
||||
+$ chmod +x $HOME/git-shell-commands/cvs
|
||||
+----------------
|
||||
+
|
||||
SEE ALSO
|
||||
--------
|
||||
ssh(1),
|
||||
diff --git a/shell.c b/shell.c
|
||||
index fe2d314593..234b2d4f16 100644
|
||||
--- a/shell.c
|
||||
+++ b/shell.c
|
||||
@@ -25,19 +25,6 @@ static int do_generic_cmd(const char *me, char *arg)
|
||||
return execv_git_cmd(my_argv);
|
||||
}
|
||||
|
||||
-static int do_cvs_cmd(const char *me, char *arg)
|
||||
-{
|
||||
- const char *cvsserver_argv[3] = {
|
||||
- "cvsserver", "server", NULL
|
||||
- };
|
||||
-
|
||||
- if (!arg || strcmp(arg, "server"))
|
||||
- die("git-cvsserver only handles server: %s", arg);
|
||||
-
|
||||
- setup_path();
|
||||
- return execv_git_cmd(cvsserver_argv);
|
||||
-}
|
||||
-
|
||||
static int is_valid_cmd_name(const char *cmd)
|
||||
{
|
||||
/* Test command contains no . or / characters */
|
||||
@@ -134,7 +121,6 @@ static struct commands {
|
||||
{ "git-receive-pack", do_generic_cmd },
|
||||
{ "git-upload-pack", do_generic_cmd },
|
||||
{ "git-upload-archive", do_generic_cmd },
|
||||
- { "cvs", do_cvs_cmd },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh
|
||||
index 432c61d246..c30660d606 100755
|
||||
--- a/t/t9400-git-cvsserver-server.sh
|
||||
+++ b/t/t9400-git-cvsserver-server.sh
|
||||
@@ -588,4 +588,52 @@ test_expect_success 'cvs annotate' '
|
||||
test_cmp ../expect ../actual
|
||||
'
|
||||
|
||||
+#------------
|
||||
+# running via git-shell
|
||||
+#------------
|
||||
+
|
||||
+cd "$WORKDIR"
|
||||
+
|
||||
+test_expect_success 'create remote-cvs helper' '
|
||||
+ write_script remote-cvs <<-\EOF
|
||||
+ exec git shell -c "cvs server"
|
||||
+ EOF
|
||||
+'
|
||||
+
|
||||
+test_expect_success 'cvs server does not run with vanilla git-shell' '
|
||||
+ (
|
||||
+ cd cvswork &&
|
||||
+ CVS_SERVER=$WORKDIR/remote-cvs &&
|
||||
+ export CVS_SERVER &&
|
||||
+ test_must_fail cvs log merge
|
||||
+ )
|
||||
+'
|
||||
+
|
||||
+test_expect_success 'configure git shell to run cvs server' '
|
||||
+ mkdir "$HOME"/git-shell-commands &&
|
||||
+
|
||||
+ write_script "$HOME"/git-shell-commands/cvs <<-\EOF &&
|
||||
+ if ! test $# = 1 && test "$1" = "server"
|
||||
+ then
|
||||
+ echo >&2 "git-cvsserver only handles \"server\""
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ exec git cvsserver server
|
||||
+ EOF
|
||||
+
|
||||
+ # Should not be used, but part of the recommended setup
|
||||
+ write_script "$HOME"/git-shell-commands/no-interactive-login <<-\EOF
|
||||
+ echo Interactive login forbidden
|
||||
+ EOF
|
||||
+'
|
||||
+
|
||||
+test_expect_success 'cvs server can run with recommended config' '
|
||||
+ (
|
||||
+ cd cvswork &&
|
||||
+ CVS_SERVER=$WORKDIR/remote-cvs &&
|
||||
+ export CVS_SERVER &&
|
||||
+ cvs log merge
|
||||
+ )
|
||||
+'
|
||||
+
|
||||
test_done
|
||||
--
|
||||
2.14.1
|
||||
|
||||
|
||||
From 974a1f5703091e07891cfb743c50cb66634ef8cf Mon Sep 17 00:00:00 2001
|
||||
From: Jeff King <peff@peff.net>
|
||||
Date: Mon, 11 Sep 2017 10:24:11 -0400
|
||||
Subject: [PATCH 5/6] archimport: use safe_pipe_capture for user input
|
||||
|
||||
Refnames can contain shell metacharacters which need to be
|
||||
passed verbatim to sub-processes. Using safe_pipe_capture
|
||||
skips the shell entirely.
|
||||
|
||||
Signed-off-by: Jeff King <peff@peff.net>
|
||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
||||
(cherry picked from commit 8d0fad0a7a6ba34fd706c148fa7ed1f8eb2b8b26)
|
||||
---
|
||||
git-archimport.perl | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/git-archimport.perl b/git-archimport.perl
|
||||
index 9cb123a07d..b7c173c345 100755
|
||||
--- a/git-archimport.perl
|
||||
+++ b/git-archimport.perl
|
||||
@@ -983,7 +983,7 @@ sub find_parents {
|
||||
# check that we actually know about the branch
|
||||
next unless -e "$git_dir/refs/heads/$branch";
|
||||
|
||||
- my $mergebase = `git-merge-base $branch $ps->{branch}`;
|
||||
+ my $mergebase = safe_pipe_capture(qw(git-merge-base), $branch, $ps->{branch});
|
||||
if ($?) {
|
||||
# Don't die here, Arch supports one-way cherry-picking
|
||||
# between branches with no common base (or any relationship
|
||||
@@ -1074,7 +1074,7 @@ sub find_parents {
|
||||
|
||||
sub git_rev_parse {
|
||||
my $name = shift;
|
||||
- my $val = `git-rev-parse $name`;
|
||||
+ my $val = safe_pipe_capture(qw(git-rev-parse), $name);
|
||||
die "Error: git-rev-parse $name" if $?;
|
||||
chomp $val;
|
||||
return $val;
|
||||
--
|
||||
2.14.1
|
||||
|
||||
|
||||
From c6d8647e2857f1ffbe1c6ff0c006b8da0710f9d4 Mon Sep 17 00:00:00 2001
|
||||
From: Jeff King <peff@peff.net>
|
||||
Date: Mon, 11 Sep 2017 10:24:26 -0400
|
||||
Subject: [PATCH 6/6] cvsimport: shell-quote variable used in backticks
|
||||
|
||||
We run `git rev-parse` though the shell, and quote its
|
||||
argument only with single-quotes. This prevents most
|
||||
metacharacters from being a problem, but misses the obvious
|
||||
case when $name itself has single-quotes in it. We can fix
|
||||
this by applying the usual shell-quoting formula.
|
||||
|
||||
Signed-off-by: Jeff King <peff@peff.net>
|
||||
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
||||
(cherry picked from commit 5b4efea666951efe0770f8d5a301f8917015315f)
|
||||
---
|
||||
git-cvsimport.perl | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
|
||||
index 1e4e65a45d..36929921ea 100755
|
||||
--- a/git-cvsimport.perl
|
||||
+++ b/git-cvsimport.perl
|
||||
@@ -642,6 +642,7 @@ sub is_sha1 {
|
||||
|
||||
sub get_headref ($) {
|
||||
my $name = shift;
|
||||
+ $name =~ s/'/'\\''/;
|
||||
my $r = `git rev-parse --verify '$name' 2>/dev/null`;
|
||||
return undef unless $? == 0;
|
||||
chomp $r;
|
||||
--
|
||||
2.14.1
|
||||
|
||||
44
git.spec
44
git.spec
|
|
@ -54,8 +54,8 @@
|
|||
%endif
|
||||
|
||||
Name: git
|
||||
Version: 2.9.3
|
||||
Release: 1%{?dist}
|
||||
Version: 2.9.5
|
||||
Release: 3%{?dist}
|
||||
Summary: Fast Version Control System
|
||||
License: GPLv2
|
||||
Group: Development/Tools
|
||||
|
|
@ -92,6 +92,21 @@ Patch1: git-cvsimport-Ignore-cvsps-2.2b1-Branches-output.patch
|
|||
# https://bugzilla.redhat.com/600411
|
||||
Patch3: git-1.7-el5-emacs-support.patch
|
||||
|
||||
# fix infinite loop + test
|
||||
Patch4: 0001-Add-test-for-ls-tree-with-broken-symlink-under-refs-.patch
|
||||
Patch5: 0002-resolve_ref_unsafe-limit-the-number-of-stat_ref-retr.patch
|
||||
|
||||
# https://bugzilla.redhat.com/1438801
|
||||
# https://github.com/git/git/commit/bc6b13a7d
|
||||
Patch6: 0001-blame-fix-segfault-on-untracked-files.patch
|
||||
|
||||
# Cherry-picked patch set from 2.10.5 to harden git shell and git cvsserver
|
||||
Patch7: git-2.9.5-git-shell-and-cvsserver-hardening.patch
|
||||
|
||||
# https://bugzilla.redhat.com/1510455 (CVE-2017-15298)
|
||||
# https://github.com/git/git/commit/a937b37e76
|
||||
Patch8: 0001-revision-quit-pruning-diff-more-quickly-when-possibl.patch
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
|
||||
%if ! %{use_prebuilt_docs} && ! 0%{?_without_docs}
|
||||
|
|
@ -376,6 +391,11 @@ rm -rf "$gpghome" # Cleanup tmp gpg home dir
|
|||
%if %{emacs_old}
|
||||
%patch3 -p1
|
||||
%endif
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
|
||||
%if %{use_prebuilt_docs}
|
||||
mkdir -p prebuilt_docs/{html,man}
|
||||
|
|
@ -736,6 +756,26 @@ rm -rf %{buildroot}
|
|||
# No files for you!
|
||||
|
||||
%changelog
|
||||
* Tue Nov 07 2017 Todd Zullinger <tmz@pobox.com> - 2.9.5-3
|
||||
- Fix git-clone memory exhaustion (CVE-2017-15298)
|
||||
Resolves: #1510455, #1510457
|
||||
|
||||
* Tue Sep 26 2017 Todd Zullinger <tmz@pobox.com> - 2.9.5-2
|
||||
- Cherry-pick patch set to harden git shell and git cvsserver
|
||||
|
||||
* Thu Aug 10 2017 Todd Zullinger <tmz@pobox.com> - 2.9.5-1
|
||||
- Update to 2.9.5 (resolves CVE-2017-1000117)
|
||||
|
||||
* Tue May 09 2017 Todd Zullinger <tmz@pobox.com> - 2.9.4-1
|
||||
- Update to 2.9.4 (resolves CVE-2017-8386)
|
||||
|
||||
* Tue Apr 04 2017 Todd Zullinger <tmz@pobox.com> - 2.9.3-3
|
||||
- Apply upstream fix for blame segfault (#1438801)
|
||||
|
||||
* Thu Jan 19 2017 Petr Stodulka <pstodulk@redhat.com> -2.9.3-2
|
||||
- fix infinite loop of "git ls-tree" on broken symlink
|
||||
Resolves: #1414792
|
||||
|
||||
* Mon Aug 15 2016 Jon Ciesla <limburgher@gmail.com> - 2.9.3-1
|
||||
- Update to 2.9.3.
|
||||
|
||||
|
|
|
|||
12
sources
12
sources
|
|
@ -1,6 +1,6 @@
|
|||
316776336775d25d58888686a4893c86 git-2.9.3.tar.sign
|
||||
3d32cb5cb5b4f29bd2eb1cde596fc542 git-2.9.3.tar.xz
|
||||
cf0bf766505aa0674006dba6561c153b git-htmldocs-2.9.3.tar.sign
|
||||
29378f5a360d86b9f5838ad74680accd git-htmldocs-2.9.3.tar.xz
|
||||
1b7e97104f3f98cbae9fb475ab37aa19 git-manpages-2.9.3.tar.sign
|
||||
337165a3b2bbe4814c73075cb6854ca2 git-manpages-2.9.3.tar.xz
|
||||
SHA512 (git-2.9.5.tar.xz) = 5a3f62b9640a477bfd1a299f365ddb36c69ce5fb92ecf3ba7176686836a3057de7c74078b46526abd7bee0204c49e36bbd7d77d4c2f69c6524eca592ab6c365d
|
||||
SHA512 (git-2.9.5.tar.sign) = ae799e503c9648fffd9c18ce7bf826f8e28cec2bce196f67275f49eeba3c250457c2a4aa8316079e43f06a6374bbc2c3cc196555f58452aecef8be8727b2edcd
|
||||
SHA512 (git-htmldocs-2.9.5.tar.xz) = 8ac48cc1bd9635ede960fb2dc5e18590fa0c743e0892e754cade2b5b2833a24f463059f2992e74a281b5ae3ff48309187d06f2e546676ceb3c38cf5ef32fb555
|
||||
SHA512 (git-htmldocs-2.9.5.tar.sign) = 9239fda9b02adf4232048d259fe133cf67999836e3bb9ea76e96b18721916af5b22b375afbd857cfbb49dbafd9a9b8e1a02b0e53d21ecf04f2e5831a6b9fcdea
|
||||
SHA512 (git-manpages-2.9.5.tar.xz) = e4daa7b481c1e14da76dac04348843240c9ece80123f6e6e10835d74737605c03ca07c60b90b94f59ba5fc91b2608115db632f3636a6eec6c95df682191ea9fb
|
||||
SHA512 (git-manpages-2.9.5.tar.sign) = 48f9395ea09200275fe9836f27bfea1672151b351ae79a6554d9817d72e97d0db8d4656079bd1af3eeb2fda2c1d7e0ec9ce3f16b0fc3dda659cfd6fc836c6495
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue