diff -uNr git-core-1.5.4.3/debian/changelog git-core-1.5.4.3-cve/debian/changelog --- git-core-1.5.4.3/debian/changelog 2009-01-23 01:19:19.000000000 +0000 +++ git-core-1.5.4.3-cve/debian/changelog 2009-01-23 01:13:02.000000000 +0000 @@ -1,3 +1,11 @@ +git-core (1:1.5.4.3-1ubuntu2.1) hardy-security; urgency=high + + * SECURITY UPDATE: Fix remote code execution in gitweb (LP: #317052) + - CVE-2008-5516: http://repo.or.cz/w/git.git?a=commitdiff;h=c582abae + - CVE-2008-5517: http://repo.or.cz/w/git.git?a=commitdiff;h=516381d5 + + -- David Leadbeater Fri, 23 Jan 2009 01:12:47 -0000 + git-core (1:1.5.4.3-1ubuntu2) hardy; urgency=low * debian/rules: Use wish8.4 for the tcl interpreter, to match our dependency diff -uNr git-core-1.5.4.3/debian/diff/0005-gitweb-CVE-2008-5516.diff git-core-1.5.4.3-cve/debian/diff/0005-gitweb-CVE-2008-5516.diff --- git-core-1.5.4.3/debian/diff/0005-gitweb-CVE-2008-5516.diff 1970-01-01 01:00:00.000000000 +0100 +++ git-core-1.5.4.3-cve/debian/diff/0005-gitweb-CVE-2008-5516.diff 2009-01-23 01:19:45.000000000 +0000 @@ -0,0 +1,143 @@ +From 8f8bfb38271775770cd1da8fb7cfd1e2d7ef2481 Mon Sep 17 00:00:00 2001 +From: Jakub Narebski +Date: Wed, 5 Mar 2008 09:31:55 +0100 +Subject: [PATCH 1/2] gitweb: Fix and simplify pickaxe search + +Instead of using "git-rev-list | git-diff-tree" pipeline for pickaxe +search, use git-log with appropriate options. Besides reducing number +of forks by one, this allows to use list form of open, which in turn +allow to not worry about quoting arguments and to avoid forking shell. + +The options to git-log were chosen to reduce required changes in +pickaxe git command output parsing; gitweb still parses returned +commits one by one. + +Parsing "pickaxe" output is simplified: git_search now reuses +parse_difftree_raw_line and writes affected files as they arrive using +the fact that commit name goes always before [raw] diff. + +While at it long bug of pickaxe search was fixed, namely that the last +commit found by pickaxe search was never shown. + +Signed-off-by: Jakub Narebski +Signed-off-by: Junio C Hamano + +Note: This patch was backported to 1.5.4.7 by Todd Zullinger +. Any blame for problems should come to me, not the +upstream authors. :) +--- + gitweb/gitweb.perl | 83 ++++++++++++++++++++++++++------------------------- + 1 files changed, 42 insertions(+), 41 deletions(-) + +diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl +index 86a6ced..e011393 100755 +--- a/gitweb/gitweb.perl ++++ b/gitweb/gitweb.perl +@@ -5199,50 +5199,18 @@ sub git_search { + print "\n"; + my $alternate = 1; + $/ = "\n"; +- my $git_command = git_cmd_str(); +- my $searchqtext = $searchtext; +- $searchqtext =~ s/'/'\\''/; +- open my $fd, "-|", "$git_command rev-list $hash | " . +- "$git_command diff-tree -r --stdin -S\'$searchqtext\'"; ++ open my $fd, '-|', git_cmd(), '--no-pager', 'log', @diff_opts, ++ '--pretty=format:%H', '--no-abbrev', '--raw', "-S$searchtext"; + undef %co; + my @files; + while (my $line = <$fd>) { +- if (%co && $line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\t(.*)$/) { +- my %set; +- $set{'file'} = $6; +- $set{'from_id'} = $3; +- $set{'to_id'} = $4; +- $set{'id'} = $set{'to_id'}; +- if ($set{'id'} =~ m/0{40}/) { +- $set{'id'} = $set{'from_id'}; +- } +- if ($set{'id'} =~ m/0{40}/) { +- next; +- } +- push @files, \%set; +- } elsif ($line =~ m/^([0-9a-fA-F]{40})$/){ ++ chomp $line; ++ next unless $line; ++ ++ my %set = parse_difftree_raw_line($line); ++ if (defined $set{'commit'}) { ++ # finish previous commit + if (%co) { +- if ($alternate) { +- print "\n"; +- } else { +- print "\n"; +- } +- $alternate ^= 1; +- my $author = chop_and_escape_str($co{'author_name'}, 15, 5); +- print "\n" . +- "\n" . +- "\n" . + "\n" . + "\n"; + } +- %co = parse_commit($1); ++ ++ if ($alternate) { ++ print "\n"; ++ } else { ++ print "\n"; ++ } ++ $alternate ^= 1; ++ %co = parse_commit($set{'commit'}); ++ my $author = chop_and_escape_str($co{'author_name'}, 15, 5); ++ print "\n" . ++ "\n" . ++ "\n" . ++ "\n" . ++ "\n"; ++ } ++ + print "
$co{'age_string_date'}" . $author . "" . +- $cgi->a({-href => href(action=>"commit", hash=>$co{'id'}), +- -class => "list subject"}, +- chop_and_escape_str($co{'title'}, 50) . "
"); +- while (my $setref = shift @files) { +- my %set = %$setref; +- print $cgi->a({-href => href(action=>"blob", hash_base=>$co{'id'}, +- hash=>$set{'id'}, file_name=>$set{'file'}), +- -class => "list"}, +- "" . esc_path($set{'file'}) . "") . +- "
\n"; +- } + print "
" . + $cgi->a({-href => href(action=>"commit", hash=>$co{'id'})}, "commit") . +@@ -5251,11 +5219,44 @@ sub git_search { + print "
$co{'age_string_date'}$author" . ++ $cgi->a({-href => href(action=>"commit", hash=>$co{'id'}), ++ -class => "list subject"}, ++ chop_and_escape_str($co{'title'}, 50) . "
"); ++ } elsif (defined $set{'to_id'}) { ++ next if ($set{'to_id'} =~ m/^0{40}$/); ++ ++ print $cgi->a({-href => href(action=>"blob", hash_base=>$co{'id'}, ++ hash=>$set{'to_id'}, file_name=>$set{'to_file'}), ++ -class => "list"}, ++ "" . esc_path($set{'file'}) . "") . ++ "
\n"; + } + } + close $fd; + ++ # finish last commit (warning: repetition!) ++ if (%co) { ++ print "
" . ++ $cgi->a({-href => href(action=>"commit", hash=>$co{'id'})}, "commit") . ++ " | " . ++ $cgi->a({-href => href(action=>"tree", hash=>$co{'tree'}, hash_base=>$co{'id'})}, "tree"); ++ print "
\n"; + } + +-- +1.6.1 + diff -uNr git-core-1.5.4.3/debian/diff/0006-gitweb-CVE-2008-5517.diff git-core-1.5.4.3-cve/debian/diff/0006-gitweb-CVE-2008-5517.diff --- git-core-1.5.4.3/debian/diff/0006-gitweb-CVE-2008-5517.diff 1970-01-01 01:00:00.000000000 +0100 +++ git-core-1.5.4.3-cve/debian/diff/0006-gitweb-CVE-2008-5517.diff 2009-01-23 01:19:45.000000000 +0000 @@ -0,0 +1,75 @@ +From 2813e6cef24a8b363a97ea0c86bf4494fc453f32 Mon Sep 17 00:00:00 2001 +From: Lea Wiemann +Date: Tue, 17 Jun 2008 23:46:35 +0200 +Subject: [PATCH 2/2] gitweb: quote commands properly when calling the shell + +This eliminates the function git_cmd_str, which was used for composing +command lines, and adds a quote_command function, which quotes all of +its arguments (as in quote.c). + +Signed-off-by: Lea Wiemann +Signed-off-by: Junio C Hamano +--- + gitweb/gitweb.perl | 24 ++++++++++++++---------- + 1 files changed, 14 insertions(+), 10 deletions(-) + +diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl +index e011393..bd50c07 100755 +--- a/gitweb/gitweb.perl ++++ b/gitweb/gitweb.perl +@@ -1396,9 +1396,13 @@ sub git_cmd { + return $GIT, '--git-dir='.$git_dir; + } + +-# returns path to the core git executable and the --git-dir parameter as string +-sub git_cmd_str { +- return join(' ', git_cmd()); ++# quote the given arguments for passing them to the shell ++# quote_command("command", "arg 1", "arg with ' and ! characters") ++# => "'command' 'arg 1' 'arg with '\'' and '\!' characters'" ++# Try to avoid using this function wherever possible. ++sub quote_command { ++ return join(' ', ++ map( { my $a = $_; $a =~ s/(['!])/'\\$1'/g; "'$a'" } @_ )); + } + + # get HEAD ref of given project as hash +@@ -4477,7 +4481,6 @@ sub git_snapshot { + $hash = git_get_head_hash($project); + } + +- my $git_command = git_cmd_str(); + my $name = $project; + $name =~ s,([^/])/*\.git$,$1,; + $name = basename($name); +@@ -4485,11 +4488,12 @@ sub git_snapshot { + $name =~ s/\047/\047\\\047\047/g; + my $cmd; + $filename .= "-$hash$known_snapshot_formats{$format}{'suffix'}"; +- $cmd = "$git_command archive " . +- "--format=$known_snapshot_formats{$format}{'format'} " . +- "--prefix=\'$name\'/ $hash"; ++ $cmd = quote_command( ++ git_cmd(), 'archive', ++ "--format=$known_snapshot_formats{$format}{'format'}", ++ "--prefix=$name/", $hash); + if (exists $known_snapshot_formats{$format}{'compressor'}) { +- $cmd .= ' | ' . join ' ', @{$known_snapshot_formats{$format}{'compressor'}}; ++ $cmd .= ' | ' . quote_command(@{$known_snapshot_formats{$format}{'compressor'}}); + } + + print $cgi->header( +@@ -4702,8 +4706,8 @@ sub git_object { + if ($hash || ($hash_base && !defined $file_name)) { + my $object_id = $hash || $hash_base; + +- my $git_command = git_cmd_str(); +- open my $fd, "-|", "$git_command cat-file -t $object_id 2>/dev/null" ++ open my $fd, "-|", quote_command( ++ git_cmd(), 'cat-file', '-t', $object_id) . ' 2> /dev/null' + or die_error('404 Not Found', "Object does not exist"); + $type = <$fd>; + chomp $type; +-- +1.6.1 +