summaryrefslogtreecommitdiff
path: root/git-compat-util.h
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2022-06-23 12:36:03 +0200
committerJohannes Schindelin <johannes.schindelin@gmx.de>2022-06-23 12:36:03 +0200
commitaef3d5948c5b00a0409e117da7e720f574040505 (patch)
tree0faf03246ee43768f4eee7ef66e7a838e471958f /git-compat-util.h
parentd516b2db0af2221bd6b13e7347abdcb5830b2829 (diff)
parentf2eed22852b0a21556f0c9f56732913eba553e62 (diff)
downloadgit-aef3d5948c5b00a0409e117da7e720f574040505.tar.gz
Sync with 2.34.4
* maint-2.34: Git 2.34.4 Git 2.33.4 Git 2.32.3 Git 2.31.4 Git 2.30.5 setup: tighten ownership checks post CVE-2022-24765 git-compat-util: allow root to access both SUDO_UID and root owned t0034: add negative tests and allow git init to mostly work under sudo git-compat-util: avoid failing dir ownership checks if running privileged t: regression git needs safe.directory when using sudo
Diffstat (limited to 'git-compat-util.h')
-rw-r--r--git-compat-util.h58
1 files changed, 57 insertions, 1 deletions
diff --git a/git-compat-util.h b/git-compat-util.h
index e30a374a84..65f82607cc 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -431,12 +431,68 @@ static inline int git_offset_1st_component(const char *path)
#endif
#ifndef is_path_owned_by_current_user
+
+#ifdef __TANDEM
+#define ROOT_UID 65535
+#else
+#define ROOT_UID 0
+#endif
+
+/*
+ * Do not use this function when
+ * (1) geteuid() did not say we are running as 'root', or
+ * (2) using this function will compromise the system.
+ *
+ * PORTABILITY WARNING:
+ * This code assumes uid_t is unsigned because that is what sudo does.
+ * If your uid_t type is signed and all your ids are positive then it
+ * should all work fine.
+ * If your version of sudo uses negative values for uid_t or it is
+ * buggy and return an overflowed value in SUDO_UID, then git might
+ * fail to grant access to your repository properly or even mistakenly
+ * grant access to someone else.
+ * In the unlikely scenario this happened to you, and that is how you
+ * got to this message, we would like to know about it; so sent us an
+ * email to git@vger.kernel.org indicating which platform you are
+ * using and which version of sudo, so we can improve this logic and
+ * maybe provide you with a patch that would prevent this issue again
+ * in the future.
+ */
+static inline void extract_id_from_env(const char *env, uid_t *id)
+{
+ const char *real_uid = getenv(env);
+
+ /* discard anything empty to avoid a more complex check below */
+ if (real_uid && *real_uid) {
+ char *endptr = NULL;
+ unsigned long env_id;
+
+ errno = 0;
+ /* silent overflow errors could trigger a bug here */
+ env_id = strtoul(real_uid, &endptr, 10);
+ if (!*endptr && !errno)
+ *id = env_id;
+ }
+}
+
static inline int is_path_owned_by_current_uid(const char *path)
{
struct stat st;
+ uid_t euid;
+
if (lstat(path, &st))
return 0;
- return st.st_uid == geteuid();
+
+ euid = geteuid();
+ if (euid == ROOT_UID)
+ {
+ if (st.st_uid == ROOT_UID)
+ return 1;
+ else
+ extract_id_from_env("SUDO_UID", &euid);
+ }
+
+ return st.st_uid == euid;
}
#define is_path_owned_by_current_user is_path_owned_by_current_uid