1. 22 5月, 2018 10 次提交
    • J
      verify_path: disallow symlinks in .gitmodules · 10ecfa76
      Jeff King 提交于
      There are a few reasons it's not a good idea to make
      .gitmodules a symlink, including:
      
        1. It won't be portable to systems without symlinks.
      
        2. It may behave inconsistently, since Git may look at
           this file in the index or a tree without bothering to
           resolve any symbolic links. We don't do this _yet_, but
           the config infrastructure is there and it's planned for
           the future.
      
      With some clever code, we could make (2) work. And some
      people may not care about (1) if they only work on one
      platform. But there are a few security reasons to simply
      disallow it:
      
        a. A symlinked .gitmodules file may circumvent any fsck
           checks of the content.
      
        b. Git may read and write from the on-disk file without
           sanity checking the symlink target. So for example, if
           you link ".gitmodules" to "../oops" and run "git
           submodule add", we'll write to the file "oops" outside
           the repository.
      
      Again, both of those are problems that _could_ be solved
      with sufficient code, but given the complications in (1) and
      (2), we're better off just outlawing it explicitly.
      
      Note the slightly tricky call to verify_path() in
      update-index's update_one(). There we may not have a mode if
      we're not updating from the filesystem (e.g., we might just
      be removing the file). Passing "0" as the mode there works
      fine; since it's not a symlink, we'll just skip the extra
      checks.
      Signed-off-by: NJeff King <peff@peff.net>
      10ecfa76
    • J
      update-index: stat updated files earlier · eb12dd0c
      Jeff King 提交于
      In the update_one(), we check verify_path() on the proposed
      path before doing anything else. In preparation for having
      verify_path() look at the file mode, let's stat the file
      earlier, so we can check the mode accurately.
      
      This is made a bit trickier by the fact that this function
      only does an lstat in a few code paths (the ones that flow
      down through process_path()). So we can speculatively do the
      lstat() here and pass the results down, and just use a dummy
      mode for cases where we won't actually be updating the index
      from the filesystem.
      Signed-off-by: NJeff King <peff@peff.net>
      eb12dd0c
    • J
      verify_dotfile: mention case-insensitivity in comment · 641084b6
      Jeff King 提交于
      We're more restrictive than we need to be in matching ".GIT"
      on case-sensitive filesystems; let's make a note that this
      is intentional.
      Signed-off-by: NJeff King <peff@peff.net>
      641084b6
    • J
      verify_path: drop clever fallthrough · e19e5e66
      Jeff King 提交于
      We check ".git" and ".." in the same switch statement, and
      fall through the cases to share the end-of-component check.
      While this saves us a line or two, it makes modifying the
      function much harder. Let's just write it out.
      Signed-off-by: NJeff King <peff@peff.net>
      e19e5e66
    • J
      skip_prefix: add case-insensitive variant · 41a80924
      Jeff King 提交于
      We have the convenient skip_prefix() helper, but if you want
      to do case-insensitive matching, you're stuck doing it by
      hand. We could add an extra parameter to the function to
      let callers ask for this, but the function is small and
      somewhat performance-critical. Let's just re-implement it
      for the case-insensitive version.
      Signed-off-by: NJeff King <peff@peff.net>
      41a80924
    • J
      is_{hfs,ntfs}_dotgitmodules: add tests · dc2d9ba3
      Johannes Schindelin 提交于
      This tests primarily for NTFS issues, but also adds one example of an
      HFS+ issue.
      
      Thanks go to Congyi Wu for coming up with the list of examples where
      NTFS would possibly equate the filename with `.gitmodules`.
      Signed-off-by: NJohannes Schindelin <johannes.schindelin@gmx.de>
      Signed-off-by: NJeff King <peff@peff.net>
      dc2d9ba3
    • J
      is_ntfs_dotgit: match other .git files · e7cb0b44
      Johannes Schindelin 提交于
      When we started to catch NTFS short names that clash with .git, we only
      looked for GIT~1. This is sufficient because we only ever clone into an
      empty directory, so .git is guaranteed to be the first subdirectory or
      file in that directory.
      
      However, even with a fresh clone, .gitmodules is *not* necessarily the
      first file to be written that would want the NTFS short name GITMOD~1: a
      malicious repository can add .gitmodul0000 and friends, which sorts
      before `.gitmodules` and is therefore checked out *first*. For that
      reason, we have to test not only for ~1 short names, but for others,
      too.
      
      It's hard to just adapt the existing checks in is_ntfs_dotgit(): since
      Windows 2000 (i.e., in all Windows versions still supported by Git),
      NTFS short names are only generated in the <prefix>~<number> form up to
      number 4. After that, a *different* prefix is used, calculated from the
      long file name using an undocumented, but stable algorithm.
      
      For example, the short name of .gitmodules would be GITMOD~1, but if it
      is taken, and all of ~2, ~3 and ~4 are taken, too, the short name
      GI7EBA~1 will be used. From there, collisions are handled by
      incrementing the number, shortening the prefix as needed (until ~9999999
      is reached, in which case NTFS will not allow the file to be created).
      
      We'd also want to handle .gitignore and .gitattributes, which suffer
      from a similar problem, using the fall-back short names GI250A~1 and
      GI7D29~1, respectively.
      
      To accommodate for that, we could reimplement the hashing algorithm, but
      it is just safer and simpler to provide the known prefixes. This
      algorithm has been reverse-engineered and described at
      https://usn.pw/blog/gen/2015/06/09/filenames/, which is defunct but
      still available via https://web.archive.org/.
      
      These can be recomputed by running the following Perl script:
      
      -- snip --
      use warnings;
      use strict;
      
      sub compute_short_name_hash ($) {
              my $checksum = 0;
              foreach (split('', $_[0])) {
                      $checksum = ($checksum * 0x25 + ord($_)) & 0xffff;
              }
      
              $checksum = ($checksum * 314159269) & 0xffffffff;
              $checksum = 1 + (~$checksum & 0x7fffffff) if ($checksum & 0x80000000);
              $checksum -= (($checksum * 1152921497) >> 60) * 1000000007;
      
              return scalar reverse sprintf("%x", $checksum & 0xffff);
      }
      
      print compute_short_name_hash($ARGV[0]);
      -- snap --
      
      E.g., running that with the argument ".gitignore" will
      result in "250a" (which then becomes "gi250a" in the code).
      Signed-off-by: NJohannes Schindelin <johannes.schindelin@gmx.de>
      Signed-off-by: NJeff King <peff@peff.net>
      e7cb0b44
    • J
      is_hfs_dotgit: match other .git files · 0fc333ba
      Jeff King 提交于
      Both verify_path() and fsck match ".git", ".GIT", and other
      variants specific to HFS+. Let's allow matching other
      special files like ".gitmodules", which we'll later use to
      enforce extra restrictions via verify_path() and fsck.
      Signed-off-by: NJeff King <peff@peff.net>
      0fc333ba
    • J
      is_ntfs_dotgit: use a size_t for traversing string · 11a9f4d8
      Jeff King 提交于
      We walk through the "name" string using an int, which can
      wrap to a negative value and cause us to read random memory
      before our array (e.g., by creating a tree with a name >2GB,
      since "int" is still 32 bits even on most 64-bit platforms).
      Worse, this is easy to trigger during the fsck_tree() check,
      which is supposed to be protecting us from malicious
      garbage.
      
      Note one bit of trickiness in the existing code: we
      sometimes assign -1 to "len" at the end of the loop, and
      then rely on the "len++" in the for-loop's increment to take
      it back to 0. This is still legal with a size_t, since
      assigning -1 will turn into SIZE_MAX, which then wraps
      around to 0 on increment.
      Signed-off-by: NJeff King <peff@peff.net>
      11a9f4d8
    • J
      submodule-config: verify submodule names as paths · 0383bbb9
      Jeff King 提交于
      Submodule "names" come from the untrusted .gitmodules file,
      but we blindly append them to $GIT_DIR/modules to create our
      on-disk repo paths. This means you can do bad things by
      putting "../" into the name (among other things).
      
      Let's sanity-check these names to avoid building a path that
      can be exploited. There are two main decisions:
      
        1. What should the allowed syntax be?
      
           It's tempting to reuse verify_path(), since submodule
           names typically come from in-repo paths. But there are
           two reasons not to:
      
             a. It's technically more strict than what we need, as
                we really care only about breaking out of the
                $GIT_DIR/modules/ hierarchy.  E.g., having a
                submodule named "foo/.git" isn't actually
                dangerous, and it's possible that somebody has
                manually given such a funny name.
      
             b. Since we'll eventually use this checking logic in
                fsck to prevent downstream repositories, it should
                be consistent across platforms. Because
                verify_path() relies on is_dir_sep(), it wouldn't
                block "foo\..\bar" on a non-Windows machine.
      
        2. Where should we enforce it? These days most of the
           .gitmodules reads go through submodule-config.c, so
           I've put it there in the reading step. That should
           cover all of the C code.
      
           We also construct the name for "git submodule add"
           inside the git-submodule.sh script. This is probably
           not a big deal for security since the name is coming
           from the user anyway, but it would be polite to remind
           them if the name they pick is invalid (and we need to
           expose the name-checker to the shell anyway for our
           test scripts).
      
           This patch issues a warning when reading .gitmodules
           and just ignores the related config entry completely.
           This will generally end up producing a sensible error,
           as it works the same as a .gitmodules file which is
           missing a submodule entry (so "submodule update" will
           barf, but "git clone --recurse-submodules" will print
           an error but not abort the clone.
      
           There is one minor oddity, which is that we print the
           warning once per malformed config key (since that's how
           the config subsystem gives us the entries). So in the
           new test, for example, the user would see three
           warnings. That's OK, since the intent is that this case
           should never come up outside of malicious repositories
           (and then it might even benefit the user to see the
           message multiple times).
      
      Credit for finding this vulnerability and the proof of
      concept from which the test script was adapted goes to
      Etienne Stalmans.
      Signed-off-by: NJeff King <peff@peff.net>
      0383bbb9
  2. 22 9月, 2017 11 次提交
  3. 12 9月, 2017 3 次提交
    • J
      cvsimport: shell-quote variable used in backticks · 5b4efea6
      Jeff King 提交于
      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: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      5b4efea6
    • J
      archimport: use safe_pipe_capture for user input · 8d0fad0a
      Jeff King 提交于
      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: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      8d0fad0a
    • J
      shell: drop git-cvsserver support by default · 9a42c03c
      Jeff King 提交于
      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: NJeff King <peff@peff.net>
      Signed-off-by: NJunio C Hamano <gitster@pobox.com>
      9a42c03c
  4. 11 9月, 2017 3 次提交
  5. 02 8月, 2017 3 次提交
  6. 01 8月, 2017 9 次提交
  7. 31 7月, 2017 1 次提交