Package: clang-3.5
Version: 1:3.5~svn201651-1
Severity: important
Tags: security
The GetHTMLRunDir subroutine creates temporary directories in an
insecure way:
1) The directory name is easily predictable:
if (!defined $Dir) {
$Dir = $ENV{'TMPDIR'} || $ENV{'TEMP'} || $ENV{'TMP'} || "/tmp";
$TmpMode = 1;
}
# [...]
my $TimeString = sprintf("%02d%02d%02d", $hour, $min, $sec);
my $DateString = sprintf("%d-%02d-%02d-%s-$$",
$year, $month, $day, $TimeString);
# [...]
if ($TmpMode) {
$NewDir = "$Dir/$Prog-$DateString-$RunNumber";
}
2) The directory is created with default permissions (instead of 0700).
3) The function doesn't fail if the directory already exists, even if
it's owned by another user. Now, the upstream intention was to always
choose a directory that doesn't exist, but the logic is broken:
foreach my $f (@FILES) {
# Strip the prefix '$Prog-' if we are dumping files to /tmp.
if ($TmpMode) {
next if (!($f =~ /^$Prog-(.+)/));
$f = $1;
}
my @x = split/-/, $f;
next if (scalar(@x) != 4);
next if ($x[0] != $year);
next if ($x[1] != $month);
next if ($x[2] != $day);
next if ($x[3] != $TimeString);
next if ($x[4] != $$);
if ($x[5] > $max) {
$max = $x[5];
}
}
$RunNumber = $max + 1;
But, for files that could be created by GetHTMLRunDir, scalar(@x) is 6,
not 4, so the loop is mostly no-op. (Even if the loop was implemented
correctly, there would still be race window between when the directory
name is chosen and when it is created.)
This bug can be exploited by malicious local user for denial of service,
information disclosure, or to overwrite arbitrary files via symlink
attack.
--
Jakub Wilk