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) ...@@ -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_t owner_level =
GIT_FS_PATH_OWNER_CURRENT_USER | 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; int error = 0;
if (path) if (path)
......
...@@ -1934,27 +1934,36 @@ done: ...@@ -1934,27 +1934,36 @@ done:
#else #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( int git_fs_path_owner_is(
bool *out, bool *out,
const char *path, const char *path,
git_fs_path_owner_t owner_type) git_fs_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_FS_PATH_OWNER_CURRENT_USER) euid = geteuid();
uids[uid_count++] = geteuid();
if (owner_type & GIT_FS_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)
...@@ -1964,13 +1973,27 @@ int git_fs_path_owner_is( ...@@ -1964,13 +1973,27 @@ int git_fs_path_owner_is(
return -1; return -1;
} }
for (i = 0; i < uid_count; i++) { if ((owner_type & GIT_FS_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_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; return 0;
} }
......
...@@ -747,8 +747,13 @@ typedef enum { ...@@ -747,8 +747,13 @@ typedef enum {
*/ */
GIT_FS_PATH_USER_IS_ADMINISTRATOR = (1 << 2), 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. */ /** 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; } 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