diff options
author | Johannes Schindelin <johannes.schindelin@gmx.de> | 2024-04-24 09:11:55 +0200 |
---|---|---|
committer | Johannes Schindelin <johannes.schindelin@gmx.de> | 2024-04-29 20:42:30 +0200 |
commit | 1c00f92eb5ee4a48ab615eefa41f2dd6024d43bc (patch) | |
tree | 3440394b1b4f08cf56f27405d54c08937f16df4a /hook.c | |
parent | 786a3e4b8d754d2b14b1208b98eeb0a554ef19a8 (diff) | |
parent | 10dc9846b82b5f4927d57c6bb657a9352121bebf (diff) |
Sync with 2.44.1
* maint-2.44: (41 commits)
Git 2.44.1
Git 2.43.4
Git 2.42.2
Git 2.41.1
Git 2.40.2
Git 2.39.4
fsck: warn about symlink pointing inside a gitdir
core.hooksPath: add some protection while cloning
init.templateDir: consider this config setting protected
clone: prevent hooks from running during a clone
Add a helper function to compare file contents
init: refactor the template directory discovery into its own function
find_hook(): refactor the `STRIP_EXTENSION` logic
clone: when symbolic links collide with directories, keep the latter
entry: report more colliding paths
t5510: verify that D/F confusion cannot lead to an RCE
submodule: require the submodule path to contain directories only
clone_submodule: avoid using `access()` on directories
submodules: submodule paths must not contain symlinks
clone: prevent clashing git dirs when cloning submodule in parallel
...
Diffstat (limited to 'hook.c')
-rw-r--r-- | hook.c | 53 |
1 files changed, 46 insertions, 7 deletions
@@ -7,25 +7,56 @@ #include "run-command.h" #include "config.h" #include "strbuf.h" +#include "environment.h" +#include "setup.h" +#include "copy.h" + +static int identical_to_template_hook(const char *name, const char *path) +{ + const char *env = getenv("GIT_CLONE_TEMPLATE_DIR"); + const char *template_dir = get_template_dir(env && *env ? env : NULL); + struct strbuf template_path = STRBUF_INIT; + int found_template_hook, ret; + + strbuf_addf(&template_path, "%s/hooks/%s", template_dir, name); + found_template_hook = access(template_path.buf, X_OK) >= 0; +#ifdef STRIP_EXTENSION + if (!found_template_hook) { + strbuf_addstr(&template_path, STRIP_EXTENSION); + found_template_hook = access(template_path.buf, X_OK) >= 0; + } +#endif + if (!found_template_hook) + return 0; + + ret = do_files_match(template_path.buf, path); + + strbuf_release(&template_path); + return ret; +} const char *find_hook(const char *name) { static struct strbuf path = STRBUF_INIT; + int found_hook; + strbuf_reset(&path); strbuf_git_path(&path, "hooks/%s", name); - if (access(path.buf, X_OK) < 0) { + found_hook = access(path.buf, X_OK) >= 0; +#ifdef STRIP_EXTENSION + if (!found_hook) { int err = errno; -#ifdef STRIP_EXTENSION strbuf_addstr(&path, STRIP_EXTENSION); - if (access(path.buf, X_OK) >= 0) - return path.buf; - if (errno == EACCES) - err = errno; + found_hook = access(path.buf, X_OK) >= 0; + if (!found_hook) + errno = err; + } #endif - if (err == EACCES && advice_enabled(ADVICE_IGNORED_HOOK)) { + if (!found_hook) { + if (errno == EACCES && advice_enabled(ADVICE_IGNORED_HOOK)) { static struct string_list advise_given = STRING_LIST_INIT_DUP; if (!string_list_lookup(&advise_given, name)) { @@ -39,6 +70,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)) + 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); return path.buf; } |