Version in base suite: 4.3-3 Version in overlay suite: (not present) Base version: changetrack_4.3-3 Target version: changetrack_4.3-3+etch1 Base file: /org/ftp.debian.org/ftp/pool/main/c/changetrack/changetrack_4.3-3.dsc Target file: /org/ftp.debian.org/queue/o-p-u-new/changetrack_4.3-3+etch1.dsc changetrack | 58 +++++++++++++++++++++++++++---------------------------- debian/changelog | 10 ++++++++- 2 files changed, 38 insertions(+), 30 deletions(-) diff -u changetrack-4.3/changetrack changetrack-4.3/changetrack --- changetrack-4.3/changetrack +++ changetrack-4.3/changetrack @@ -156,26 +156,26 @@ my $anyfile = 0; # flag in case we find nothing - #print "[", $filename, "] => "; - #print "{"; - #foreach my $realfile ( @files ) { - # print $realfile, " "; - #} - #print "}\n"; - foreach my $realfile ( @files ) { my @diff = (); my @ed = (); + if( "$realfile" =~ m/[\r\n\f\t<>`\$&!'"{}()\[\]\|]/ ) { + if(!$opt_q) + { print "Skipping unsafe filename '$realfile'\n";} + @diff = (@diff, "unsafe: '$realfile'\n"); + next; + } + # skip backup files not explicitly included - if((substr($realfile,-1,1) eq "~") && ($filename =~ m/\*/)) { + if((substr("$realfile",-1,1) eq "~") && ($filename =~ m/\*/)) { if(!$opt_q) { print "Skipping backup file $realfile\n";} next; } # skip directories - if(-d $realfile) { + if(-d "$realfile") { if(!$opt_q) { print "Skipping directory $realfile\n";} @diff = (@diff, "Is a directory: $realfile\n"); @@ -211,8 +211,9 @@ $fileuid = $temp[4]; # owner $filegid = $temp[5]; # group - $compfile =~ s/\//:/g; # replace '/' with ':' - $compfile =~ s/^://; # trash leading ':' + $compfile =~ s|/|:|g; # replace '/' with ':' + $compfile =~ s| |_|g; # replace ' ' with '_' + $compfile =~ s|^:||; # trash leading ':' $compfile = $historypath . $compfile; $logfile = $compfile . ".history"; # stores past events @@ -225,12 +226,12 @@ $yestfile = $compfile . ".yesterday"; # stores current data if( ! -r "$yestfile" ) { # can't open yesterday, doesn't exist. - @diff = (@diff, "New file $realfile\n"); + @diff = (@diff, "New file '$realfile'\n"); if($opt_e) { @ed = (@ed,"# cat this file into ed, eg 'cat $edfile | ed'\n"); @ed = (@ed,"# output goes into $outfile\n"); @ed = (@ed,"# edit this file to get rid of commands you don't want.\n"); - @ed = (@ed,"\n!cp $origfile $outfile\n"); + @ed = (@ed,"\n!cp \"$origfile\" $outfile\n"); @ed = (@ed,"E $outfile\n"); # keep a copy of original file @@ -243,12 +244,12 @@ printf STAT "%o\n%s\n%s\n", $filemode, $fileuid, $filegid; close(STAT); if(!$opt_r) { - `cp $realfile $compfile`; + copy($realfile,$compfile); chdir($historypath); - `co $rcs_quiet $compfile`; # hack to make rcs work. - system("rcs $rcs_quiet -i -t-'this is $realfile' $compfile"); - `rcs $rcs_quiet -U $compfile`; - `rm $compfile -f`; + `co $rcs_quiet "$compfile"`; # hack to make rcs work. + system("rcs $rcs_quiet -i -t-'this is \"$realfile\"' \"$compfile\""); + `rcs $rcs_quiet -U "$compfile"`; + `rm "$compfile -f"`; } } @@ -295,7 +296,7 @@ close(STAT); } - open(DIFF, "diff $diffargs $yestfile $realfile |") or die "Exiting: can't run diff:$!\n"; + open(DIFF, "diff $diffargs \"$yestfile\" \"$realfile\" |") or die "Exiting: can't run diff:$!\n"; if(!$opt_q) { print "$realfile";}; @@ -314,7 +315,7 @@ close(DIFF); if($diff) { - open(DIFF, "diff -e $yestfile $realfile |") or die "Can't do diff -e:$!\n"; + open(DIFF, "diff -e \"$yestfile\" \"$realfile\" |") or die "Can't do diff -e:$!\n"; # use -e to create ed commands while() { @ed = (@ed,"$_"); # get the 'ed'-styled diffs. No need to understand them. @@ -329,7 +330,7 @@ foreach $email (@emails) { # it's ok to append to things that don't exist. - $emessages{$email} .= "Changes made to $realfile follow:\n"; + $emessages{$email} .= "Changes made to '$realfile' follow:\n"; foreach my $line (@diff) { $emessages{$email} .= " $line"; } @@ -361,6 +362,7 @@ my $chmodfile = $realfile; $chmodfile =~ s|/|:|g; + $chmodfile =~ s| |_|g; $chmodfile =~ s|^:||g; # the RCS file should never be writable. chmod($filemode & 0444, "$historypath/RCS/$chmodfile,v"); @@ -384,13 +386,11 @@ if(!$opt_r) { chdir($historypath) or die "Can't chdir to $historypath for ci: $!\n"; my $quiet = ""; - print "cp $realfile $compfile\n" unless defined($opt_q); - `co $compfile`; # hack to make rcs work here too! - `cp $realfile $compfile`; # make backup copy - #`mv $realfile $realfile.track`; # copy backwards, to keep modification date - #`cp $realfile.track $realfile`; # make backup copy - system("ci $rcs_quiet -m'modification of $realfile on $date' -l $compfile"); - `rm $compfile`; + print "cp \"$realfile\" \"$compfile\"\n" unless defined($opt_q); + `co "$compfile"`; # hack to make rcs work here too! + copy($realfile,$compfile); # make backup copy + system("ci $rcs_quiet -m'modification of \"$realfile\" on $date' -l \"$compfile\""); + `rm "$compfile"`; } } } @@ -399,6 +399,7 @@ # no file was matched by 'ls', so create message for misspelled files $origfile = $filename; $filename =~ s|/|:|g; # replace each '/' by ':' + $filename =~ s| |_|g; # replace each ' ' by '_' $filename =~ s|^:||; # remove leading ':' open(LOG, ">>$historypath$filename"); print LOG "$date No files match `$origfile'\n"; @@ -521 +521,0 @@ - diff -u changetrack-4.3/debian/changelog changetrack-4.3/debian/changelog --- changetrack-4.3/debian/changelog +++ changetrack-4.3/debian/changelog @@ -1,3 +1,12 @@ +changetrack (4.3-3+etch1) oldstable-security; urgency=medium + + * Fix possible local exploit by rejecting filenames with unsafe + characters (cf. CVE-2009-3233). Thanks to Marek Grzybowski and + Andrzej Lemieszek. + (Closes: #546791) + + -- Jens Peter Secher Thu, 17 Sep 2009 22:32:43 +0200 + changetrack (4.3-3) unstable; urgency=low * Send mail via /usr/sbin/sendmail instead of Mail::Sendmail to avoid @@ -278 +286,0 @@ -