mirror of
https://github.com/libgit2/libgit2.git
synced 2026-01-25 02:56:17 +00:00
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.
This commit is contained in:
@@ -1928,27 +1928,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)
|
||||
@@ -1958,13 +1967,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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user