mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 20:07:34 +00:00
Shell: Limit the access of processes spawned for autocompletion
This commit limits the autocomplete processes to effectively have readonly access to the fs, and only enough pledges to get the dynamic loader working.
This commit is contained in:
parent
8233da3398
commit
f12d81ddf5
2 changed files with 51 additions and 0 deletions
|
@ -844,6 +844,14 @@ ErrorOr<RefPtr<Job>> Shell::run_command(const AST::Command& command)
|
||||||
|
|
||||||
void Shell::execute_process(Vector<const char*>&& argv)
|
void Shell::execute_process(Vector<const char*>&& argv)
|
||||||
{
|
{
|
||||||
|
#ifdef __serenity__
|
||||||
|
for (auto& promise : m_active_promises) {
|
||||||
|
pledge("exec", promise.data.exec_promises.characters());
|
||||||
|
for (auto& item : promise.data.unveils)
|
||||||
|
unveil(item.path.characters(), item.access.characters());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int rc = execvp(argv[0], const_cast<char* const*>(argv.data()));
|
int rc = execvp(argv[0], const_cast<char* const*>(argv.data()));
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
auto parts = StringView { argv[0] }.split_view('/');
|
auto parts = StringView { argv[0] }.split_view('/');
|
||||||
|
@ -1833,6 +1841,13 @@ ErrorOr<Vector<Line::CompletionSuggestion>> Shell::complete_via_program_itself(s
|
||||||
});
|
});
|
||||||
timer->start();
|
timer->start();
|
||||||
|
|
||||||
|
// Restrict the process to effectively readonly access to the FS.
|
||||||
|
auto scoped_promise = promise({
|
||||||
|
.exec_promises = "stdio rpath prot_exec no_error",
|
||||||
|
.unveils = {
|
||||||
|
{ "/", "rx" },
|
||||||
|
},
|
||||||
|
});
|
||||||
execute_node->for_each_entry(*this, [&](NonnullRefPtr<AST::Value> entry) -> IterationDecision {
|
execute_node->for_each_entry(*this, [&](NonnullRefPtr<AST::Value> entry) -> IterationDecision {
|
||||||
auto result = entry->resolve_as_string(*this);
|
auto result = entry->resolve_as_string(*this);
|
||||||
JsonParser parser(result);
|
JsonParser parser(result);
|
||||||
|
|
|
@ -159,6 +159,41 @@ public:
|
||||||
[[nodiscard]] Frame push_frame(String name);
|
[[nodiscard]] Frame push_frame(String name);
|
||||||
void pop_frame();
|
void pop_frame();
|
||||||
|
|
||||||
|
struct Promise {
|
||||||
|
struct Data {
|
||||||
|
struct Unveil {
|
||||||
|
String path;
|
||||||
|
String access;
|
||||||
|
};
|
||||||
|
String exec_promises;
|
||||||
|
Vector<Unveil> unveils;
|
||||||
|
} data;
|
||||||
|
|
||||||
|
IntrusiveListNode<Promise> node;
|
||||||
|
using List = IntrusiveList<&Promise::node>;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ScopedPromise {
|
||||||
|
ScopedPromise(Promise::List& promises, Promise&& promise)
|
||||||
|
: promises(promises)
|
||||||
|
, promise(move(promise))
|
||||||
|
{
|
||||||
|
promises.append(this->promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
~ScopedPromise()
|
||||||
|
{
|
||||||
|
promises.remove(promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise::List& promises;
|
||||||
|
Promise promise;
|
||||||
|
};
|
||||||
|
[[nodiscard]] ScopedPromise promise(Promise::Data data)
|
||||||
|
{
|
||||||
|
return { m_active_promises, { move(data), {} } };
|
||||||
|
}
|
||||||
|
|
||||||
enum class EscapeMode {
|
enum class EscapeMode {
|
||||||
Bareword,
|
Bareword,
|
||||||
SingleQuotedString,
|
SingleQuotedString,
|
||||||
|
@ -362,6 +397,7 @@ private:
|
||||||
|
|
||||||
HashMap<String, ShellFunction> m_functions;
|
HashMap<String, ShellFunction> m_functions;
|
||||||
NonnullOwnPtrVector<LocalFrame> m_local_frames;
|
NonnullOwnPtrVector<LocalFrame> m_local_frames;
|
||||||
|
Promise::List m_active_promises;
|
||||||
NonnullRefPtrVector<AST::Redirection> m_global_redirections;
|
NonnullRefPtrVector<AST::Redirection> m_global_redirections;
|
||||||
|
|
||||||
HashMap<String, String> m_aliases;
|
HashMap<String, String> m_aliases;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue