Bug#744817: clang-3.5: scan-build: insecure use of /tmp

Jakub Wilk jwilk at debian.org
Mon Apr 14 22:13:23 UTC 2014


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



More information about the Pkg-llvm-team mailing list