Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport "untracked cache: fix off-by-one" #2182

Merged
merged 1 commit into from
May 7, 2019

Conversation

dscho
Copy link
Member

@dscho dscho commented May 6, 2019

This one made it already into core Git's master, but we cannot merge it as-is because it is ahead of Git for Windows' current master by more than just one commit. So let's cherry-pick it.

In f9e6c64 (untracked cache: load from UNTR index extension,
2015-03-08), code was added to read back the untracked cache from an
index extension.

Probably in the endeavor to avoid the `calloc()` implied by
`FLEX_ALLOC_STR()` (it is hard to know why exactly, the commit message
of that commit is a bit parsimonious with information), it calls
`malloc()` manually and then `memcpy()`s the bits and pieces into place.

It allocates the size of `struct untracked_cache_dir` plus the string
length of the untracked file name, then copies the information in two
steps: first the fixed-size metadata, then the name. And here lies the
rub: it includes the trailing NUL byte in the name.

If `FLEX_ARRAY` is defined as 0, this results in a buffer overrun.

To fix this, let's just add 1, for the trailing NUL byte. Technically,
this overallocates on platforms where `FLEX_ARRAY` is 1, but it should
not matter much in reality, as `malloc()` usually overallocates anyway,
unless the size to allocate aligns exactly with some internal chunk size
(see below for more on that).

The real strange thing is that neither valgrind nor DrMemory catches
this bug. In this developer's tests, a `memcpy()` (but not a
`memset()`!) could write up to 4 bytes after the allocated memory range
before valgrind would start reporting an issue.

However, when running Git built with nedmalloc as allocator, under rare
conditions (and inconsistently at that), this bug triggered an `abort()`
because nedmalloc rounds up the size to be `malloc()`ed to a multiple of
a certain chunk size, then adds a few bytes to be used for storing some
internal state. If there is no rounding up to do (because the size is
already a multiple of that chunk size), and if the buffer is overrun as
in the code patched in this commit, the internal state is corrupted.

The scenario that triggered this here bug fix entailed a git.git
checkout with an extra copy of the source code in an untracked
subdirectory, meaning that there was an untracked subdirectory called
"thunderbird-patch-inline" whose name's length is exactly 24 bytes,
which, added to the size of above-mentioned `struct untracked_cache_dir`
that weighs in with 104 bytes on a 64-bit system, amounts to 128,
aligning perfectly with nedmalloc's chunk size.

As there is no obvious way to trigger this bug reliably, on all
platforms supported by Git, and as the bug is obvious enough, this patch
comes without a regression test.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
@dscho dscho merged commit c63a3d5 into git-for-windows:master May 7, 2019
@dscho dscho added this to the v2.21.0(2) milestone May 7, 2019
@dscho dscho deleted the untracked-cache-off-by-one branch May 7, 2019 13:17
dscho added a commit that referenced this pull request May 7, 2019
Backport "untracked cache: fix off-by-one"
git-for-windows-ci pushed a commit that referenced this pull request May 8, 2019
Backport "untracked cache: fix off-by-one"
dscho added a commit to git-for-windows/build-extra that referenced this pull request May 9, 2019
A bug which on occasion caused lengthy rebase
runs to crash without error message [was
fixed](git-for-windows/git#2182).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
git-for-windows-ci pushed a commit that referenced this pull request May 9, 2019
Backport "untracked cache: fix off-by-one"
git-for-windows-ci pushed a commit that referenced this pull request May 10, 2019
Backport "untracked cache: fix off-by-one"
dscho added a commit to dscho/git that referenced this pull request May 13, 2019
…f-by-one

Backport "untracked cache: fix off-by-one"
git-for-windows-ci pushed a commit that referenced this pull request May 14, 2019
Backport "untracked cache: fix off-by-one"
dscho added a commit that referenced this pull request May 21, 2019
Backport "untracked cache: fix off-by-one"
dscho added a commit that referenced this pull request May 22, 2019
Backport "untracked cache: fix off-by-one"
dscho added a commit that referenced this pull request May 25, 2019
Backport "untracked cache: fix off-by-one"
dscho added a commit that referenced this pull request Jun 4, 2019
Backport "untracked cache: fix off-by-one"
dscho added a commit that referenced this pull request Jun 8, 2019
Backport "untracked cache: fix off-by-one"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant