File 0020-repo-allow-users-running-with-sudo-to-access-their-r.patch of Package libgit2.28344

From 749f5fdbdc1a923ca3c49db328f448b613e75585 Mon Sep 17 00:00:00 2001
From: Edward Thomson <ethomson@edwardthomson.com>
Date: Tue, 5 Jul 2022 23:47:15 -0400
Subject: [PATCH 20/20] repo: allow users running with sudo to access their
 repositories

In the ownership checks implemented for CVE-2022-24765, we disallowed
users to access their own repositories when running with `sudo`.

Examine the `SUDO_UID` environment variable and allow users running
with `sudo`. This matches git's behavior.
---
 src/path.c       | 51 +++++++++++++++++++++++++++++++++++-------------
 src/path.h       |  7 ++++++-
 src/repository.c |  3 ++-
 3 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/src/path.c b/src/path.c
index 606b2ed5e..309f24442 100644
--- a/src/path.c
+++ b/src/path.c
@@ -2173,27 +2173,36 @@ done:
 
 #else
 
+static int sudo_uid_lookup(uid_t *out)
+{
+	git_buf uid_str = GIT_BUF_INIT;
+	int64_t uid;
+	int error;
+
+	if ((error = git__getenv(&uid_str, "SUDO_UID")) == 0 &&
+	    (error = git__strntol64(&uid, uid_str.ptr, uid_str.size, NULL, 10)) == 0 &&
+	    uid == (int64_t)((uid_t)uid)) {
+		*out = (uid_t)uid;
+	}
+
+	git_buf_dispose(&uid_str);
+	return error;
+}
+
 int git_path_owner_is(
 	bool *out,
 	const char *path,
 	git_path_owner_t owner_type)
 {
-	uid_t uids[2] = { 0 };
-	size_t uid_count = 0, i;
 	struct stat st;
+	uid_t euid, sudo_uid;
 
 	if (mock_owner) {
 		*out = ((mock_owner & owner_type) != 0);
 		return 0;
 	}
 
-	if (owner_type & GIT_PATH_OWNER_CURRENT_USER)
-		uids[uid_count++] = geteuid();
-
-	if (owner_type & GIT_PATH_OWNER_ADMINISTRATOR)
-		uids[uid_count++] = 0;
-
-	*out = false;
+	euid = geteuid();
 
 	if (p_lstat(path, &st) != 0) {
 		if (errno == ENOENT)
@@ -2203,13 +2212,27 @@ int git_path_owner_is(
 		return -1;
 	}
 
-	for (i = 0; i < uid_count; i++) {
-		if (uids[i] == st.st_uid) {
-			*out = true;
-			break;
-		}
+	if ((owner_type & GIT_PATH_OWNER_CURRENT_USER) != 0 &&
+	    st.st_uid == euid) {
+		*out = true;
+		return 0;
+	}
+
+	if ((owner_type & GIT_PATH_OWNER_ADMINISTRATOR) != 0 &&
+	    st.st_uid == 0) {
+		*out = true;
+		return 0;
+	}
+
+	if ((owner_type & GIT_PATH_OWNER_RUNNING_SUDO) != 0 &&
+	    euid == 0 &&
+	    sudo_uid_lookup(&sudo_uid) == 0 &&
+	    st.st_uid == sudo_uid) {
+		*out = true;
+		return 0;
 	}
 
+	*out = false;
 	return 0;
 }
 
diff --git a/src/path.h b/src/path.h
index bb51cff11..f697c8f3e 100644
--- a/src/path.h
+++ b/src/path.h
@@ -738,8 +738,13 @@ typedef enum {
 	 */
 	GIT_PATH_USER_IS_ADMINISTRATOR = (1 << 2),
 
+	/**
+	 * The file is owned by the current user, who is running `sudo`.
+	 */
+	GIT_PATH_OWNER_RUNNING_SUDO = (1 << 3),
+
 	/** The file may be owned by another user. */
-	GIT_PATH_OWNER_OTHER = (1 << 3)
+	GIT_PATH_OWNER_OTHER = (1 << 4)
 } git_path_owner_t;
 
 /**
diff --git a/src/repository.c b/src/repository.c
index ac32085da..2518c8b03 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -530,7 +530,8 @@ static int validate_ownership_path(bool *is_safe, const char *path)
 {
 	git_path_owner_t owner_level =
 		GIT_PATH_OWNER_CURRENT_USER |
-		GIT_PATH_USER_IS_ADMINISTRATOR;
+		GIT_PATH_USER_IS_ADMINISTRATOR |
+		GIT_PATH_OWNER_RUNNING_SUDO;
 	int error = 0;
 
 	if (path)
-- 
2.37.1

openSUSE Build Service is sponsored by