1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 14:27:35 +00:00

Kernel: Enable SMAP protection during the execve() syscall

The userspace execve() wrapper now measures all the strings and puts
them in a neat and tidy structure on the stack.

This way we know exactly how much to copy in the kernel, and we don't
have to use the SMAP-violating validate_read_str(). :^)
This commit is contained in:
Andreas Kling 2020-01-10 12:20:36 +01:00
parent bf9f36bf22
commit 952bb95baa
4 changed files with 78 additions and 38 deletions

View file

@ -2,6 +2,7 @@
#include <AK/String.h>
#include <AK/Vector.h>
#include <Kernel/Syscall.h>
#include <alloca.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
@ -49,7 +50,31 @@ int execv(const char* path, char* const argv[])
int execve(const char* filename, char* const argv[], char* const envp[])
{
int rc = syscall(SC_execve, filename, argv, envp);
size_t arg_count = 0;
for (size_t i = 0; argv[i]; ++i)
++arg_count;
size_t env_count = 0;
for (size_t i = 0; envp[i]; ++i)
++env_count;
auto copy_strings = [&](auto& vec, size_t count, auto& output) {
output.length = count;
for (size_t i = 0; vec[i]; ++i) {
output.strings[i].characters = vec[i];
output.strings[i].length = strlen(vec[i]);
}
};
Syscall::SC_execve_params params;
params.arguments.strings = (Syscall::SyscallString*)alloca(arg_count * sizeof(Syscall::SyscallString));
params.environment.strings = (Syscall::SyscallString*)alloca(env_count * sizeof(Syscall::SyscallString));
params.path = { filename, strlen(filename) };
copy_strings(argv, arg_count, params.arguments);
copy_strings(envp, env_count, params.environment);
int rc = syscall(SC_execve, &params);
__RETURN_WITH_ERRNO(rc, rc, -1);
}