From e954b4bdd46a8174da28e349aa52b06297971789 Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Wed, 26 Jan 2022 03:13:06 -0800 Subject: [PATCH] Kernel: Return error from sys$execve() when called with zero arguments There are many assumptions in the stack that argc is not zero, and argv[0] points to a valid string. The recent pwnkit exploit on Linux was able to exploit this assumption in the `pkexec` utility (a SUID-root binary) to escalate from any user to root. By convention `execve(..)` should always be called with at least one valid argument, so lets enforce that semantic to harden the system against vulnerabilities like pwnkit. Reference: https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt --- Kernel/Syscalls/execve.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp index 66319cbe98..6696e9b149 100644 --- a/Kernel/Syscalls/execve.cpp +++ b/Kernel/Syscalls/execve.cpp @@ -851,6 +851,11 @@ ErrorOr Process::sys$execve(Userspace if (params.arguments.length > ARG_MAX || params.environment.length > ARG_MAX) return E2BIG; + // NOTE: The caller is expected to always pass at least one argument by convention, + // the program path that was passed as params.path. + if (params.arguments.length == 0) + return EINVAL; + auto path = TRY(get_syscall_path_argument(params.path)); auto copy_user_strings = [](const auto& list, auto& output) -> ErrorOr {