mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-22 01:49:11 +00:00
Pass runchroot to match_digest() too.
We use the open fd for the actual I/O but having runchroot makes it possible to report the correct file name in error messages.
This commit is contained in:
parent
645eda55ab
commit
607076d8a0
@ -272,7 +272,8 @@ command_matches_dir(const char *sudoers_dir, size_t dlen, const char *runchroot,
|
||||
if (user_stat == NULL ||
|
||||
(user_stat->st_dev == sudoers_stat.st_dev &&
|
||||
user_stat->st_ino == sudoers_stat.st_ino)) {
|
||||
if (!digest_matches(fd, buf, digests))
|
||||
/* buf is already relative to runchroot */
|
||||
if (!digest_matches(fd, buf, NULL, digests))
|
||||
continue;
|
||||
free(safe_cmnd);
|
||||
if ((safe_cmnd = strdup(buf + chrootlen)) == NULL) {
|
||||
@ -311,7 +312,7 @@ command_matches_all(const char *runchroot,
|
||||
}
|
||||
|
||||
/* Check digest of user_cmnd since we have no sudoers_cmnd for ALL. */
|
||||
if (!digest_matches(fd, user_cmnd, digests))
|
||||
if (!digest_matches(fd, user_cmnd, runchroot, digests))
|
||||
goto bad;
|
||||
set_cmnd_fd(fd);
|
||||
|
||||
@ -351,7 +352,7 @@ command_matches_fnmatch(const char *sudoers_cmnd, const char *sudoers_args,
|
||||
if (!do_stat(fd, user_cmnd, runchroot, &sb))
|
||||
goto bad;
|
||||
/* Check digest of user_cmnd since sudoers_cmnd is a pattern. */
|
||||
if (!digest_matches(fd, user_cmnd, digests))
|
||||
if (!digest_matches(fd, user_cmnd, runchroot, digests))
|
||||
goto bad;
|
||||
set_cmnd_fd(fd);
|
||||
|
||||
@ -438,7 +439,7 @@ command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args,
|
||||
(user_stat->st_dev == sudoers_stat.st_dev &&
|
||||
user_stat->st_ino == sudoers_stat.st_ino)) {
|
||||
/* There could be multiple matches, check digest early. */
|
||||
if (!digest_matches(fd, cp, digests)) {
|
||||
if (!digest_matches(fd, cp, runchroot, digests)) {
|
||||
bad_digest = true;
|
||||
continue;
|
||||
}
|
||||
@ -490,7 +491,7 @@ command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args,
|
||||
if (user_stat == NULL ||
|
||||
(user_stat->st_dev == sudoers_stat.st_dev &&
|
||||
user_stat->st_ino == sudoers_stat.st_ino)) {
|
||||
if (!digest_matches(fd, cp, digests))
|
||||
if (!digest_matches(fd, cp, runchroot, digests))
|
||||
continue;
|
||||
free(safe_cmnd);
|
||||
if ((safe_cmnd = strdup(cp)) == NULL) {
|
||||
@ -563,7 +564,7 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args,
|
||||
}
|
||||
if (!command_args_match(sudoers_cmnd, sudoers_args))
|
||||
goto bad;
|
||||
if (!digest_matches(fd, sudoers_cmnd, digests)) {
|
||||
if (!digest_matches(fd, sudoers_cmnd, runchroot, digests)) {
|
||||
/* XXX - log functions not available but we should log very loudly */
|
||||
goto bad;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -38,13 +39,15 @@
|
||||
#include <gram.h>
|
||||
|
||||
bool
|
||||
digest_matches(int fd, const char *file, const struct command_digest_list *digests)
|
||||
digest_matches(int fd, const char *path, const char *runchroot,
|
||||
const struct command_digest_list *digests)
|
||||
{
|
||||
unsigned int digest_type = SUDO_DIGEST_INVALID;
|
||||
unsigned char *file_digest = NULL;
|
||||
unsigned char *sudoers_digest = NULL;
|
||||
struct command_digest *digest;
|
||||
size_t digest_len = (size_t)-1;
|
||||
char pathbuf[PATH_MAX];
|
||||
bool matched = false;
|
||||
debug_decl(digest_matches, SUDOERS_DEBUG_MATCH);
|
||||
|
||||
@ -58,11 +61,21 @@ digest_matches(int fd, const char *file, const struct command_digest_list *diges
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (runchroot != NULL) {
|
||||
const int len =
|
||||
snprintf(pathbuf, sizeof(pathbuf), "%s%s", runchroot, path);
|
||||
if (len >= ssizeof(pathbuf)) {
|
||||
errno = ENAMETOOLONG;
|
||||
debug_return_bool(false);
|
||||
}
|
||||
path = pathbuf;
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(digest, digests, entries) {
|
||||
/* Compute file digest if needed. */
|
||||
if (digest->digest_type != digest_type) {
|
||||
free(file_digest);
|
||||
file_digest = sudo_filedigest(fd, file, digest->digest_type,
|
||||
file_digest = sudo_filedigest(fd, path, digest->digest_type,
|
||||
&digest_len);
|
||||
if (lseek(fd, (off_t)0, SEEK_SET) == -1) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
|
||||
@ -106,14 +119,14 @@ digest_matches(int fd, const char *file, const struct command_digest_list *diges
|
||||
|
||||
sudo_debug_printf(SUDO_DEBUG_DIAG|SUDO_DEBUG_LINENO,
|
||||
"%s digest mismatch for %s, expecting %s",
|
||||
digest_type_to_name(digest->digest_type), file, digest->digest_str);
|
||||
digest_type_to_name(digest->digest_type), path, digest->digest_str);
|
||||
free(sudoers_digest);
|
||||
sudoers_digest = NULL;
|
||||
}
|
||||
goto done;
|
||||
|
||||
bad_format:
|
||||
sudo_warnx(U_("digest for %s (%s) is not in %s form"), file,
|
||||
sudo_warnx(U_("digest for %s (%s) is not in %s form"), path,
|
||||
digest->digest_str, digest_type_to_name(digest->digest_type));
|
||||
done:
|
||||
free(sudoers_digest);
|
||||
|
@ -325,7 +325,7 @@ bool addr_matches(char *n);
|
||||
bool command_matches(const char *sudoers_cmnd, const char *sudoers_args, const char *runchroot, struct cmnd_info *info, const struct command_digest_list *digests);
|
||||
|
||||
/* match_digest.c */
|
||||
bool digest_matches(int fd, const char *file, const struct command_digest_list *digests);
|
||||
bool digest_matches(int fd, const char *path, const char *runchroot, const struct command_digest_list *digests);
|
||||
|
||||
/* match.c */
|
||||
struct group;
|
||||
|
Loading…
x
Reference in New Issue
Block a user