From d53ecaeb04182b04b5e872d7707000adb6c418fa Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Mon, 26 Oct 2020 02:44:56 -0700 Subject: [PATCH] hooks/pre-receive: make stale incoming-* dirs removable In order for gc.sh to remove stale objects/incoming-* directories (those that are over 12 hours old), gc.sh must have the permissions to do so. The $GIT_QUARANTINE_PATH directory is created with very stingy permissions namely mode 0700. Since the push operation that creates the $GIT_QUARANTINE_PATH directory will be running as a different user than the one running gc.sh (either the www user for https push or an ssh jail user for ssh push), gc.sh (which runs as the mirror user) cannot remove the $GIT_QUARANTINE_PATH directory as long as it retains only mode 0700 permissions. During the incoming receive, both git-shell-verify and git-http-backend-verify take great pains to make sure that any incoming pack files are not unpacked. This means there are only two directories that need to be "fixed" in the pre-receive hook, $GIT_QUARANTINE_PATH and $GIT_QUARANTINE_PATH/pack. Make sure both of them are ug+rwx,o+rx and also take this opportunity to fixup any pack file parts as well as they will also have "stingy" permissions. Previously, the pre-receive hook was guaranteeing that pack file parts received g+w, but that can leave some of them with no group or other read permission (e.g. pack-*.keep parts). When fixing up pack file parts, make sure they all get ug+rw,o+r rather than just ug+w to eliminate the issue. Signed-off-by: Kyle J. McKay --- hooks/pre-receive | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/hooks/pre-receive b/hooks/pre-receive index 7da9105..94230b7 100755 --- a/hooks/pre-receive +++ b/hooks/pre-receive @@ -70,12 +70,17 @@ hexdig='[0-9a-f]' octet="$hexdig$hexdig" octet4="$octet$octet$octet$octet" octet20="$octet4$octet4$octet4$octet4$octet4" -_make_packs_ugw() { - find -L "$1" -maxdepth 1 -type f ! -perm -ug+w \ - -name "pack-$octet20*.*" -exec chmod ug+w '{}' + || : +_make_packs_ugrw() { + find -L "$1" -maxdepth 1 -type f ! -perm -ug+rw,o+r \ + -name "pack-$octet20*.*" -exec chmod ug+rw,o+r '{}' + || : } 2>/dev/null -_make_packs_ugw objects/pack -[ -z "$GIT_QUARANTINE_PATH" ] || _make_packs_ugw "$GIT_QUARANTINE_PATH/pack" +_make_packs_ugrw objects/pack +if [ -n "$GIT_QUARANTINE_PATH" ]; then + # gc.sh will be unable remove stale incoming-* dirs without this + chmod ug+rwx,o+rx "$GIT_QUARANTINE_PATH" "$GIT_QUARANTINE_PATH/pack" >/dev/null 2>&1 || : + chmod g+s "$GIT_QUARANTINE_PATH" "$GIT_QUARANTINE_PATH/pack" >/dev/null 2>&1 || : + _make_packs_ugrw "$GIT_QUARANTINE_PATH/pack" +fi # Trigger a mini-gc if there are at least 20 packs present. # Our current pack that contains this push's data will have a .keep while -- 2.11.4.GIT