git: 151922253f92 - stable/12 - execve: disallow argc == 0

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Thu, 10 Feb 2022 20:22:21 UTC
The branch stable/12 has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=151922253f927350a3f427d100b6291a7b8d676e

commit 151922253f927350a3f427d100b6291a7b8d676e
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2022-01-25 22:47:23 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2022-02-10 20:17:27 +0000

    execve: disallow argc == 0
    
    The manpage has contained the following verbiage on the matter for just
    under 31 years:
    
    "At least one argument must be present in the array"
    
    Previous to this version, it had been prefaced with the weakening phrase
    "By convention."
    
    Carry through and document it the rest of the way.  Allowing argc == 0
    has been a source of security issues in the past, and it's hard to
    imagine a valid use-case for allowing it.  Toss back EINVAL if we ended
    up not copying in any args for *execve().
    
    The manpage change can be considered "Obtained from: OpenBSD"
    
    (cherry picked from commit 773fa8cd136a5775241c3e3a70f1997633ebeedf)
    (cherry picked from commit c9afc7680f3e1f0510518de9de4264553a31aade)
---
 lib/libc/sys/execve.2                 | 5 ++++-
 lib/libc/tests/gen/posix_spawn_test.c | 9 +++------
 sys/kern/kern_exec.c                  | 6 ++++++
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/lib/libc/sys/execve.2 b/lib/libc/sys/execve.2
index 20b73342f96e..2b9bed41a10f 100644
--- a/lib/libc/sys/execve.2
+++ b/lib/libc/sys/execve.2
@@ -28,7 +28,7 @@
 .\"     @(#)execve.2	8.5 (Berkeley) 6/1/94
 .\" $FreeBSD$
 .\"
-.Dd March 30, 2020
+.Dd January 26, 2022
 .Dt EXECVE 2
 .Os
 .Sh NAME
@@ -273,6 +273,9 @@ Search permission is denied for a component of the path prefix.
 The new process file is not an ordinary file.
 .It Bq Er EACCES
 The new process file mode denies execute permission.
+.It Bq Er EINVAL
+.Fa argv
+did not contain at least one element.
 .It Bq Er ENOEXEC
 The new process file has the appropriate access
 permission, but has an invalid magic number in its header.
diff --git a/lib/libc/tests/gen/posix_spawn_test.c b/lib/libc/tests/gen/posix_spawn_test.c
index 5e2c485473d0..46259cbf8cde 100644
--- a/lib/libc/tests/gen/posix_spawn_test.c
+++ b/lib/libc/tests/gen/posix_spawn_test.c
@@ -117,17 +117,14 @@ ATF_TC_BODY(posix_spawnp_enoexec_fallback_null_argv0, tc)
 {
 	char buf[FILENAME_MAX];
 	char *myargs[1];
-	int error, status;
-	pid_t pid, waitres;
+	int error;
+	pid_t pid;
 
 	snprintf(buf, sizeof(buf), "%s/spawnp_enoexec.sh",
 	    atf_tc_get_config_var(tc, "srcdir"));
 	myargs[0] = NULL;
 	error = posix_spawnp(&pid, buf, NULL, NULL, myargs, myenv);
-	ATF_REQUIRE(error == 0);
-	waitres = waitpid(pid, &status, 0);
-	ATF_REQUIRE(waitres == pid);
-	ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 42);
+	ATF_REQUIRE(error == EINVAL);
 }
 
 ATF_TP_ADD_TCS(tp)
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 64c9e84db07c..acc2d38ba689 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -349,6 +349,12 @@ kern_execve(struct thread *td, struct image_args *args, struct mac *mac_p,
 	    args->begin_envv - args->begin_argv);
 	AUDIT_ARG_ENVV(args->begin_envv, args->envc,
 	    args->endp - args->begin_envv);
+
+	/* Must have at least one argument. */
+	if (args->argc == 0) {
+		exec_free_args(args);
+		return (EINVAL);
+	}
 	return (do_execve(td, args, mac_p, oldvmspace));
 }