소스 검색

Userland: Unveil /usr/lib/Loader.so when using 'x' permissions on unveil

We should not rely on the Kernel to unveil this for us, so if a program
needs to execute another program it should unveil the dynamic loader too
to prevent crashing.
To do this, we check if the user program tried to unveil a binary with
at least using the 'x' permission, so we will try to also unveil the
dynamic loader too.
Liav A 2 년 전
부모
커밋
d102ea5f81
1개의 변경된 파일24개의 추가작업 그리고 0개의 파일을 삭제
  1. 24 0
      Userland/Libraries/LibCore/System.cpp

+ 24 - 0
Userland/Libraries/LibCore/System.cpp

@@ -81,10 +81,34 @@ ErrorOr<void> pledge(StringView promises, StringView execpromises)
     HANDLE_SYSCALL_RETURN_VALUE("pledge", rc, {});
     HANDLE_SYSCALL_RETURN_VALUE("pledge", rc, {});
 }
 }
 
 
+static ErrorOr<void> unveil_dynamic_loader()
+{
+    static bool dynamic_loader_unveiled { false };
+    if (dynamic_loader_unveiled)
+        return {};
+    // FIXME: Try to find a way to not hardcode the dynamic loader path.
+    constexpr auto dynamic_loader_path = "/usr/lib/Loader.so"sv;
+    constexpr auto dynamic_loader_permissions = "x"sv;
+
+    Syscall::SC_unveil_params params {
+        { dynamic_loader_path.characters_without_null_termination(), dynamic_loader_path.length() },
+        { dynamic_loader_permissions.characters_without_null_termination(), dynamic_loader_permissions.length() },
+    };
+    int rc = syscall(SC_unveil, &params);
+    if (rc < 0) {
+        return Error::from_syscall("unveil (DynamicLoader @ /usr/lib/Loader.so)"sv, rc);
+    }
+    dynamic_loader_unveiled = true;
+    return {};
+}
+
 ErrorOr<void> unveil(StringView path, StringView permissions)
 ErrorOr<void> unveil(StringView path, StringView permissions)
 {
 {
     auto const parsed_path = TRY(Core::SessionManagement::parse_path_with_sid(path));
     auto const parsed_path = TRY(Core::SessionManagement::parse_path_with_sid(path));
 
 
+    if (permissions.contains('x'))
+        TRY(unveil_dynamic_loader());
+
     Syscall::SC_unveil_params params {
     Syscall::SC_unveil_params params {
         { parsed_path.characters(), parsed_path.length() },
         { parsed_path.characters(), parsed_path.length() },
         { permissions.characters_without_null_termination(), permissions.length() },
         { permissions.characters_without_null_termination(), permissions.length() },