8000 git_repository_open, given a nonexistent path, trashes `pthread_self` on macOS/ARM64 · Issue #6871 · libgit2/libgit2 · GitHub
[go: up one dir, main page]

Skip to content

git_repository_open, given a nonexistent path, trashes pthread_self on macOS/ARM64 #6871

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

Open
OneSadCookie opened this issue Aug 29, 2024 · 4 comments

Comments

@OneSadCookie
Copy link

Reproduction steps

#include <git2.h>
#include <pthread.h>
#include <stdio.h>

int main(int argc, char const * const *argv) {
    if (argc < 2) {
        fprintf(stderr, "Pass a path to a directory for git_repository_open\n");
        return 1;
    }
    char const *path = argv[1];
    
    printf("before git_repository_open: pthread_self: %p\n", pthread_self());

    git_repository *repo = NULL;
    int err = git_repository_open(&repo, path);
    if (err == 0) {
        printf("git_repository_open succeeded: %p\n", repo);
    } else {
        printf("git_repository_open failed: %d\n", err);
    }

    printf("after git_repository_open: pthread_self: %p\n", pthread_self());
    exit(0);
}

I'm using the libgit2 from homebrew, but the version Apple ships with Xcode also has the problem:

cc \
    -I/opt/homebrew/include \
    main.c \
    /opt/homebrew/lib/libgit2.a \
    /opt/homebrew/lib/libssh2.a \
    /opt/homebrew/lib/libcrypto.a \
    -lz -liconv \
    -framework Security -framework Foundation

Running the test program on /usr succeeds, but on /foo fails:

$ lldb a.out 
(lldb) target create "a.out"
Current executable set to '/Users/<me>/.../Libgit2NukesPthreadSelf/a.out' (arm64).
(lldb) r /usr
Process 73772 launched: '/Users/<me>/.../Libgit2NukesPthreadSelf/a.out' (arm64)
before git_repository_open: pthread_self: 0x1fa3fcf40
git_repository_open failed: -1
after git_repository_open: pthread_self: 0x1fa3fcf40
Process 73772 exited with status = 0 (0x00000000) 

(lldb) r /foo
Process 73796 launched: '/Users/<me>/.../Libgit2NukesPthreadSelf/a.out' (arm64)
before git_repository_open: pthread_self: 0x1fa3fcf40
git_repository_open failed: -3
Process 73796 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x1925a973c)
    frame #0: 0x00000001925a973c libsystem_pthread.dylib`pthread_self + 56
libsystem_pthread.dylib`pthread_self:
->  0x1925a973c <+56>: brk    #0xc473
    0x1925a9740 <+60>: cmp    x16, x0
    0x1925a9744 <+64>: b.ne   0x1925a9750    ; <+76>
    0x1925a9748 <+68>: ldp    x29, x30, [sp], #0x10
Target 0: (a.out) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x1925a973c)
  * frame #0: 0x00000001925a973c libsystem_pthread.dylib`pthread_self + 56
    frame #1: 0x00000001000020e0 a.out`main + 224
    frame #2: 0x0000000192223154 dyld`start + 2476

Expected behavior

git_repository_open should not trash memory

Actual behavior

Pretty sure git_repository_open is trashing memory! At the least, it's somehow triggering pthread_self's internal safety check, probably this one: https://github.com/apple/darwin-libpthread/blob/main/src/inline_internal.h#L177

Version of libgit2 (release number or SHA1)

1.8.1

Operating system(s) tested

macOS Sonoma 14.6.1

@ethomson
Copy link
Member

I'll take a look, but you must call git_libgit2_init before calling any other function. This sets up the thread-local storage that libgit2 uses for things like error handling. If git_repository_open fails, it will try to write an error message to that TLS.

So I suspect that adding git_libgit2_init at the start of this program may resolve this?

That said, we aim to fail nicely here when git_libgit2_init has not been invoked. I updated the library in #5578 to try to deal with this, but it was aimed at the allocator. I'll 👀 this case though and see where we're falling down.

@ethomson
Copy link
Member

It also seems like we should add some additional documentation to the primary entry points for the application, in the git_repository apis to point this out; clone, init and open are likely the three places that somebody new to the library will call first.

@OneSadCookie
Copy link
Author

Ah, you're quite correct of course, adding the call to git_libgit2_init does fix it.

I did start by looking for docs or a tutorial, but only found a giant reference document with hundreds of functions, so I just started guessing names...

Thank you! Feel free to close the issue (or not!) as you see fit.

@ethomson
Copy link
Member

Thanks for the update! I will leave this open so that I can:

  1. Take another look at git_libgit2_init. It's a footgun that we need to improve.
  2. Update the documentation;

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

No branches or pull requests

2 participants
0