From 58a34fbe09a7bb54f98310da3543468ec95b195f Mon Sep 17 00:00:00 2001 From: Michael Lelli Date: Sat, 2 May 2020 17:41:18 -0500 Subject: Kernel: Fix pledge syscall applying new pledges when it fails (#2076) If the exec promises fail to apply, then the normal promises should not apply either. Add a test for this fixed functionality. --- Kernel/Process.cpp | 16 ++++++++++++---- Tests/Kernel/pledge-test-failures.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 Tests/Kernel/pledge-test-failures.cpp diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 31dacfbfc5..97456e180c 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -4826,24 +4826,32 @@ int Process::sys$pledge(const Syscall::SC_pledge_params* user_params) return true; }; + u32 new_promises; + u32 new_execpromises; + if (!promises.is_null()) { - u32 new_promises = 0; + new_promises = 0; if (!parse_pledge(promises, new_promises)) return -EINVAL; if (m_promises && (!new_promises || new_promises & ~m_promises)) return -EPERM; - m_promises = new_promises; + } else { + new_promises = m_promises; } if (!execpromises.is_null()) { - u32 new_execpromises = 0; + new_execpromises = 0; if (!parse_pledge(execpromises, new_execpromises)) return -EINVAL; if (m_execpromises && (!new_execpromises || new_execpromises & ~m_execpromises)) return -EPERM; - m_execpromises = new_execpromises; + } else { + new_execpromises = m_execpromises; } + m_promises = new_promises; + m_execpromises = new_execpromises; + return 0; } diff --git a/Tests/Kernel/pledge-test-failures.cpp b/Tests/Kernel/pledge-test-failures.cpp new file mode 100644 index 0000000000..c085f2368c --- /dev/null +++ b/Tests/Kernel/pledge-test-failures.cpp @@ -0,0 +1,25 @@ +#include +#include + +int main(int argc, char** argv) +{ + int res = pledge("stdio unix rpath", "stdio"); + if (res < 0) { + perror("pledge"); + return 1; + } + + res = pledge("stdio unix", "stdio unix"); + if (res >= 0) { + fprintf(stderr, "second pledge should have failed\n"); + return 1; + } + + res = pledge("stdio rpath", "stdio"); + if (res < 0) { + perror("pledge"); + return 1; + } + + return 0; +} -- cgit v1.2.3