summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-01-26 15:25:18 +0100
committerAndreas Kling <kling@serenityos.org>2021-01-26 15:26:37 +0100
commitc7858622ec7b1dfb6ad8b8006814faab7a3ed3c6 (patch)
treef81d7577082c3d47b86e789126f2719970d7cba9
parent1e25d2b734938cdfb9759c72dd7eb33c474693ff (diff)
downloadserenity-c7858622ec7b1dfb6ad8b8006814faab7a3ed3c6.zip
Kernel: Update process promise states on execve() and fork()
We now move the execpromises state into the regular promises, and clear the execpromises state. Also make sure to duplicate the promise state on fork. This fixes an issue where "su" would launch a shell which immediately crashed due to not having pledged "stdio".
-rw-r--r--Kernel/Process.h1
-rw-r--r--Kernel/Syscalls/execve.cpp4
-rw-r--r--Kernel/Syscalls/fork.cpp2
-rw-r--r--Kernel/Syscalls/pledge.cpp4
4 files changed, 10 insertions, 1 deletions
diff --git a/Kernel/Process.h b/Kernel/Process.h
index 3acafcccbb..c761bbabf0 100644
--- a/Kernel/Process.h
+++ b/Kernel/Process.h
@@ -637,6 +637,7 @@ private:
bool m_has_promises { false };
u32 m_promises { 0 };
+ bool m_has_execpromises { false };
u32 m_execpromises { 0 };
VeilState m_veil_state { VeilState::None };
diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp
index 1348582663..b6ebe30e66 100644
--- a/Kernel/Syscalls/execve.cpp
+++ b/Kernel/Syscalls/execve.cpp
@@ -544,6 +544,10 @@ int Process::do_exec(NonnullRefPtr<FileDescription> main_program_description, Ve
m_environment = environment;
m_promises = m_execpromises;
+ m_has_promises = m_has_execpromises;
+
+ m_execpromises = 0;
+ m_has_execpromises = false;
m_veil_state = VeilState::None;
m_unveiled_paths.clear();
diff --git a/Kernel/Syscalls/fork.cpp b/Kernel/Syscalls/fork.cpp
index edf359c3a5..db600ee562 100644
--- a/Kernel/Syscalls/fork.cpp
+++ b/Kernel/Syscalls/fork.cpp
@@ -43,6 +43,8 @@ pid_t Process::sys$fork(RegisterState& regs)
child->m_root_directory_relative_to_global_root = m_root_directory_relative_to_global_root;
child->m_promises = m_promises;
child->m_execpromises = m_execpromises;
+ child->m_has_promises = m_has_promises;
+ child->m_has_execpromises = m_has_execpromises;
child->m_veil_state = m_veil_state;
child->m_unveiled_paths = m_unveiled_paths.deep_copy();
child->m_fds = m_fds;
diff --git a/Kernel/Syscalls/pledge.cpp b/Kernel/Syscalls/pledge.cpp
index d101295ee7..0613ab575e 100644
--- a/Kernel/Syscalls/pledge.cpp
+++ b/Kernel/Syscalls/pledge.cpp
@@ -84,7 +84,9 @@ int Process::sys$pledge(Userspace<const Syscall::SC_pledge_params*> user_params)
return -EPERM;
}
- m_has_promises = true;
+ m_has_promises = m_has_promises || !promises.is_null();
+ m_has_execpromises = m_has_execpromises || !execpromises.is_null();
+
m_promises = new_promises;
m_execpromises = new_execpromises;