summaryrefslogtreecommitdiffstats
path: root/debian/patches/0004-hook-clone-protections-add-escape-hatch.diff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--debian/patches/0004-hook-clone-protections-add-escape-hatch.diff182
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