Fix race condition in reading credentials 31/140331/2
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Mon, 24 Jul 2017 12:00:29 +0000 (14:00 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Wed, 26 Jul 2017 09:40:03 +0000 (11:40 +0200)
Race condition scenario:
1. Client connects to service and gets descriptor D.
2. Client sends request R.
3. Client closes connection.
4. Second client connects to service and gets descriptor D
5. Service thread starts to process request R and calls
   getCredentialsFromSocket. Function returns credentials of
   second client.

Change-Id: Id42d58b90147157df9772dd856d4769b8698434b

src/common/include/connection-info.h
src/server/main/include/generic-socket-manager.h
src/server/main/socket-manager.cpp
src/server/service/base-service.cpp
src/server/service/service.cpp

index 006176a..4d8a489 100644 (file)
 #pragma once
 
 #include <map>
+#include <credentials.h>
 #include <generic-socket-manager.h>
 #include <message-buffer.h>
 
 namespace SecurityManager
 {
     struct ConnectionInfo {
+        ConnectionInfo(InterfaceID inter, Credentials crd)
+          : interfaceID(inter)
+          , creds(std::move(crd))
+        {}
+
         InterfaceID interfaceID;
+        Credentials creds;
         MessageBuffer buffer;
     };
 
index 2b69f72..74ba9e1 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <dpl/exception.h>
 
+#include <credentials.h>
 #include <generic-event.h>
 
 extern "C" {
@@ -77,8 +78,14 @@ struct GenericSocketService {
     typedef std::vector<ServiceDescription> ServiceDescriptionVector;
 
     struct AcceptEvent : public GenericEvent {
+        AcceptEvent(ConnectionID connection, InterfaceID interface, Credentials crd)
+          : connectionID(connection)
+          , interfaceID(interface)
+          , creds(std::move(crd))
+        {}
         ConnectionID connectionID;
         InterfaceID interfaceID;
+        Credentials creds;
     };
 
     struct WriteEvent : public GenericEvent {
index 5e69067..5a9835f 100644 (file)
@@ -45,6 +45,7 @@
 #include <dpl/assert.h>
 #include <dpl/errno_string.h>
 
+#include <credentials.h>
 #include <smack-check.h>
 #include <socket-manager.h>
 
@@ -212,10 +213,10 @@ void SocketManager::ReadyForAccept(int sock) {
     desc.service = m_socketDescriptionVector[sock].service;
     desc.useSendMsg = m_socketDescriptionVector[sock].useSendMsg;
 
-    GenericSocketService::AcceptEvent event;
-    event.connectionID.sock = client;
-    event.connectionID.counter = desc.counter;
-    event.interfaceID = desc.interfaceID;
+    GenericSocketService::AcceptEvent event(
+        ConnectionID{client, desc.counter},
+        desc.interfaceID,
+        Credentials::getCredentialsFromSocket(client));
     desc.service->Event(event);
 }
 
index 0acc740..131aa77 100644 (file)
@@ -45,8 +45,10 @@ void BaseService::accept(const AcceptEvent &event)
              " ConnectionID.counter: " << event.connectionID.counter <<
              " ServiceID: " << event.interfaceID);
 
-    auto &info = m_connectionInfoMap[event.connectionID.counter];
-    info.interfaceID = event.interfaceID;
+    m_connectionInfoMap.emplace(
+        std::make_pair(
+            event.connectionID.counter,
+            ConnectionInfo(event.interfaceID, event.creds)));
 }
 
 void BaseService::write(const WriteEvent &event)
@@ -62,7 +64,7 @@ void BaseService::write(const WriteEvent &event)
 void BaseService::process(const ReadEvent &event)
 {
     LogDebug("Read event for counter: " << event.connectionID.counter);
-    auto &info = m_connectionInfoMap[event.connectionID.counter];
+    auto &info = m_connectionInfoMap.at(event.connectionID.counter);
     info.buffer.Push(event.rawBuffer);
 
     // We can get several requests in one package.
index 817c92e..0118280 100644 (file)
@@ -66,8 +66,7 @@ bool Service::processOne(const ConnectionID &conn, MessageBuffer &buffer,
 
     if (IFACE == interfaceID) {
         Try {
-            Credentials creds = Credentials::getCredentialsFromSocket(conn.sock);
-
+            Credentials &creds = m_connectionInfoMap.at(conn.counter).creds;
             // deserialize API call type
             int call_type_int;
             Deserialization::Deserialize(buffer, call_type_int);