Commit ed24b8ba 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 af9e0032
......@@ -531,7 +531,8 @@ static int validate_ownership_path(bool *is_safe, const char *path)
{
git_fs_path_owner_t owner_level =
GIT_FS_PATH_OWNER_CURRENT_USER |
GIT_FS_PATH_USER_IS_ADMINISTRATOR;
GIT_FS_PATH_USER_IS_ADMINISTRATOR |
GIT_FS_PATH_OWNER_RUNNING_SUDO;
int error = 0;
if (path)
......
......@@ -1934,27 +1934,36 @@ done:
#else
static int sudo_uid_lookup(uid_t *out)
{
git_str uid_str = GIT_STR_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_str_dispose(&uid_str);
return error;
}
int git_fs_path_owner_is(
bool *out,
const char *path,
git_fs_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_FS_PATH_OWNER_CURRENT_USER)
uids[uid_count++] = geteuid();
if (owner_type & GIT_FS_PATH_OWNER_ADMINISTRATOR)
uids[uid_count++] = 0;
*out = false;
euid = geteuid();
if (p_lstat(path, &st) != 0) {
if (errno == ENOENT)
......@@ -1964,13 +1973,27 @@ int git_fs_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_FS_PATH_OWNER_CURRENT_USER) != 0 &&
st.st_uid == euid) {
*out = true;
return 0;
}
if ((owner_type & GIT_FS_PATH_OWNER_ADMINISTRATOR) != 0 &&
st.st_uid == 0) {
*out = true;
return 0;
}
if ((owner_type & GIT_FS_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;
}
......
......@@ -747,8 +747,13 @@ typedef enum {
*/
GIT_FS_PATH_USER_IS_ADMINISTRATOR = (1 << 2),
/**
* The file is owned by the current user, who is running `sudo`.
*/
GIT_FS_PATH_OWNER_RUNNING_SUDO = (1 << 3),
/** The file may be owned by another user. */
GIT_FS_PATH_OWNER_OTHER = (1 << 3)
GIT_FS_PATH_OWNER_OTHER = (1 << 4)
} git_fs_path_owner_t;
/**
......
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