
# 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.

Index: sudo-1.8.22/include/sudo_util.h
===================================================================
--- sudo-1.8.22.orig/include/sudo_util.h
+++ sudo-1.8.22/include/sudo_util.h
@@ -199,6 +199,7 @@ __dso_public ssize_t sudo_parseln_v2(cha
 
 /* 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
Index: sudo-1.8.22/lib/util/progname.c
===================================================================
--- sudo-1.8.22.orig/lib/util/progname.c
+++ sudo-1.8.22/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);
+}
Index: sudo-1.8.22/lib/util/util.exp.in
===================================================================
--- sudo-1.8.22.orig/lib/util/util.exp.in
+++ sudo-1.8.22/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
Index: sudo-1.8.22/src/sudo.c
===================================================================
--- sudo-1.8.22.orig/src/sudo.c
+++ sudo-1.8.22/src/sudo.c
@@ -312,7 +312,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,
@@ -323,7 +323,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
