Multiple Vulnerabilities in Git

We discussed this vulnerability during Episode 182 on 24 January 2023

Multiple vulnerabilities were announced in Git, the most interesting to me though are the integer overflows in parsing .gitattributes leading to out-of-bounds reads and writes.

First, the uninteresting. CVE-2022-41953, Git GUI on windows as part of post-processing on a checkout will run a spell-checker if available. It will search for this spell-check tool inside the worktree that was just checked out.

CVE-2022-41903 - Integer Overflow in Padding Operators This is described as multiple integer overflows can occur when processing a padding operator as part of the “pretty-formats” which are exposed directly in the git log --format option. But can be accessed through other commands also that perform pretty prettying such as git archive. Looking at the commits however, most of the fixed issues are indeed integer overflows but the out of bounds reads are other issues.

The first of these out-of-bounds reads is when left-flushing, to do this the code needs to look ahead and see if there are any spaces to be “stolen.” It loops over the string skipping ahead until it finds the first space, it does not respect the buffer’s boundary while doing so.

The second out-of-bounds read is a little more interesting as it has to do with an incomplete update to the code that happened. Prior to supporting truncation in the padding operators the end of the string would be found using strchr, which would return NULL if the character in question wasn’t found. Adding support for truncation they also added support for other characters to mark the end, so they used strcspn which returns the offset in the string to the first character in the selection set, or if none were found, to the NULL at the end of the string. The conditional following this was not updated to reflect the change in return, it continued to look if the value was NULL rather than the value it pointed to being NULL. This mistake results in the end of the token being incorrectly calculated and returned, leading to reading out of bounds later after this function returned.

The out of bounds write in pretty formatting was an integer overflow issue. The struct strbuf would track length using a size_t but the code on line 1554 would read the sb->len into an integer value leading to a potentially incorrect memcpy shortly there after.

There were several more integer overflows patched in this area, but these three were the most interesting to look at from an exploitation perspective.

CVE-2022-23521 - Multiple Integer Overflows while processing .gitattributes

Again, multiple issues were fixed, but two are interesting to me

The first can result in an out-of-bounds write. This happens when you have too many attribute names present. It can result in a crash just because the xcalloc call tries to allocate too much memory, but if you provide enough attributes so that the value wraps back to 0 rather than stopping when it goes negative. The xcalloc on line 384 will allocate too little space for the data written into the buffer a few lines later.

The second is an out-of-bounds read and provides a kinda fun primitive. In attr_stack_free (starting on L448), the problem is that struct attr_stack->num_matches is an unsigned value, but the loop iterator i is a signed int. With a sufficently large num_matches the iterator will go negative, resulting in trying to read before the attr array, and then a call to free with the value that was read. There is potential for a use-after-free if there are other threads running (I’m not sure if there are), but this is basically an infinite free loop as the loop will never terminate since i cannot be greataer than the num_matches value.