Commit 749f5fdb by Edward Thomson

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.
parent 2e4ea7b7
...@@ -2173,27 +2173,36 @@ done: ...@@ -2173,27 +2173,36 @@ done:
#else #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( int git_path_owner_is(
bool *out, bool *out,
const char *path, const char *path,
git_path_owner_t owner_type) git_path_owner_t owner_type)
{ {
uid_t uids[2] = { 0 };
size_t uid_count = 0, i;
struct stat st; struct stat st;
uid_t euid, sudo_uid;
if (mock_owner) { if (mock_owner) {
*out = ((mock_owner & owner_type) != 0); *out = ((mock_owner & owner_type) != 0);
return 0; return 0;
} }
if (owner_type & GIT_PATH_OWNER_CURRENT_USER) euid = geteuid();
uids[uid_count++] = geteuid();
if (owner_type & GIT_PATH_OWNER_ADMINISTRATOR)
uids[uid_count++] = 0;
*out = false;
if (p_lstat(path, &st) != 0) { if (p_lstat(path, &st) != 0) {
if (errno == ENOENT) if (errno == ENOENT)
...@@ -2203,13 +2212,27 @@ int git_path_owner_is( ...@@ -2203,13 +2212,27 @@ int git_path_owner_is(
return -1; return -1;
} }
for (i = 0; i < uid_count; i++) { if ((owner_type & GIT_PATH_OWNER_CURRENT_USER) != 0 &&
if (uids[i] == st.st_uid) { st.st_uid == euid) {
*out = true; *out = true;
break; 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; return 0;
} }
......
...@@ -738,8 +738,13 @@ typedef enum { ...@@ -738,8 +738,13 @@ typedef enum {
*/ */
GIT_PATH_USER_IS_ADMINISTRATOR = (1 << 2), 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. */ /** The file may be owned by another user. */
GIT_PATH_OWNER_OTHER = (1 << 3) GIT_PATH_OWNER_OTHER = (1 << 4)
} git_path_owner_t; } git_path_owner_t;
/** /**
......
...@@ -530,7 +530,8 @@ static int validate_ownership_path(bool *is_safe, const char *path) ...@@ -530,7 +530,8 @@ static int validate_ownership_path(bool *is_safe, const char *path)
{ {
git_path_owner_t owner_level = git_path_owner_t owner_level =
GIT_PATH_OWNER_CURRENT_USER | GIT_PATH_OWNER_CURRENT_USER |
GIT_PATH_USER_IS_ADMINISTRATOR; GIT_PATH_USER_IS_ADMINISTRATOR |
GIT_PATH_OWNER_RUNNING_SUDO;
int error = 0; int error = 0;
if (path) if (path)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment