Browse Source

hle: kernel: hle_ipc: Ensure SessionRequestHandler is valid.

bunnei 5 năm trước cách đây
mục cha
commit
08d798b6fe

+ 15 - 0
src/core/hle/kernel/hle_ipc.cpp

@@ -41,6 +41,21 @@ SessionRequestManager::SessionRequestManager(KernelCore& kernel_) : kernel{kerne
 
 
 SessionRequestManager::~SessionRequestManager() = default;
 SessionRequestManager::~SessionRequestManager() = default;
 
 
+bool SessionRequestManager::HasSessionRequestHandler(const HLERequestContext& context) const {
+    if (IsDomain() && context.HasDomainMessageHeader()) {
+        const auto& message_header = context.GetDomainMessageHeader();
+        const auto object_id = message_header.object_id;
+
+        if (object_id > DomainHandlerCount()) {
+            LOG_CRITICAL(IPC, "object_id {} is too big!", object_id);
+            return false;
+        }
+        return DomainHandler(object_id - 1) != nullptr;
+    } else {
+        return session_handler != nullptr;
+    }
+}
+
 void SessionRequestHandler::ClientConnected(KServerSession* session) {
 void SessionRequestHandler::ClientConnected(KServerSession* session) {
     session->SetSessionHandler(shared_from_this());
     session->SetSessionHandler(shared_from_this());
 }
 }

+ 2 - 1
src/core/hle/kernel/hle_ipc.h

@@ -156,6 +156,8 @@ public:
         return session_handler->GetServiceThread();
         return session_handler->GetServiceThread();
     }
     }
 
 
+    bool HasSessionRequestHandler(const HLERequestContext& context) const;
+
 private:
 private:
     bool is_domain{};
     bool is_domain{};
     SessionRequestHandlerPtr session_handler;
     SessionRequestHandlerPtr session_handler;
@@ -163,7 +165,6 @@ private:
 
 
 private:
 private:
     KernelCore& kernel;
     KernelCore& kernel;
-    std::weak_ptr<ServiceThread> service_thread;
 };
 };
 
 
 /**
 /**

+ 9 - 4
src/core/hle/kernel/k_server_session.cpp

@@ -119,11 +119,16 @@ ResultCode KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memor
 
 
     context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
     context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
 
 
-    if (auto strong_ptr = manager->GetServiceThread().lock()) {
-        strong_ptr->QueueSyncRequest(*parent, std::move(context));
-        return ResultSuccess;
+    // Ensure we have a session request handler
+    if (manager->HasSessionRequestHandler(*context)) {
+        if (auto strong_ptr = manager->GetServiceThread().lock()) {
+            strong_ptr->QueueSyncRequest(*parent, std::move(context));
+            return ResultSuccess;
+        } else {
+            ASSERT_MSG(false, "strong_ptr is nullptr!");
+        }
     } else {
     } else {
-        ASSERT_MSG(false, "strong_ptr was nullptr!");
+        ASSERT_MSG(false, "handler is invalid!");
     }
     }
 
 
     return ResultSuccess;
     return ResultSuccess;