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
ahah! updating to debian:sid
(1.7.1) and this works as intended
Glad to hear it, thanks!