Public bug reported:

Release: Ubuntu 20.04.6 LTS (focal)
Package: git 1:2.25.1-1ubuntu3.14
Introduced in: 1:2.25.1-1ubuntu3.12 (USN-6793-1), which adds 
debian/patches/CVE-2024-32465.patch

In a partial clone whose HEAD tree has not been fetched, `git sparse-
checkout set` segfaults when GIT_NO_LAZY_FETCH=1.

The segfault skips git's lock file cleanup, so later `git sparse-
checkout` commands in the same repository fail with "Unable to create
'.../.git/info/sparse-checkout.lock': File exists".

Real-world impact: the Claude Code plugin installer (version 2.1.274 and
later) sets GIT_NO_LAZY_FETCH=1 when it clones plugin sources. For
plugins in a git subdirectory, it clones with --filter=tree:0 and then
runs `git sparse-checkout set --cone`. If that step fails, the installer
retries it with GIT_NO_LAZY_FETCH=0. On focal the first attempt
segfaults, and the retry fails on the stale lock.

Steps to reproduce on focal with git 1:2.25.1-1ubuntu3.14 installed:

    git clone -q --depth 1 --filter=tree:0 --no-checkout 
https://github.com/octocat/Hello-World.git repo
    cd repo
    GIT_NO_LAZY_FETCH=1 git sparse-checkout set --cone -- somedir
    # warning: lazy fetching disabled; some objects may not be available
    # Segmentation fault (exit 139)
    ls .git/info/sparse-checkout.lock
    # the lock file is still there

The attached repro.sh reproduces the issue without depending on an
installed git.

Expected: a fatal error, a nonzero exit, and no lock file left behind.

Cause:

CVE-2024-32465.patch is a backport of upstream 7b70e9efb18c ("upload-
pack: disable lazy-fetching by default"). It makes fetch_objects() in
promisor-remote.c return -1 when GIT_NO_LAZY_FETCH is set.
builtin/sparse-checkout.c:update_working_directory() in 2.25.1 does not
check the result of parse_tree_indirect():

    tree = parse_tree_indirect(&oid);
    parse_tree(tree);
    init_tree_desc(&t, tree->buffer, tree->size);

With the patch, a missing HEAD tree now comes back as NULL, and
parse_tree(NULL) dereferences it. AddressSanitizer trace from the
1:2.25.1-1ubuntu3.14 source package with all patches in
debian/patches/series applied, built with -g -O0 -fsanitize=address:

    warning: lazy fetching disabled; some objects may not be available
    ==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000
    The signal is caused by a READ memory access.
        #0 parse_tree_gently tree.c:223
        #1 parse_tree tree.h:24
        #2 update_working_directory builtin/sparse-checkout.c:109
        #3 write_patterns_and_update builtin/sparse-checkout.c:205
        #4 sparse_checkout_set builtin/sparse-checkout.c:452
        #5 cmd_sparse_checkout builtin/sparse-checkout.c:509

Upstream is not affected because f56f31af0301 ("sparse-checkout: use new
update_sparsity() function", v2.27.0) removed this code path. Upstream
v2.39.4 is the oldest upstream release that carries 7b70e9efb18c, and
does not exhibit the problem.

Suggested fix:

    --- a/builtin/sparse-checkout.c
    +++ b/builtin/sparse-checkout.c
    @@ -106,6 +106,8 @@
                return 0;
     
        tree = parse_tree_indirect(&oid);
    +   if (!tree)
    +           die(_("unable to read tree of HEAD"));
        parse_tree(tree);
        init_tree_desc(&t, tree->buffer, tree->size);
     

Building 1:2.25.1-1ubuntu3.14 with this change, the reproducer exits 128
and leaves no lock file. The Claude Code installer described above also
succeeds with this build.

A Claude Code user reports a similar segfault on jammy (git
1:2.34.1-1ubuntu1.17), in `git checkout HEAD` with GIT_NO_LAZY_FETCH=1.
It also leaves a stale .git/index.lock:
https://github.com/anthropics/claude-code/issues/98629. I have not
reproduced that.

** Affects: git (Ubuntu)
     Importance: Undecided
         Status: New

** Attachment added: "repro.sh"
   https://bugs.launchpad.net/bugs/2170889/+attachment/6009273/+files/repro.sh

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2170889

Title:
  CVE-2024-32465 regression: git sparse-checkout segfaults and leaves a
  stale lock when GIT_NO_LAZY_FETCH=1

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/git/+bug/2170889/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to