File sudo-fix-bsc-1180687.patch of Package sudo.26711
# HG changeset patch
# User Todd C. Miller <Todd.Miller@sudo.ws>
# Date 1609953360 25200
# Node ID 1d32c53859f99c63c60f23a40001bd80dc555f07
# Parent b0cae3ac8e46a85f1592f178e6e7c22fe4257a5c
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.
diff --git a/include/sudo_util.h b/include/sudo_util.h
index 96cac16..c7bb8b0 100644
--- a/include/sudo_util.h
+++ b/include/sudo_util.h
@@ -215,6 +215,7 @@ __dso_public ssize_t sudo_parseln_v2(char **buf, size_t *bufsize, unsigned int *
/* progname.c */
__dso_public void initprogname(const char *);
+__dso_public void initprogname2(const char *, const char * const *);
/* secure_path.c */
#define SUDO_PATH_SECURE 0
diff --git a/lib/util/progname.c b/lib/util/progname.c
index ffe946c..6f188a8 100644
--- a/lib/util/progname.c
+++ b/lib/util/progname.c
@@ -37,10 +37,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')
@@ -50,6 +51,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);
@@ -62,8 +75,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;
@@ -81,6 +95,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 *
@@ -89,3 +115,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 510c34c..d69d3f2 100644
--- a/lib/util/util.exp.in
+++ b/lib/util/util.exp.in
@@ -1,4 +1,5 @@
@COMPAT_EXP@initprogname
+initprogname2
sudo_arc4random_uniform
sudo_conf_askpass_path_v1
sudo_conf_clear_paths_v1
diff --git a/src/sudo.c b/src/sudo.c
index fbf4bc4..d9e2687 100644
--- a/src/sudo.c
+++ b/src/sudo.c
@@ -315,7 +315,7 @@ main(int argc, char *argv[], char *envp[])
sa.sa_handler = SIG_DFL;
sigaction(WTERMSIG(status), &sa, NULL);
sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys,
- WTERMSIG(status) | 128);
+ WTERMSIG(status) | 128);
kill(getpid(), WTERMSIG(status));
}
sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys,
@@ -326,7 +326,10 @@ main(int argc, char *argv[], char *envp[])
int
os_init_common(int argc, char *argv[], char *envp[])
{
- initprogname(argc > 0 ? argv[0] : "sudo");
+ const char * const allowed_prognames[] = { "sudo", "sudoedit", NULL };
+
+ /* Only allow "sudo" or "sudoedit" as the program name. */
+ initprogname2(argc > 0 ? argv[0] : "sudo", allowed_prognames);
#ifdef STATIC_SUDOERS_PLUGIN
preload_static_symbols();
#endif