libgit2 / libgit2

A cross-platform, linkable library implementation of Git that you can use in your application.

Home Page:https://libgit2.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

libgit2's permissions check is incompatible with git's

asottile-sentry opened this issue · comments

this is mostly relevant when executing a program in docker where the user is likely root and may be inspecting mounted repositories owned by another user

even when opting in with the usual:

[safe]
    directory = *

libgit2 is unable to access repository details where git happily will.

I've tried to boil this down to a minimal example -- the actual issue is getsentry/action-release#178 where sentry-cli uses libgit2 to request information from a mounted git repository. since it is docker and executed by github actions we have no control over the docker user

my reproduction below uses the version of libgit2 from debian:testing which at the time of writing is a little bit old (1.5.1) but reading the code I don't think this is different in latest

Reproduction steps

t.c - small executable demoing libgit2

#include <stdio.h>
#include <git2/errors.h>
#include <git2/global.h>
#include <git2/repository.h>

int main(int argc, char** argv) {
    git_libgit2_init();

    git_repository* repo = NULL;
    int err = git_repository_open(&repo, argv[1]);
    if (err) {
        const git_error* last = git_error_last();
        printf("got error: %d %s\n", last->klass, last->message);
    } else {
        printf("success!\n");
    }
    return err;
}

Dockerfile - example container to demo the issue

FROM debian:testing
RUN : \
    && apt-get update \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        git \
        gcc \
        libgit2-dev \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

COPY t.c .
RUN gcc t.c -lgit2

RUN git config --global safe.directory '*'

execution

$ git clone -qq https://github.com/asottile/astpretty
$ docker build -qq -t git2-example .
sha256:47de85e6495cdef1bdd2853ad61955eefa9d78ff91dbc3d25ff389a588cf74c3
$ docker run --rm --user 0:0 -v $PWD/astpretty:/src:ro git2-example /a.out /src
got error: 7 repository path '/src/' is not owned by current user
$ docker run --rm --user 0:0 -v $PWD/astpretty:/src:ro git2-example git -C /src rev-parse HEAD
6b6c9afa5212c50bd4a34235930705503f2d959e

Expected behavior

I expect the example to succeed and not produce an error

Actual behavior

see above:

got error: 7 repository path '/src/' is not owned by current user

Version of libgit2 (release number or SHA1)

1.5.1 -- also seeing similar behaviour against 1.4

I realize this is a bit old, I was having difficulty building the latest on my own but I can try harder to get that compiling

Operating system(s) tested

debian:testing, ubuntu:22.04

I can hack around this by pretending to be sudo -- this feels like it shouldn't be ok (1000 is my host user id):

$ docker run --rm --user 0:0 -e SUDO_UID=1000 -v $PWD/astpretty:/src:ro git2-example /a.out /src
success!

Ah, safe.directory. The gift that keeps giving. I thought we’d nailed down all the differences. Possibly not, but it’s also possible that git changed something else without telling anybody else. 😓

@asottile-sentry's workaround didn't work in every case as demonstrated in this issue when I tried to roll this change into production.

ah they had a different uid because they were self-hosting github actions

Unfortunately, v1.5 is too old. safe.directory = * support didn't land until #6429 which was included in v1.6.1.

ahah! updating to debian:sid (1.7.1) and this works as intended

Glad to hear it, thanks!