From 36ff717c540873fcfc2f32accb9520e96e56b1cd Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Fri, 23 Jul 2021 09:14:35 -0700 Subject: [PATCH] Kernel: Migrate sys$pledge to use the KString API This avoids potential unhandled OOM that's possible with the old copy_string_from_user API. --- Kernel/Syscalls/pledge.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/Kernel/Syscalls/pledge.cpp b/Kernel/Syscalls/pledge.cpp index 07a46e49f89..ecd0a25b7b4 100644 --- a/Kernel/Syscalls/pledge.cpp +++ b/Kernel/Syscalls/pledge.cpp @@ -19,21 +19,23 @@ KResultOr Process::sys$pledge(Userspace 1024 || params.execpromises.length > 1024) return E2BIG; - String promises; + OwnPtr promises; if (params.promises.characters) { - promises = copy_string_from_user(params.promises); - if (promises.is_null()) - return EFAULT; + auto promises_or_error = try_copy_kstring_from_user(params.promises); + if (promises_or_error.is_error()) + return promises_or_error.error(); + promises = promises_or_error.release_value(); } - String execpromises; + OwnPtr execpromises; if (params.execpromises.characters) { - execpromises = copy_string_from_user(params.execpromises); - if (execpromises.is_null()) - return EFAULT; + auto execpromises_or_error = try_copy_kstring_from_user(params.execpromises); + if (execpromises_or_error.is_error()) + return execpromises_or_error.error(); + execpromises = execpromises_or_error.release_value(); } - auto parse_pledge = [&](auto& pledge_spec, u32& mask) { + auto parse_pledge = [&](auto pledge_spec, u32& mask) { auto parts = pledge_spec.split_view(' '); for (auto& part : parts) { #define __ENUMERATE_PLEDGE_PROMISE(x) \ @@ -50,20 +52,19 @@ KResultOr Process::sys$pledge(Userspaceview(), new_promises)) return EINVAL; if (m_has_promises && (new_promises & ~m_promises)) return EPERM; - m_has_promises = true; m_promises = new_promises; } - if (!execpromises.is_null()) { + if (execpromises) { u32 new_execpromises = 0; - if (!parse_pledge(execpromises, new_execpromises)) + if (!parse_pledge(execpromises->view(), new_execpromises)) return EINVAL; if (m_has_execpromises && (new_execpromises & ~m_execpromises)) return EPERM;