summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Lelli <toadking@toadking.com>2020-05-02 17:41:18 -0500
committerGitHub <noreply@github.com>2020-05-03 00:41:18 +0200
commit58a34fbe09a7bb54f98310da3543468ec95b195f (patch)
treeace570097bec6ef7695070e436083f6ee6b9741c
parent37d1b0c8759435f757858b9a6ed04b8abe261692 (diff)
downloadserenity-58a34fbe09a7bb54f98310da3543468ec95b195f.zip
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.
-rw-r--r--Kernel/Process.cpp16
-rw-r--r--Tests/Kernel/pledge-test-failures.cpp25
2 files changed, 37 insertions, 4 deletions
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 <stdio.h>
+#include <unistd.h>
+
+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;
+}