mirror of
https://github.com/sudo-project/sudo.git
synced 2025-09-05 00:35:14 +00:00
Revert pivot_root and go back to prepending the new root directory.
We cannot perform passwd/group lookups _after_ changing the root directory. This does mean that symbolic links in a path are not currently handled properly when matching chroot()ed commands. Fixes a local privilege escalation vulnerability where a user could craft their own nsswitch.conf file to load a shared library of their choosing and run arbitrary code. CVE-2025-32463 Reported by Rich Mirch @ Stratascale Cyber Research Unit (CRU).
This commit is contained in:
@@ -43,14 +43,14 @@
|
||||
* On failure, returns false.
|
||||
*/
|
||||
static bool
|
||||
cmnd_allowed(char *cmnd, size_t cmnd_size, struct stat *cmnd_sbp,
|
||||
char * const *allowlist)
|
||||
cmnd_allowed(char *cmnd, size_t cmnd_size, const char *runchroot,
|
||||
struct stat *cmnd_sbp, char * const *allowlist)
|
||||
{
|
||||
const char *cmnd_base;
|
||||
char * const *al;
|
||||
debug_decl(cmnd_allowed, SUDOERS_DEBUG_UTIL);
|
||||
|
||||
if (!sudo_goodpath(cmnd, cmnd_sbp))
|
||||
if (!sudo_goodpath(cmnd, runchroot, cmnd_sbp))
|
||||
debug_return_bool(false);
|
||||
|
||||
if (allowlist == NULL)
|
||||
@@ -67,7 +67,7 @@ cmnd_allowed(char *cmnd, size_t cmnd_size, struct stat *cmnd_sbp,
|
||||
if (strcmp(cmnd_base, base) != 0)
|
||||
continue;
|
||||
|
||||
if (sudo_goodpath(path, &sb) &&
|
||||
if (sudo_goodpath(path, runchroot, &sb) &&
|
||||
sb.st_dev == cmnd_sbp->st_dev && sb.st_ino == cmnd_sbp->st_ino) {
|
||||
/* Overwrite cmnd with safe version from allowlist. */
|
||||
if (strlcpy(cmnd, path, cmnd_size) < cmnd_size)
|
||||
@@ -87,7 +87,8 @@ cmnd_allowed(char *cmnd, size_t cmnd_size, struct stat *cmnd_sbp,
|
||||
*/
|
||||
int
|
||||
find_path(const char *infile, char **outfile, struct stat *sbp,
|
||||
const char *path, bool ignore_dot, char * const *allowlist)
|
||||
const char *path, const char *runchroot, bool ignore_dot,
|
||||
char * const *allowlist)
|
||||
{
|
||||
char command[PATH_MAX];
|
||||
const char *cp, *ep, *pathend;
|
||||
@@ -108,7 +109,8 @@ find_path(const char *infile, char **outfile, struct stat *sbp,
|
||||
errno = ENAMETOOLONG;
|
||||
debug_return_int(NOT_FOUND_ERROR);
|
||||
}
|
||||
found = cmnd_allowed(command, sizeof(command), sbp, allowlist);
|
||||
found = cmnd_allowed(command, sizeof(command), runchroot, sbp,
|
||||
allowlist);
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -137,7 +139,8 @@ find_path(const char *infile, char **outfile, struct stat *sbp,
|
||||
errno = ENAMETOOLONG;
|
||||
debug_return_int(NOT_FOUND_ERROR);
|
||||
}
|
||||
found = cmnd_allowed(command, sizeof(command), sbp, allowlist);
|
||||
found = cmnd_allowed(command, sizeof(command), runchroot,
|
||||
sbp, allowlist);
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
@@ -151,7 +154,8 @@ find_path(const char *infile, char **outfile, struct stat *sbp,
|
||||
errno = ENAMETOOLONG;
|
||||
debug_return_int(NOT_FOUND_ERROR);
|
||||
}
|
||||
found = cmnd_allowed(command, sizeof(command), sbp, allowlist);
|
||||
found = cmnd_allowed(command, sizeof(command), runchroot,
|
||||
sbp, allowlist);
|
||||
if (found && ignore_dot)
|
||||
debug_return_int(NOT_FOUND_DOT);
|
||||
}
|
||||
|
Reference in New Issue
Block a user