Understanding Git releases with critical CVE-2022-23521 and CVE-2022-41903

Understanding Git releases with critical CVE-2022-23521 and CVE-2022-41903

git_vulnerabilities

Here in this article we will try to explore on the recent critical vulnerabilities CVE-2022-23521 and CVE-2022-41903 that were disclosed in the Git distributed version control system software. We will try to understand about these vulnerabilities and see how they can impact in our environments.

These CVE’s were actually an outcome of the security audit that was carried out by X41 D-Sec GmbH on the git version control source code. This test was sponsored and organized by Open Source Technology Improvement Fund.

If you are interested in watching the video. Here is the YouTube video on the same step by step procedure outlined below.

Let’s get started.

So, these are the two recent CVE’s that were recently disclosed in the Git distributed version control system.

CVEDescription
CVE-2022-41903Heap overflow in git archive, git log --format leading to RCE
CVE-2022-23521gitattributes parsing integer overflow

Before getting into the details of the CVE, let us try to understand about the git utilities and some important terminology that actually exposed these vulnerabilities.

Git Utilities and Terminologies

Git archive

git archive is a command line utility provided by git to create a archive of files from a named tree. Some of the format that are supported are tar, zip, tar.gz, tgz. If no format specifier is provided the format is inferred from the output filename if possible. Otherwise the output format is tar.

git archive behaves differently when given a tree ID versus when given a commit ID or tag ID. In the first case the current time is used as the modification time of each file in the archive. In the latter case the commit time as recorded in the referenced commit object is used instead.

Git log

git log is a command line utility provided by git which has the ability to display commits using an arbitrary format with its –format specifiers. This format specifier functionality is the same functionality that is also exposed to git archive via the export-subst gitattribute.

Gitattributes

Git configuration settings can also be specified for a path, so that Git applies those settings only for a subdirectory or subset of files.

These path-specific settings are called Git attributes and are set either in a .gitattributes file in one of your directories (normally the root of your project) or in the .git/info/attributes file if you don’t want the attributes file committed with your project.

eg. To tell Git to treat all pbxproj files as binary data, add the following line to your .gitattributes file

*.pbxproj binary

Integer Overflow

An integer overflow occurs when you attempt to store inside an integer variable a value that is larger than the maximum value the variable can hold. The C standard defines this situation as undefined behavior (meaning that anything might happen). In practice, this usually translates to a wrap of the value if an unsigned integer was used and a change of the sign and value if a signed integer was used.

This is a typical scenario in integer overflow issues and it usually leads to other vulnerabilities, such as heap overflows, if later in the code the original value is used as a loop guard to populate the (now too small) allocated space.

source credit

Now that we have some understanding on the terminologies used in the reported CVE’s, let’s try to get into the details of CVE.

GIT Critical CVE’s

CVE-2022-41903 – Heap overflow in git archive, git log --format leading to RCE

git log has the ability to display commits using an arbitrary format with its –format specifiers. This functionality is also exposed to git archive via the export-subst gitattribute.

When processing the padding operators (e.g., %<(, %<|(, %>(, %>>(, or %><( ), an integer overflow can occur in pretty.c::format_and_pad_commit() where a size_t is improperly stored as an int, and then added as an offset to a subsequent memcpy() call.

This overflow can be triggered directly by a user running a command which invokes the commit formatting machinery (e.g., git log –format=…). It may also be triggered indirectly through git archive via the export-subst mechanism, which expands format specifiers inside of files within the repository during a git archive.

This integer overflow can result in arbitrary heap writes, which may result in remote code execution.

NOTE: When writing C code we should always use size_t whenever dealing with memory ranges. The int type on the other hand is basically defined as the size of the (signed) integer value that the host machine can use to most efficiently perform integer arithmetic.

Let’s take a look at a scenario in which we have a vulnerable git version running.

gitadmin@gitserver:~$ git --version
git version 2.25.1

Now, lets try to run the following git log command line utility with a specifically crafted format string which ideally lead us into a situation of out of memory issue as captured in the system logs in the linux system.

gitadmin@gitserver:~/stack/kubestuff$ /usr/bin/git log -2 --pretty='format:%>(2147483646)2147483646$$$%%%%2147483646$%>' > /dev/null
Killed

This crafted formatted string is also a part of the audit conducted by X41 D-Sec GmbH. All credit to them, i am just trying to simulate it in my environment.

Important to Note

2^31 = 2147483646

As you can see from the below system logs, that even though i had enough memory it actually killed one of my process with an Out of memory exception because of incorrect handling of the type in the git software.

Error – /var/log/syslog

Feb 15 17:09:24 gitserver kernel: [ 3525.979839] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/system.slice/gitlab-runsvdir.service,task=bundle,pid=7888,uid=997
Feb 15 17:09:24 gitserver kernel: [ 3525.979980] Out of memory: Killed process 7888 (bundle) total-vm:1896696kB, anon-rss:1135268kB, file-rss:0kB, shmem-rss:924kB, UID:997 pgtables:3316kB oom_score_adj:0
Feb 15 17:09:24 gitserver kernel: [ 3526.041053] oom_reaper: reaped process 7888 (bundle), now anon-rss:0kB, file-rss:0kB, shmem-rss:944kB
Feb 15 17:09:25 gitserver kernel: [ 3526.495780] thread_pool.rb* invoked oom-killer: gfp_mask=0x100cca(GFP_HIGHUSER_MOVABLE), order=0, oom_score_adj=0
Feb 15 17:09:25 gitserver kernel: [ 3526.495788] CPU: 1 PID: 8360 Comm: thread_pool.rb* Not tainted 5.13.0-52-generic #59~20.04.1-Ubuntu
Feb 15 17:09:25 gitserver kernel: [ 3526.495792] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.1-2.fc37 04/01/2014
Feb 15 17:09:25 gitserver kernel: [ 3526.495794] Call Trace:
Feb 15 17:09:25 gitserver kernel: [ 3526.495796]  <TASK>
Feb 15 17:09:25 gitserver kernel: [ 3526.495798]  dump_stack+0x7d/0x9c

The most complete workaround is upgrading to the most recent patched version published.

If doing so is impractical, disable git archive in untrusted repositories. If you expose git archive via git daemon, disable it by running git config –global daemon.uploadArch false. If you do not, avoid running git archive directly on untrusted repositories.

Credit
Credit for finding this vulnerability goes to Joern Schneeweisz of GitLab. An early patch was authored by Markus Vervier of X41 D-Sec. Both of their work was on behalf of the OSTIF. The patches that appear in the releases have further been polished and extended by Patrick Steinhardt of GitLab.

CVE-2022-23521 – gitattributes parsing integer overflow

gitattributes are a mechanism to allow defining attributes for paths. These attributes can be defined by adding a .gitattributes file to the repository, which contains a set of file patterns and the attributes that should be set for paths matching this pattern.

When parsing gitattributes, multiple integer overflows can occur when there is a huge number of path patterns, a huge number of attributes for a single pattern, or when the declared attribute names are huge.

These overflows can be triggered via a crafted .gitattributes file that may be part of the commit history. Git silently splits lines longer than 2KB when parsing gitattributes from a file, but not when parsing them from the index. Consequentially, the failure mode depends on whether the file exists in the working tree, the index or both.

This integer overflow can result in arbitrary heap reads and writes, which may result in remote code execution.

The most complete workaround is upgrading to the most recent patched version published.

Credit

Credit for finding this vulnerability goes to Markus Vervier and Eric Sesterhenn of X41 D-Sec. This work was sponsored by OSTIF. Fixes were written by Patrick Steinhardt of GitLab with help from others on the Git security mailing list.

As of this writing the latest version of git that have these vulnerabilities fixed are below.

>= v2.30.7, v2.31.6, v2.32.5, v2.33.6, v2.34.6, v2.35.6, v2.36.4, v2.37.5, v2.38.3, v2.39.1

Hope you enjoyed reading this article. Thank you..