mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-31 06:15:37 +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:
@@ -272,7 +272,8 @@ command_matches_dir(const char *sudoers_dir, size_t dlen, const char *runchroot,
|
|||||||
if (user_stat == NULL ||
|
if (user_stat == NULL ||
|
||||||
(user_stat->st_dev == sudoers_stat.st_dev &&
|
(user_stat->st_dev == sudoers_stat.st_dev &&
|
||||||
user_stat->st_ino == sudoers_stat.st_ino)) {
|
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;
|
continue;
|
||||||
free(safe_cmnd);
|
free(safe_cmnd);
|
||||||
if ((safe_cmnd = strdup(buf + chrootlen)) == NULL) {
|
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. */
|
/* 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;
|
goto bad;
|
||||||
set_cmnd_fd(fd);
|
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))
|
if (!do_stat(fd, user_cmnd, runchroot, &sb))
|
||||||
goto bad;
|
goto bad;
|
||||||
/* Check digest of user_cmnd since sudoers_cmnd is a pattern. */
|
/* 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;
|
goto bad;
|
||||||
set_cmnd_fd(fd);
|
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_dev == sudoers_stat.st_dev &&
|
||||||
user_stat->st_ino == sudoers_stat.st_ino)) {
|
user_stat->st_ino == sudoers_stat.st_ino)) {
|
||||||
/* There could be multiple matches, check digest early. */
|
/* There could be multiple matches, check digest early. */
|
||||||
if (!digest_matches(fd, cp, digests)) {
|
if (!digest_matches(fd, cp, runchroot, digests)) {
|
||||||
bad_digest = true;
|
bad_digest = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -490,7 +491,7 @@ command_matches_glob(const char *sudoers_cmnd, const char *sudoers_args,
|
|||||||
if (user_stat == NULL ||
|
if (user_stat == NULL ||
|
||||||
(user_stat->st_dev == sudoers_stat.st_dev &&
|
(user_stat->st_dev == sudoers_stat.st_dev &&
|
||||||
user_stat->st_ino == sudoers_stat.st_ino)) {
|
user_stat->st_ino == sudoers_stat.st_ino)) {
|
||||||
if (!digest_matches(fd, cp, digests))
|
if (!digest_matches(fd, cp, runchroot, digests))
|
||||||
continue;
|
continue;
|
||||||
free(safe_cmnd);
|
free(safe_cmnd);
|
||||||
if ((safe_cmnd = strdup(cp)) == NULL) {
|
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))
|
if (!command_args_match(sudoers_cmnd, sudoers_args))
|
||||||
goto bad;
|
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 */
|
/* XXX - log functions not available but we should log very loudly */
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -38,13 +39,15 @@
|
|||||||
#include <gram.h>
|
#include <gram.h>
|
||||||
|
|
||||||
bool
|
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 int digest_type = SUDO_DIGEST_INVALID;
|
||||||
unsigned char *file_digest = NULL;
|
unsigned char *file_digest = NULL;
|
||||||
unsigned char *sudoers_digest = NULL;
|
unsigned char *sudoers_digest = NULL;
|
||||||
struct command_digest *digest;
|
struct command_digest *digest;
|
||||||
size_t digest_len = (size_t)-1;
|
size_t digest_len = (size_t)-1;
|
||||||
|
char pathbuf[PATH_MAX];
|
||||||
bool matched = false;
|
bool matched = false;
|
||||||
debug_decl(digest_matches, SUDOERS_DEBUG_MATCH);
|
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;
|
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) {
|
TAILQ_FOREACH(digest, digests, entries) {
|
||||||
/* Compute file digest if needed. */
|
/* Compute file digest if needed. */
|
||||||
if (digest->digest_type != digest_type) {
|
if (digest->digest_type != digest_type) {
|
||||||
free(file_digest);
|
free(file_digest);
|
||||||
file_digest = sudo_filedigest(fd, file, digest->digest_type,
|
file_digest = sudo_filedigest(fd, path, digest->digest_type,
|
||||||
&digest_len);
|
&digest_len);
|
||||||
if (lseek(fd, (off_t)0, SEEK_SET) == -1) {
|
if (lseek(fd, (off_t)0, SEEK_SET) == -1) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
|
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,
|
sudo_debug_printf(SUDO_DEBUG_DIAG|SUDO_DEBUG_LINENO,
|
||||||
"%s digest mismatch for %s, expecting %s",
|
"%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);
|
free(sudoers_digest);
|
||||||
sudoers_digest = NULL;
|
sudoers_digest = NULL;
|
||||||
}
|
}
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
bad_format:
|
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));
|
digest->digest_str, digest_type_to_name(digest->digest_type));
|
||||||
done:
|
done:
|
||||||
free(sudoers_digest);
|
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);
|
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 */
|
/* 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 */
|
/* match.c */
|
||||||
struct group;
|
struct group;
|
||||||
|
Reference in New Issue
Block a user