diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-17 09:21:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-17 09:21:29 +0000 |
commit | 920a7eed738050b983347797a0d23122cd799699 (patch) | |
tree | 6254bc8e87d554b832d84d39da16e1d268080487 /debian/patches/0004-hook-clone-protections-add-escape-hatch.diff | |
parent | Merging upstream version 1:2.45.2. (diff) | |
download | git-920a7eed738050b983347797a0d23122cd799699.tar.xz git-920a7eed738050b983347797a0d23122cd799699.zip |
Merging debian version 1:2.45.2-1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | debian/patches/0004-hook-clone-protections-add-escape-hatch.diff | 182 |
1 files changed, 0 insertions, 182 deletions
diff --git a/debian/patches/0004-hook-clone-protections-add-escape-hatch.diff b/debian/patches/0004-hook-clone-protections-add-escape-hatch.diff deleted file mode 100644 index b2aa135..0000000 --- a/debian/patches/0004-hook-clone-protections-add-escape-hatch.diff +++ /dev/null @@ -1,182 +0,0 @@ -From 1f34eea689413fa10a664f4c154b097be7796b0a Mon Sep 17 00:00:00 2001 -From: Johannes Schindelin <johannes.schindelin@gmx.de> -Date: Sat, 18 May 2024 10:32:43 +0000 -Subject: hook(clone protections): add escape hatch - -commit 85811d32aca9f0ba324a04bd8709c315d472efbe upstream. - -As defense-in-depth measures, v2.39.4 and friends leading up to v2.45.1 -introduced code that detects when hooks have been installed during a -`git clone`, which is indicative of a common attack vector with critical -severity that allows Remote Code Execution. - -There are legitimate use cases for such behavior, though, for example -when those hooks stem from Git's own templates, which system -administrators are at liberty to modify to enforce, say, commit message -conventions. The git clone protections specifically add exceptions to -allow for that. - -Another legitimate use case that has been identified too late to be -handled in these security bug-fix versions is Git LFS: It behaves -somewhat similar to common attack vectors by writing a few hooks while -running the `smudge` filter during a regular clone, which means that Git -has no chance to know that the hooks are benign and e.g. the -`post-checkout` hook can be safely executed as part of the clone -operation. - -To help Git LFS, and other tools behaving similarly (if there are any), -let's add a new, multi-valued `safe.hook.sha256` config setting. Like -the already-existing `safe.*` settings, it is ignored in -repository-local configs, and it is interpreted as a list of SHA-256 -checksums of hooks' contents that are safe to execute during a clone -operation. Future Git LFS versions will need to write those entries at -the same time they install the `smudge`/`clean` filters. - -Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> -Signed-off-by: Junio C Hamano <gitster@pobox.com> -Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> ---- - Documentation/config/safe.txt | 6 +++ - hook.c | 69 ++++++++++++++++++++++++++++++++--- - t/t1800-hook.sh | 15 ++++++++ - 3 files changed, 85 insertions(+), 5 deletions(-) - -diff --git a/Documentation/config/safe.txt b/Documentation/config/safe.txt -index 577df40223a..e2eb4992bef 100644 ---- a/Documentation/config/safe.txt -+++ b/Documentation/config/safe.txt -@@ -59,3 +59,9 @@ which id the original user has. - If that is not what you would prefer and want git to only trust - repositories that are owned by root instead, then you can remove - the `SUDO_UID` variable from root's environment before invoking git. -+ -+safe.hook.sha256:: -+ The value is the SHA-256 of hooks that are considered to be safe -+ to run during a clone operation. -++ -+Multiple values can be added via `git config --global --add`. -diff --git a/hook.c b/hook.c -index 8de469b134a..9eca6c0103a 100644 ---- a/hook.c -+++ b/hook.c -@@ -10,6 +10,9 @@ - #include "environment.h" - #include "setup.h" - #include "copy.h" -+#include "strmap.h" -+#include "hash-ll.h" -+#include "hex.h" - - static int identical_to_template_hook(const char *name, const char *path) - { -@@ -37,11 +40,66 @@ static int identical_to_template_hook(const char *name, const char *path) - return ret; - } - -+static struct strset safe_hook_sha256s = STRSET_INIT; -+static int safe_hook_sha256s_initialized; -+ -+static int get_sha256_of_file_contents(const char *path, char *sha256) -+{ -+ struct strbuf sb = STRBUF_INIT; -+ int fd; -+ ssize_t res; -+ -+ git_hash_ctx ctx; -+ const struct git_hash_algo *algo = &hash_algos[GIT_HASH_SHA256]; -+ unsigned char hash[GIT_MAX_RAWSZ]; -+ -+ if ((fd = open(path, O_RDONLY)) < 0) -+ return -1; -+ res = strbuf_read(&sb, fd, 400); -+ close(fd); -+ if (res < 0) -+ return -1; -+ -+ algo->init_fn(&ctx); -+ algo->update_fn(&ctx, sb.buf, sb.len); -+ strbuf_release(&sb); -+ algo->final_fn(hash, &ctx); -+ -+ hash_to_hex_algop_r(sha256, hash, algo); -+ -+ return 0; -+} -+ -+static int safe_hook_cb(const char *key, const char *value, -+ const struct config_context *ctx UNUSED, void *d) -+{ -+ struct strset *set = d; -+ -+ if (value && !strcmp(key, "safe.hook.sha256")) -+ strset_add(set, value); -+ -+ return 0; -+} -+ -+static int is_hook_safe_during_clone(const char *name, const char *path, char *sha256) -+{ -+ if (get_sha256_of_file_contents(path, sha256) < 0) -+ return 0; -+ -+ if (!safe_hook_sha256s_initialized) { -+ safe_hook_sha256s_initialized = 1; -+ git_protected_config(safe_hook_cb, &safe_hook_sha256s); -+ } -+ -+ return strset_contains(&safe_hook_sha256s, sha256); -+} -+ - const char *find_hook(const char *name) - { - static struct strbuf path = STRBUF_INIT; - - int found_hook; -+ char sha256[GIT_SHA256_HEXSZ + 1] = { '\0' }; - - strbuf_reset(&path); - strbuf_git_path(&path, "hooks/%s", name); -@@ -73,13 +131,14 @@ const char *find_hook(const char *name) - return NULL; - } - if (!git_hooks_path && git_env_bool("GIT_CLONE_PROTECTION_ACTIVE", 0) && -- !identical_to_template_hook(name, path.buf)) -+ !identical_to_template_hook(name, path.buf) && -+ !is_hook_safe_during_clone(name, path.buf, sha256)) - die(_("active `%s` hook found during `git clone`:\n\t%s\n" - "For security reasons, this is disallowed by default.\n" -- "If this is intentional and the hook should actually " -- "be run, please\nrun the command again with " -- "`GIT_CLONE_PROTECTION_ACTIVE=false`"), -- name, path.buf); -+ "If this is intentional and the hook is safe to run, " -+ "please run the following command and try again:\n\n" -+ " git config --global --add safe.hook.sha256 %s"), -+ name, path.buf, sha256); - return path.buf; - } - -diff --git a/t/t1800-hook.sh b/t/t1800-hook.sh -index 8b0234cf2d5..cbdf60c451a 100755 ---- a/t/t1800-hook.sh -+++ b/t/t1800-hook.sh -@@ -185,4 +185,19 @@ test_expect_success 'stdin to hooks' ' - test_cmp expect actual - ' - -+test_expect_success '`safe.hook.sha256` and clone protections' ' -+ git init safe-hook && -+ write_script safe-hook/.git/hooks/pre-push <<-\EOF && -+ echo "called hook" >safe-hook.log -+ EOF -+ -+ test_must_fail env GIT_CLONE_PROTECTION_ACTIVE=true \ -+ git -C safe-hook hook run pre-push 2>err && -+ cmd="$(grep "git config --global --add safe.hook.sha256 [0-9a-f]" err)" && -+ eval "$cmd" && -+ GIT_CLONE_PROTECTION_ACTIVE=true \ -+ git -C safe-hook hook run pre-push && -+ test "called hook" = "$(cat safe-hook/safe-hook.log)" -+' -+ - test_done |