From b132def0b19c018ed23093d40d1471b6f2d47e28 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Wed, 6 Jan 2021 10:16:00 -0700 Subject: [PATCH] For sudo, only allow "sudo" or "sudoedit" as the program name. The program name is also used when matching Debug lines in sudo.conf. We don't want the user to be able to influence sudo.conf Debug matching. The string "sudoedit" is treated the same as "sudo" in sudo.conf. Problem reported by Matthias Gerstner of SUSE. --- include/sudo_util.h | 1 + lib/util/progname.c | 36 ++++++++++++++++++++++++++++++++++-- lib/util/util.exp.in | 1 + src/sudo.c | 4 +++- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/include/sudo_util.h b/include/sudo_util.h index 3448149ba..eb4c81c60 100644 --- a/include/sudo_util.h +++ b/include/sudo_util.h @@ -244,6 +244,7 @@ sudo_dso_public ssize_t sudo_parseln_v2(char **buf, size_t *bufsize, unsigned in /* progname.c */ sudo_dso_public void initprogname(const char *); +sudo_dso_public void initprogname2(const char *, const char * const *); /* roundup.c */ sudo_dso_public unsigned int sudo_pow2_roundup_v1(unsigned int len); diff --git a/lib/util/progname.c b/lib/util/progname.c index 994a86909..d1bf15d15 100644 --- a/lib/util/progname.c +++ b/lib/util/progname.c @@ -32,10 +32,11 @@ #ifdef HAVE_GETPROGNAME void -initprogname(const char *name) +initprogname2(const char *name, const char * const * allowed) { # ifdef HAVE_SETPROGNAME const char *progname; + int i; /* Fall back on "name" if getprogname() returns an empty string. */ if ((progname = getprogname()) != NULL && *progname != '\0') @@ -45,6 +46,18 @@ initprogname(const char *name) if (name[0] == 'l' && name[1] == 't' && name[2] == '-' && name[3] != '\0') name += 3; + /* Check allow list if present (first element is the default). */ + if (allowed != NULL) { + for (i = 0; ; i++) { + if (allowed[i] == NULL) { + name = allowed[0]; + break; + } + if (strcmp(allowed[i], name) == 0) + break; + } + } + /* Update internal progname if needed. */ if (name != progname) setprogname(name); @@ -57,8 +70,9 @@ initprogname(const char *name) static const char *progname = ""; void -initprogname(const char *name) +initprogname2(const char *name, const char * const * allowed) { + int i; # ifdef HAVE___PROGNAME extern const char *__progname; @@ -76,6 +90,18 @@ initprogname(const char *name) if (progname[0] == 'l' && progname[1] == 't' && progname[2] == '-' && progname[3] != '\0') progname += 3; + + /* Check allow list if present (first element is the default). */ + if (allowed != NULL) { + for (i = 0; ; i++) { + if (allowed[i] == NULL) { + progname = allowed[0]; + break; + } + if (strcmp(allowed[i], progname) == 0) + break; + } + } } const char * @@ -84,3 +110,9 @@ sudo_getprogname(void) return progname; } #endif /* !HAVE_GETPROGNAME */ + +void +initprogname(const char *name) +{ + initprogname2(name, NULL); +} diff --git a/lib/util/util.exp.in b/lib/util/util.exp.in index 6095623fd..b0b56f09b 100644 --- a/lib/util/util.exp.in +++ b/lib/util/util.exp.in @@ -1,4 +1,5 @@ @COMPAT_EXP@initprogname +initprogname2 sudo_conf_askpass_path_v1 sudo_conf_clear_paths_v1 sudo_conf_debug_files_v1 diff --git a/src/sudo.c b/src/sudo.c index 9d60e1b6d..e4669b305 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -152,12 +152,14 @@ main(int argc, char *argv[], char *envp[]) int nargc, status = 0; char **nargv, **env_add, **user_info; char **command_info = NULL, **argv_out = NULL, **user_env_out = NULL; + const char * const allowed_prognames[] = { "sudo", "sudoedit", NULL }; struct sudo_settings *settings; int submit_optind; sigset_t mask; debug_decl_vars(main, SUDO_DEBUG_MAIN); - initprogname(argc > 0 ? argv[0] : "sudo"); + /* Only allow "sudo" or "sudoedit" as the program name. */ + initprogname2(argc > 0 ? argv[0] : "sudo", allowed_prognames); /* Crank resource limits to unlimited. */ unlimit_sudo();