diff --git a/plugins/sudoers/match_command.c b/plugins/sudoers/match_command.c index 733180e8e..1be997eb1 100644 --- a/plugins/sudoers/match_command.c +++ b/plugins/sudoers/match_command.c @@ -204,7 +204,7 @@ open_cmnd(const char *path, const struct command_digest_list *digests, int *fdp) } 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); @@ -222,10 +222,10 @@ set_cmnd_fd(struct sudoers_context *ctx, int fd, int rootfd) int error, flags; /* 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. */ (void)snprintf(fdpath, sizeof(fdpath), "dev/fd/%d", fd); - error = fstatat(rootfd, fdpath, &sb, 0); + error = fstatat(real_root, fdpath, &sb, 0); } else { /* Absolute path. */ (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 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; char path[PATH_MAX]; @@ -316,7 +317,7 @@ done: */ static int 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) { int fd = -1; @@ -335,7 +336,7 @@ command_matches_dir(struct sudoers_context *ctx, const char *sudoers_dir, goto bad; if (digest_matches(fd, ctx->user.cmnd, digests) != ALLOW) goto bad; - set_cmnd_fd(ctx, fd, rootfd); + set_cmnd_fd(ctx, fd, real_root); debug_return_int(ALLOW); bad: @@ -346,8 +347,8 @@ bad: #endif /* SUDOERS_NAME_MATCH */ static int -command_matches_all(struct sudoers_context *ctx, int rootfd, bool intercepted, - const struct command_digest_list *digests) +command_matches_all(struct sudoers_context *ctx, int real_root, + bool intercepted, const struct command_digest_list *digests) { #ifndef SUDOERS_NAME_MATCH 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. */ if (digest_matches(fd, ctx->user.cmnd, digests) != ALLOW) goto bad; - set_cmnd_fd(ctx, fd, rootfd); + set_cmnd_fd(ctx, fd, real_root); /* No need to set ctx->runas.cmnd for ALL. */ debug_return_int(ALLOW); @@ -390,7 +391,7 @@ bad: static int 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 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. */ if (digest_matches(fd, cmnd, digests) != ALLOW) 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 */ debug_return_int(ALLOW); @@ -448,7 +449,7 @@ bad: static int 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 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. */ if (digest_matches(fd, cmnd, digests) != ALLOW) 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 */ debug_return_int(ALLOW); @@ -507,7 +508,7 @@ bad: #ifndef SUDOERS_NAME_MATCH static int 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) { 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. */ dlen = strlen(cp); 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) { globfree(&gl); debug_return_int(ALLOW); @@ -649,7 +650,7 @@ done: if (cp != NULL) { if (command_args_match(ctx, sudoers_cmnd, sudoers_args) == ALLOW) { /* ctx->runas.cmnd was set above. */ - set_cmnd_fd(ctx, fd, rootfd); + set_cmnd_fd(ctx, fd, real_root); debug_return_int(ALLOW); } } @@ -660,7 +661,7 @@ done: static int 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) { 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. */ dlen = strlen(sudoers_cmnd); if (sudoers_cmnd[dlen - 1] == '/') { - debug_return_int(command_matches_dir(ctx, sudoers_cmnd, dlen, rootfd, - intercepted, digests)); + debug_return_int(command_matches_dir(ctx, sudoers_cmnd, dlen, + real_root, intercepted, digests)); } /* 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")); goto bad; } - set_cmnd_fd(ctx, fd, rootfd); + set_cmnd_fd(ctx, fd, real_root); debug_return_int(ALLOW); bad: if (fd != -1) @@ -746,16 +747,16 @@ bad: #else /* SUDOERS_NAME_MATCH */ static int 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) { - return command_matches_fnmatch(ctx, sudoers_cmnd, sudoers_args, rootfd, + return command_matches_fnmatch(ctx, sudoers_cmnd, sudoers_args, real_root, intercepted, digests); } static int 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) { 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. */ dlen = strlen(sudoers_cmnd); 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)); } @@ -784,7 +785,7 @@ command_matches_normal(struct sudoers_context *ctx, const char *sudoers_cmnd, U_("unable to allocate memory")); goto bad; } - set_cmnd_fd(ctx, fd, rootfd); + set_cmnd_fd(ctx, fd, real_root); debug_return_int(ALLOW); } } @@ -810,6 +811,7 @@ command_matches(struct sudoers_context *ctx, const char *sudoers_cmnd, char *saved_user_cmnd = NULL; struct stat saved_user_stat; bool reset_cmnd = false; + int real_root = -1; int ret = DENY; 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 (!pivot_root(runchroot, &pivot_state)) goto done; + real_root = pivot_state.saved_root; } if (reset_cmnd) { @@ -856,15 +859,14 @@ command_matches(struct sudoers_context *ctx, const char *sudoers_cmnd, if (sudoers_cmnd == NULL) { sudoers_cmnd = "ALL"; - ret = command_matches_all(ctx, pivot_get_root(&pivot_state), - intercepted, digests); + ret = command_matches_all(ctx, real_root, intercepted, digests); goto done; } /* Check for regular expressions first. */ if (sudoers_cmnd[0] == '^') { - ret = command_matches_regex(ctx, sudoers_cmnd, sudoers_args, - pivot_get_root(&pivot_state), intercepted, digests); + ret = command_matches_regex(ctx, sudoers_cmnd, sudoers_args, real_root, + intercepted, digests); goto done; } @@ -894,14 +896,14 @@ command_matches(struct sudoers_context *ctx, const char *sudoers_cmnd, */ if (def_fast_glob) { ret = command_matches_fnmatch(ctx, sudoers_cmnd, sudoers_args, - pivot_get_root(&pivot_state), intercepted, digests); + real_root, intercepted, digests); } else { ret = command_matches_glob(ctx, sudoers_cmnd, sudoers_args, - pivot_get_root(&pivot_state), intercepted, digests); + real_root, intercepted, digests); } } else { ret = command_matches_normal(ctx, sudoers_cmnd, sudoers_args, - pivot_get_root(&pivot_state), intercepted, digests); + real_root, intercepted, digests); } done: /* Restore root. */ diff --git a/plugins/sudoers/pivot.c b/plugins/sudoers/pivot.c index db67ad4b8..1c10b9ea6 100644 --- a/plugins/sudoers/pivot.c +++ b/plugins/sudoers/pivot.c @@ -85,15 +85,3 @@ unpivot_root(struct sudoers_pivot *state) 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; -} diff --git a/plugins/sudoers/pivot.h b/plugins/sudoers/pivot.h index c6b205cb9..b03993ea1 100644 --- a/plugins/sudoers/pivot.h +++ b/plugins/sudoers/pivot.h @@ -28,7 +28,5 @@ struct sudoers_pivot { bool pivot_root(const char *new_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 */ diff --git a/plugins/sudoers/regress/fuzz/fuzz_stubs.c b/plugins/sudoers/regress/fuzz/fuzz_stubs.c index 858ed3b67..198240a5d 100644 --- a/plugins/sudoers/regress/fuzz/fuzz_stubs.c +++ b/plugins/sudoers/regress/fuzz/fuzz_stubs.c @@ -69,18 +69,6 @@ unpivot_root(struct sudoers_pivot *state) return true; } -int -pivot_get_root(struct sudoers_pivot *state) -{ - return -1; -} - -int -pivot_get_cwd(struct sudoers_pivot *state) -{ - return -1; -} - int group_plugin_query(const char *user, const char *group, const struct passwd *pw) { diff --git a/plugins/sudoers/stubs.c b/plugins/sudoers/stubs.c index ff4d0dc2f..b6e0ddee9 100644 --- a/plugins/sudoers/stubs.c +++ b/plugins/sudoers/stubs.c @@ -109,17 +109,3 @@ unpivot_root(struct sudoers_pivot *state) { return true; } - -/* STUB */ -int -pivot_get_root(struct sudoers_pivot *state) -{ - return -1; -} - -/* STUB */ -int -pivot_get_cwd(struct sudoers_pivot *state) -{ - return -1; -} diff --git a/plugins/sudoers/testsudoers.c b/plugins/sudoers/testsudoers.c index 90f458a51..399fb342e 100644 --- a/plugins/sudoers/testsudoers.c +++ b/plugins/sudoers/testsudoers.c @@ -616,18 +616,6 @@ unpivot_root(struct sudoers_pivot *state) return true; } -int -pivot_get_root(struct sudoers_pivot *state) -{ - return -1; -} - -int -pivot_get_cwd(struct sudoers_pivot *state) -{ - return -1; -} - int set_cmnd_path(struct sudoers_context *ctx, const char *runchroot) {