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.
This commit is contained in:
Todd C. Miller
2021-01-06 10:16:00 -07:00
parent a29cac8bd6
commit b132def0b1
4 changed files with 39 additions and 3 deletions

View File

@@ -244,6 +244,7 @@ sudo_dso_public ssize_t sudo_parseln_v2(char **buf, size_t *bufsize, unsigned in
/* progname.c */ /* progname.c */
sudo_dso_public void initprogname(const char *); sudo_dso_public void initprogname(const char *);
sudo_dso_public void initprogname2(const char *, const char * const *);
/* roundup.c */ /* roundup.c */
sudo_dso_public unsigned int sudo_pow2_roundup_v1(unsigned int len); sudo_dso_public unsigned int sudo_pow2_roundup_v1(unsigned int len);

View File

@@ -32,10 +32,11 @@
#ifdef HAVE_GETPROGNAME #ifdef HAVE_GETPROGNAME
void void
initprogname(const char *name) initprogname2(const char *name, const char * const * allowed)
{ {
# ifdef HAVE_SETPROGNAME # ifdef HAVE_SETPROGNAME
const char *progname; const char *progname;
int i;
/* Fall back on "name" if getprogname() returns an empty string. */ /* Fall back on "name" if getprogname() returns an empty string. */
if ((progname = getprogname()) != NULL && *progname != '\0') 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') if (name[0] == 'l' && name[1] == 't' && name[2] == '-' && name[3] != '\0')
name += 3; 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. */ /* Update internal progname if needed. */
if (name != progname) if (name != progname)
setprogname(name); setprogname(name);
@@ -57,8 +70,9 @@ initprogname(const char *name)
static const char *progname = ""; static const char *progname = "";
void void
initprogname(const char *name) initprogname2(const char *name, const char * const * allowed)
{ {
int i;
# ifdef HAVE___PROGNAME # ifdef HAVE___PROGNAME
extern const char *__progname; extern const char *__progname;
@@ -76,6 +90,18 @@ initprogname(const char *name)
if (progname[0] == 'l' && progname[1] == 't' && progname[2] == '-' && if (progname[0] == 'l' && progname[1] == 't' && progname[2] == '-' &&
progname[3] != '\0') progname[3] != '\0')
progname += 3; 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 * const char *
@@ -84,3 +110,9 @@ sudo_getprogname(void)
return progname; return progname;
} }
#endif /* !HAVE_GETPROGNAME */ #endif /* !HAVE_GETPROGNAME */
void
initprogname(const char *name)
{
initprogname2(name, NULL);
}

View File

@@ -1,4 +1,5 @@
@COMPAT_EXP@initprogname @COMPAT_EXP@initprogname
initprogname2
sudo_conf_askpass_path_v1 sudo_conf_askpass_path_v1
sudo_conf_clear_paths_v1 sudo_conf_clear_paths_v1
sudo_conf_debug_files_v1 sudo_conf_debug_files_v1

View File

@@ -152,12 +152,14 @@ main(int argc, char *argv[], char *envp[])
int nargc, status = 0; int nargc, status = 0;
char **nargv, **env_add, **user_info; char **nargv, **env_add, **user_info;
char **command_info = NULL, **argv_out = NULL, **user_env_out = NULL; char **command_info = NULL, **argv_out = NULL, **user_env_out = NULL;
const char * const allowed_prognames[] = { "sudo", "sudoedit", NULL };
struct sudo_settings *settings; struct sudo_settings *settings;
int submit_optind; int submit_optind;
sigset_t mask; sigset_t mask;
debug_decl_vars(main, SUDO_DEBUG_MAIN); 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. */ /* Crank resource limits to unlimited. */
unlimit_sudo(); unlimit_sudo();