Remove pivot_get_root() and pivot_get_cwd().

They are unnecessary since struct sudoers_pivot is not opaque.
The implementation details are private to match_command.c.
This commit is contained in:
Todd C. Miller
2023-09-13 16:46:23 -06:00
parent 2aae36f345
commit 0011333f8e
6 changed files with 34 additions and 84 deletions

View File

@@ -204,7 +204,7 @@ open_cmnd(const char *path, const struct command_digest_list *digests, int *fdp)
} }
static void static void
set_cmnd_fd(struct sudoers_context *ctx, int fd, int rootfd) set_cmnd_fd(struct sudoers_context *ctx, int fd, int real_root)
{ {
debug_decl(set_cmnd_fd, SUDOERS_DEBUG_MATCH); debug_decl(set_cmnd_fd, SUDOERS_DEBUG_MATCH);
@@ -222,10 +222,10 @@ set_cmnd_fd(struct sudoers_context *ctx, int fd, int rootfd)
int error, flags; int error, flags;
/* We can only use fexecve() on a script if /dev/fd/N exists. */ /* We can only use fexecve() on a script if /dev/fd/N exists. */
if (rootfd != -1) { if (real_root != -1) {
/* Path relative to old root directory. */ /* Path relative to old root directory. */
(void)snprintf(fdpath, sizeof(fdpath), "dev/fd/%d", fd); (void)snprintf(fdpath, sizeof(fdpath), "dev/fd/%d", fd);
error = fstatat(rootfd, fdpath, &sb, 0); error = fstatat(real_root, fdpath, &sb, 0);
} else { } else {
/* Absolute path. */ /* Absolute path. */
(void)snprintf(fdpath, sizeof(fdpath), "/dev/fd/%d", fd); (void)snprintf(fdpath, sizeof(fdpath), "/dev/fd/%d", fd);
@@ -257,7 +257,8 @@ set_cmnd_fd(struct sudoers_context *ctx, int fd, int rootfd)
*/ */
static int static int
command_matches_dir(struct sudoers_context *ctx, const char *sudoers_dir, command_matches_dir(struct sudoers_context *ctx, const char *sudoers_dir,
size_t dlen, int rootfd, bool intercepted, const struct command_digest_list *digests) size_t dlen, int real_root, bool intercepted,
const struct command_digest_list *digests)
{ {
struct stat sudoers_stat; struct stat sudoers_stat;
char path[PATH_MAX]; char path[PATH_MAX];
@@ -316,7 +317,7 @@ done:
*/ */
static int static int
command_matches_dir(struct sudoers_context *ctx, const char *sudoers_dir, command_matches_dir(struct sudoers_context *ctx, const char *sudoers_dir,
size_t dlen, int rootfd, bool intercepted, size_t dlen, int real_root, bool intercepted,
const struct command_digest_list *digests) const struct command_digest_list *digests)
{ {
int fd = -1; int fd = -1;
@@ -335,7 +336,7 @@ command_matches_dir(struct sudoers_context *ctx, const char *sudoers_dir,
goto bad; goto bad;
if (digest_matches(fd, ctx->user.cmnd, digests) != ALLOW) if (digest_matches(fd, ctx->user.cmnd, digests) != ALLOW)
goto bad; goto bad;
set_cmnd_fd(ctx, fd, rootfd); set_cmnd_fd(ctx, fd, real_root);
debug_return_int(ALLOW); debug_return_int(ALLOW);
bad: bad:
@@ -346,8 +347,8 @@ bad:
#endif /* SUDOERS_NAME_MATCH */ #endif /* SUDOERS_NAME_MATCH */
static int static int
command_matches_all(struct sudoers_context *ctx, int rootfd, bool intercepted, command_matches_all(struct sudoers_context *ctx, int real_root,
const struct command_digest_list *digests) bool intercepted, const struct command_digest_list *digests)
{ {
#ifndef SUDOERS_NAME_MATCH #ifndef SUDOERS_NAME_MATCH
struct stat sb; struct stat sb;
@@ -378,7 +379,7 @@ command_matches_all(struct sudoers_context *ctx, int rootfd, bool intercepted,
/* Check digest of ctx->user.cmnd since we have no sudoers_cmnd for ALL. */ /* Check digest of ctx->user.cmnd since we have no sudoers_cmnd for ALL. */
if (digest_matches(fd, ctx->user.cmnd, digests) != ALLOW) if (digest_matches(fd, ctx->user.cmnd, digests) != ALLOW)
goto bad; goto bad;
set_cmnd_fd(ctx, fd, rootfd); set_cmnd_fd(ctx, fd, real_root);
/* No need to set ctx->runas.cmnd for ALL. */ /* No need to set ctx->runas.cmnd for ALL. */
debug_return_int(ALLOW); debug_return_int(ALLOW);
@@ -390,7 +391,7 @@ bad:
static int static int
command_matches_fnmatch(struct sudoers_context *ctx, const char *sudoers_cmnd, command_matches_fnmatch(struct sudoers_context *ctx, const char *sudoers_cmnd,
const char *sudoers_args, int rootfd, bool intercepted, const char *sudoers_args, int real_root, bool intercepted,
const struct command_digest_list *digests) const struct command_digest_list *digests)
{ {
const char *cmnd = ctx->user.cmnd; const char *cmnd = ctx->user.cmnd;
@@ -435,7 +436,7 @@ command_matches_fnmatch(struct sudoers_context *ctx, const char *sudoers_cmnd,
/* Check digest of cmnd since sudoers_cmnd is a pattern. */ /* Check digest of cmnd since sudoers_cmnd is a pattern. */
if (digest_matches(fd, cmnd, digests) != ALLOW) if (digest_matches(fd, cmnd, digests) != ALLOW)
goto bad; goto bad;
set_cmnd_fd(ctx, fd, rootfd); set_cmnd_fd(ctx, fd, real_root);
/* No need to set ctx->runas.cmnd since cmnd matches sudoers_cmnd */ /* No need to set ctx->runas.cmnd since cmnd matches sudoers_cmnd */
debug_return_int(ALLOW); debug_return_int(ALLOW);
@@ -448,7 +449,7 @@ bad:
static int static int
command_matches_regex(struct sudoers_context *ctx, const char *sudoers_cmnd, command_matches_regex(struct sudoers_context *ctx, const char *sudoers_cmnd,
const char *sudoers_args, int rootfd, bool intercepted, const char *sudoers_args, int real_root, bool intercepted,
const struct command_digest_list *digests) const struct command_digest_list *digests)
{ {
const char *cmnd = ctx->user.cmnd; const char *cmnd = ctx->user.cmnd;
@@ -493,7 +494,7 @@ command_matches_regex(struct sudoers_context *ctx, const char *sudoers_cmnd,
/* Check digest of cmnd since sudoers_cmnd is a pattern. */ /* Check digest of cmnd since sudoers_cmnd is a pattern. */
if (digest_matches(fd, cmnd, digests) != ALLOW) if (digest_matches(fd, cmnd, digests) != ALLOW)
goto bad; goto bad;
set_cmnd_fd(ctx, fd, rootfd); set_cmnd_fd(ctx, fd, real_root);
/* No need to set ctx->runas.cmnd since cmnd matches sudoers_cmnd */ /* No need to set ctx->runas.cmnd since cmnd matches sudoers_cmnd */
debug_return_int(ALLOW); debug_return_int(ALLOW);
@@ -507,7 +508,7 @@ bad:
#ifndef SUDOERS_NAME_MATCH #ifndef SUDOERS_NAME_MATCH
static int static int
command_matches_glob(struct sudoers_context *ctx, const char *sudoers_cmnd, command_matches_glob(struct sudoers_context *ctx, const char *sudoers_cmnd,
const char *sudoers_args, int rootfd, bool intercepted, const char *sudoers_args, int real_root, bool intercepted,
const struct command_digest_list *digests) const struct command_digest_list *digests)
{ {
struct stat sudoers_stat; struct stat sudoers_stat;
@@ -591,7 +592,7 @@ command_matches_glob(struct sudoers_context *ctx, const char *sudoers_cmnd,
/* If it ends in '/' it is a directory spec. */ /* If it ends in '/' it is a directory spec. */
dlen = strlen(cp); dlen = strlen(cp);
if (cp[dlen - 1] == '/') { if (cp[dlen - 1] == '/') {
if (command_matches_dir(ctx, cp, dlen, rootfd, intercepted, if (command_matches_dir(ctx, cp, dlen, real_root, intercepted,
digests) == ALLOW) { digests) == ALLOW) {
globfree(&gl); globfree(&gl);
debug_return_int(ALLOW); debug_return_int(ALLOW);
@@ -649,7 +650,7 @@ done:
if (cp != NULL) { if (cp != NULL) {
if (command_args_match(ctx, sudoers_cmnd, sudoers_args) == ALLOW) { if (command_args_match(ctx, sudoers_cmnd, sudoers_args) == ALLOW) {
/* ctx->runas.cmnd was set above. */ /* ctx->runas.cmnd was set above. */
set_cmnd_fd(ctx, fd, rootfd); set_cmnd_fd(ctx, fd, real_root);
debug_return_int(ALLOW); debug_return_int(ALLOW);
} }
} }
@@ -660,7 +661,7 @@ done:
static int static int
command_matches_normal(struct sudoers_context *ctx, const char *sudoers_cmnd, command_matches_normal(struct sudoers_context *ctx, const char *sudoers_cmnd,
const char *sudoers_args, int rootfd, bool intercepted, const char *sudoers_args, int real_root, bool intercepted,
const struct command_digest_list *digests) const struct command_digest_list *digests)
{ {
struct stat sudoers_stat; struct stat sudoers_stat;
@@ -672,8 +673,8 @@ command_matches_normal(struct sudoers_context *ctx, const char *sudoers_cmnd,
/* If it ends in '/' it is a directory spec. */ /* If it ends in '/' it is a directory spec. */
dlen = strlen(sudoers_cmnd); dlen = strlen(sudoers_cmnd);
if (sudoers_cmnd[dlen - 1] == '/') { if (sudoers_cmnd[dlen - 1] == '/') {
debug_return_int(command_matches_dir(ctx, sudoers_cmnd, dlen, rootfd, debug_return_int(command_matches_dir(ctx, sudoers_cmnd, dlen,
intercepted, digests)); real_root, intercepted, digests));
} }
/* Only proceed if ctx->user.cmnd_base and basename(sudoers_cmnd) match */ /* Only proceed if ctx->user.cmnd_base and basename(sudoers_cmnd) match */
@@ -736,7 +737,7 @@ command_matches_normal(struct sudoers_context *ctx, const char *sudoers_cmnd,
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto bad; goto bad;
} }
set_cmnd_fd(ctx, fd, rootfd); set_cmnd_fd(ctx, fd, real_root);
debug_return_int(ALLOW); debug_return_int(ALLOW);
bad: bad:
if (fd != -1) if (fd != -1)
@@ -746,16 +747,16 @@ bad:
#else /* SUDOERS_NAME_MATCH */ #else /* SUDOERS_NAME_MATCH */
static int static int
command_matches_glob(struct sudoers_context *ctx, const char *sudoers_cmnd, command_matches_glob(struct sudoers_context *ctx, const char *sudoers_cmnd,
const char *sudoers_args, int rootfd, bool intercepted, const char *sudoers_args, int real_root, bool intercepted,
const struct command_digest_list *digests) const struct command_digest_list *digests)
{ {
return command_matches_fnmatch(ctx, sudoers_cmnd, sudoers_args, rootfd, return command_matches_fnmatch(ctx, sudoers_cmnd, sudoers_args, real_root,
intercepted, digests); intercepted, digests);
} }
static int static int
command_matches_normal(struct sudoers_context *ctx, const char *sudoers_cmnd, command_matches_normal(struct sudoers_context *ctx, const char *sudoers_cmnd,
const char *sudoers_args, int rootfd, bool intercepted, const char *sudoers_args, int real_root, bool intercepted,
const struct command_digest_list *digests) const struct command_digest_list *digests)
{ {
size_t dlen; size_t dlen;
@@ -765,7 +766,7 @@ command_matches_normal(struct sudoers_context *ctx, const char *sudoers_cmnd,
/* If it ends in '/' it is a directory spec. */ /* If it ends in '/' it is a directory spec. */
dlen = strlen(sudoers_cmnd); dlen = strlen(sudoers_cmnd);
if (sudoers_cmnd[dlen - 1] == '/') { if (sudoers_cmnd[dlen - 1] == '/') {
debug_return_int(command_matches_dir(ctx, sudoers_cmnd, dlen, rootfd, debug_return_int(command_matches_dir(ctx, sudoers_cmnd, dlen, real_root,
intercepted, digests)); intercepted, digests));
} }
@@ -784,7 +785,7 @@ command_matches_normal(struct sudoers_context *ctx, const char *sudoers_cmnd,
U_("unable to allocate memory")); U_("unable to allocate memory"));
goto bad; goto bad;
} }
set_cmnd_fd(ctx, fd, rootfd); set_cmnd_fd(ctx, fd, real_root);
debug_return_int(ALLOW); debug_return_int(ALLOW);
} }
} }
@@ -810,6 +811,7 @@ command_matches(struct sudoers_context *ctx, const char *sudoers_cmnd,
char *saved_user_cmnd = NULL; char *saved_user_cmnd = NULL;
struct stat saved_user_stat; struct stat saved_user_stat;
bool reset_cmnd = false; bool reset_cmnd = false;
int real_root = -1;
int ret = DENY; int ret = DENY;
debug_decl(command_matches, SUDOERS_DEBUG_MATCH); debug_decl(command_matches, SUDOERS_DEBUG_MATCH);
@@ -834,6 +836,7 @@ command_matches(struct sudoers_context *ctx, const char *sudoers_cmnd,
if (runchroot != NULL) { if (runchroot != NULL) {
if (!pivot_root(runchroot, &pivot_state)) if (!pivot_root(runchroot, &pivot_state))
goto done; goto done;
real_root = pivot_state.saved_root;
} }
if (reset_cmnd) { if (reset_cmnd) {
@@ -856,15 +859,14 @@ command_matches(struct sudoers_context *ctx, const char *sudoers_cmnd,
if (sudoers_cmnd == NULL) { if (sudoers_cmnd == NULL) {
sudoers_cmnd = "ALL"; sudoers_cmnd = "ALL";
ret = command_matches_all(ctx, pivot_get_root(&pivot_state), ret = command_matches_all(ctx, real_root, intercepted, digests);
intercepted, digests);
goto done; goto done;
} }
/* Check for regular expressions first. */ /* Check for regular expressions first. */
if (sudoers_cmnd[0] == '^') { if (sudoers_cmnd[0] == '^') {
ret = command_matches_regex(ctx, sudoers_cmnd, sudoers_args, ret = command_matches_regex(ctx, sudoers_cmnd, sudoers_args, real_root,
pivot_get_root(&pivot_state), intercepted, digests); intercepted, digests);
goto done; goto done;
} }
@@ -894,14 +896,14 @@ command_matches(struct sudoers_context *ctx, const char *sudoers_cmnd,
*/ */
if (def_fast_glob) { if (def_fast_glob) {
ret = command_matches_fnmatch(ctx, sudoers_cmnd, sudoers_args, ret = command_matches_fnmatch(ctx, sudoers_cmnd, sudoers_args,
pivot_get_root(&pivot_state), intercepted, digests); real_root, intercepted, digests);
} else { } else {
ret = command_matches_glob(ctx, sudoers_cmnd, sudoers_args, ret = command_matches_glob(ctx, sudoers_cmnd, sudoers_args,
pivot_get_root(&pivot_state), intercepted, digests); real_root, intercepted, digests);
} }
} else { } else {
ret = command_matches_normal(ctx, sudoers_cmnd, sudoers_args, ret = command_matches_normal(ctx, sudoers_cmnd, sudoers_args,
pivot_get_root(&pivot_state), intercepted, digests); real_root, intercepted, digests);
} }
done: done:
/* Restore root. */ /* Restore root. */

View File

@@ -85,15 +85,3 @@ unpivot_root(struct sudoers_pivot *state)
debug_return_bool(ret); debug_return_bool(ret);
} }
int
pivot_get_root(struct sudoers_pivot *state)
{
return state->saved_root;
}
int
pivot_get_cwd(struct sudoers_pivot *state)
{
return state->saved_cwd;
}

View File

@@ -28,7 +28,5 @@ struct sudoers_pivot {
bool pivot_root(const char *new_root, struct sudoers_pivot *state); bool pivot_root(const char *new_root, struct sudoers_pivot *state);
bool unpivot_root(struct sudoers_pivot *state); bool unpivot_root(struct sudoers_pivot *state);
int pivot_get_root(struct sudoers_pivot *state);
int pivot_get_cwd(struct sudoers_pivot *state);
#endif /* SUDOERS_PIVOT_H */ #endif /* SUDOERS_PIVOT_H */

View File

@@ -69,18 +69,6 @@ unpivot_root(struct sudoers_pivot *state)
return true; return true;
} }
int
pivot_get_root(struct sudoers_pivot *state)
{
return -1;
}
int
pivot_get_cwd(struct sudoers_pivot *state)
{
return -1;
}
int int
group_plugin_query(const char *user, const char *group, const struct passwd *pw) group_plugin_query(const char *user, const char *group, const struct passwd *pw)
{ {

View File

@@ -109,17 +109,3 @@ unpivot_root(struct sudoers_pivot *state)
{ {
return true; return true;
} }
/* STUB */
int
pivot_get_root(struct sudoers_pivot *state)
{
return -1;
}
/* STUB */
int
pivot_get_cwd(struct sudoers_pivot *state)
{
return -1;
}

View File

@@ -616,18 +616,6 @@ unpivot_root(struct sudoers_pivot *state)
return true; return true;
} }
int
pivot_get_root(struct sudoers_pivot *state)
{
return -1;
}
int
pivot_get_cwd(struct sudoers_pivot *state)
{
return -1;
}
int int
set_cmnd_path(struct sudoers_context *ctx, const char *runchroot) set_cmnd_path(struct sudoers_context *ctx, const char *runchroot)
{ {