1. 29 May, 2018 2 commits
  2. 10 Mar, 2018 3 commits
    • index: error out on unreasonable prefix-compressed path lengths · 3db1af1f
      When computing the complete path length from the encoded
      prefix-compressed path, we end up just allocating the complete path
      without ever checking what the encoded path length actually is. This can
      easily lead to a denial of service by just encoding an unreasonable long
      path name inside of the index. Git already enforces a maximum path
      length of 4096 bytes. As we also have that enforcement ready in some
      places, just make sure that the resulting path is smaller than
      GIT_PATH_MAX.
      
      Reported-by: Krishna Ram Prakash R <krp@gtux.in>
      Reported-by: Vivek Parikh <viv0411.parikh@gmail.com>
      Patrick Steinhardt committed
    • index: fix out-of-bounds read with invalid index entry prefix length · 3207ddb0
      The index format in version 4 has prefix-compressed entries, where every
      index entry can compress its path by using a path prefix of the previous
      entry. Since implmenting support for this index format version in commit
      5625d86b (index: support index v4, 2016-05-17), though, we do not
      correctly verify that the prefix length that we want to reuse is
      actually smaller or equal to the amount of characters than the length of
      the previous index entry's path. This can lead to a an integer underflow
      and subsequently to an out-of-bounds read.
      
      Fix this by verifying that the prefix is actually smaller than the
      previous entry's path length.
      
      Reported-by: Krishna Ram Prakash R <krp@gtux.in>
      Reported-by: Vivek Parikh <viv0411.parikh@gmail.com>
      Patrick Steinhardt committed
    • index: convert `read_entry` to return entry size via an out-param · 58a6fe94
      The function `read_entry` does not conform to our usual coding style of
      returning stuff via the out parameter and to use the return value for
      reporting errors. Due to most of our code conforming to that pattern, it
      has become quite natural for us to actually return `-1` in case there is
      any error, which has also slipped in with commit 5625d86b (index:
      support index v4, 2016-05-17). As the function returns an `size_t` only,
      though, the return value is wrapped around, causing the caller of
      `read_tree` to continue with an invalid index entry. Ultimately, this
      can lead to a double-free.
      
      Improve code and fix the bug by converting the function to return the
      index entry size via an out parameter and only using the return value to
      indicate errors.
      
      Reported-by: Krishna Ram Prakash R <krp@gtux.in>
      Reported-by: Vivek Parikh <viv0411.parikh@gmail.com>
      Patrick Steinhardt committed
  3. 18 Feb, 2018 1 commit
  4. 16 Feb, 2018 1 commit
  5. 03 Jul, 2017 1 commit
    • Make sure to always include "common.h" first · 0c7f49dd
      Next to including several files, our "common.h" header also declares
      various macros which are then used throughout the project. As such, we
      have to make sure to always include this file first in all
      implementation files. Otherwise, we might encounter problems or even
      silent behavioural differences due to macros or defines not being
      defined as they should be. So in fact, our header and implementation
      files should make sure to always include "common.h" first.
      
      This commit does so by establishing a common include pattern. Header
      files inside of "src" will now always include "common.h" as its first
      other file, separated by a newline from all the other includes to make
      it stand out as special. There are two cases for the implementation
      files. If they do have a matching header file, they will always include
      this one first, leading to "common.h" being transitively included as
      first file. If they do not have a matching header file, they instead
      include "common.h" as first file themselves.
      
      This fixes the outlined problems and will become our standard practice
      for header and source files inside of the "src/" from now on.
      Patrick Steinhardt committed
  6. 06 Jun, 2017 9 commits
    • index: verify we have enough space left when writing index entries · 064a60e9
      In our code writing index entries, we carry around a `disk_size`
      representing how much memory we have in total and pass this value to
      `git_encode_varint` to do bounds checks. This does not make much sense,
      as at the time when passing on this variable it is already out of date.
      Fix this by subtracting used memory from `disk_size` as we go along.
      Furthermore, assert we've actually got enough space left to do the final
      path memcpy.
      Patrick Steinhardt committed
    • index: fix shared prefix computation when writing index entry · c71dff7e
      When using compressed index entries, each entry's path is preceded by a
      varint encoding how long the shared prefix with the previous index entry
      actually is. We currently encode a length of `(path_len - same_len)`,
      which is doubly wrong. First, `path_len` is already set to `path_len -
      same_len` previously. Second, we want to encode the shared prefix rather
      than the un-shared suffix length.
      
      Fix this by using `same_len` as the varint value instead.
      Patrick Steinhardt committed
    • index: also sanity check entry size with compressed entries · 83e0392c
      We have a check in place whether the index has enough data left for the
      required footer after reading an index entry, but this was only used for
      uncompressed entries. Move the check down a bit so that it is executed
      for both compressed and uncompressed index entries.
      Patrick Steinhardt committed
    • index: remove file-scope entry size macros · 350d2c47
      All index entry size computations are now performed in
      `index_entry_size`. As such, we do not need the file-scope macros for
      computing these sizes anymore. Remove them and move the `entry_size`
      macro into the `index_entry_size` function.
      Patrick Steinhardt committed
    • index: don't right-pad paths when writing compressed entries · 46b67034
      Our code to write index entries to disk does not check whether the
      entry that is to be written should use prefix compression for the path.
      As such, we were overallocating memory and added bogus right-padding
      into the resulting index entries. As there is no padding allowed in the
      index version 4 format, this should actually result in an invalid index.
      
      Fix this by re-using the newly extracted `index_entry_size` function.
      Patrick Steinhardt committed
    • index: move index entry size computation into its own function · 29f498e0
      Create a new function `index_entry_size` which encapsulates the logic to
      calculate how much space is needed for an index entry, whether it is
      simple/extended or compressed/uncompressed. This can later be re-used by
      our code writing index entries.
      Patrick Steinhardt committed
    • index: set last written index entry in foreach-entry-loop · 8ceb890b
      The last written disk entry is currently being written inside of the
      function `write_disk_entry`. Make behavior a bit more obviously by
      instead setting it inside of `write_entries` while iterating all
      entries.
      Patrick Steinhardt committed
    • index: set last entry when reading compressed entries · 11d0be23
      To calculate the path of a compressed index entry, we need to know the
      preceding entry's path. While we do actually set the first predecessor
      correctly to "", we fail to update this while reading the entries.
      
      Fix the issue by updating `last` inside of the loop. Previously, we've
      been passing a double-pointer to `read_entry`, which it didn't update.
      As it is more obvious to update the pointer inside the loop itself,
      though, we can simply convert it to a normal pointer.
      Patrick Steinhardt committed
    • index: fix confusion with shared prefix in compressed path names · febe8c14
      The index version 4 introduced compressed path names for the entries.
      From the git.git index-format documentation:
      
          At the beginning of an entry, an integer N in the variable width
          encoding [...] is stored, followed by a NUL-terminated string S.
          Removing N bytes from the end of the path name for the previous
          entry, and replacing it with the string S yields the path name for
          this entry.
      
      But instead of stripping N bytes from the previous path's string and
      using the remaining prefix, we were instead simply concatenating the
      previous path with the current entry path, which is obviously wrong.
      
      Fix the issue by correctly copying the first N bytes of the previous
      entry only and concatenating the result with our current entry's path.
      Patrick Steinhardt committed
  7. 17 Feb, 2017 3 commits
  8. 29 Dec, 2016 1 commit
  9. 16 Nov, 2016 1 commit
    • use `giterr_set_str()` wherever possible · 65b78ea3
      `giterr_set()` is used when it is required to format a string, and since
      we don't really require it for this case, it is better to stick to
      `giterr_set_str()`.
      
      This also suppresses a warning(-Wformat-security) raised by the compiler.
      
      Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>
      Pranit Bauva committed
  10. 10 Aug, 2016 1 commit
    • index: support index v4 · 5625d86b
      Support reading and writing index v4.  Index v4 uses a very simple
      compression scheme for pathnames, but is otherwise similar to index v3.
      
      Signed-off-by: David Turner <dturner@twitter.com>
      David Turner committed
  11. 24 Jul, 2016 1 commit
  12. 29 Jun, 2016 2 commits
  13. 07 Jun, 2016 1 commit
    • index: fix NULL pointer access in index_remove_entry · 13deb874
      When removing an entry from the index by its position, we first
      retrieve the position from the index's entries and then try to
      remove the retrieved value from the index map with
      `DELETE_IN_MAP`. When `index_remove_entry` returns `NULL` we try
      to feed it into the `DELETE_IN_MAP` macro, which will
      unconditionally call `idxentry_hash` and then happily dereference
      the `NULL` entry pointer.
      
      Fix the issue by not passing a `NULL` entry into `DELETE_IN_MAP`.
      Patrick Steinhardt committed
  14. 02 Jun, 2016 4 commits
  15. 02 May, 2016 1 commit
  16. 20 Mar, 2016 1 commit
  17. 11 Mar, 2016 1 commit
  18. 28 Feb, 2016 1 commit
  19. 25 Feb, 2016 1 commit
    • nsec: support NDK's crazy nanoseconds · 3d6a42d1
      Android NDK does not have a `struct timespec` in its `struct stat`
      for nanosecond support, instead it has a single nanosecond member inside
      the struct stat itself.  We will use that and use a macro to expand to
      the `st_mtim` / `st_mtimespec` definition on other systems (much like
      the existing `st_mtime` backcompat definition).
      Edward Thomson committed
  20. 23 Feb, 2016 2 commits
    • index: fix contradicting comparison · 0f1e2d20
      The overflow check in `read_reuc` tries to verify if the
      `git__strtol32` parses an integer bigger than UINT_MAX. The `tmp`
      variable is casted to an unsigned int for this and then checked
      for being greater than UINT_MAX, which obviously can never be
      true.
      
      Fix this by instead fixing the `mode` field's size in `struct
      git_index_reuc_entry` to `uint32_t`. We can now parse the int
      with `git__strtol64`, which can never return a value bigger than
      `UINT32_MAX`, and additionally checking if the returned value is
      smaller than zero.
      
      We do not need to handle overflows explicitly here, as
      `git__strtol64` returns an error when the returned value would
      overflow.
      Patrick Steinhardt committed
  21. 17 Feb, 2016 1 commit
    • index: allow read of index w/ illegal entries · 318b825e
      Allow `git_index_read` to handle reading existing indexes with
      illegal entries.  Allow the low-level `git_index_add` to add
      properly formed `git_index_entry`s even if they contain paths
      that would be illegal for the current filesystem (eg, `AUX`).
      Continue to disallow `git_index_add_bypath` from adding entries
      that are illegal universally illegal (eg, `.git`, `foo/../bar`).
      Edward Thomson committed
  22. 16 Feb, 2016 1 commit