Add defence code to handle socket read failure 06/141806/2
authorMu-Woong Lee <muwoong.lee@samsung.com>
Tue, 1 Aug 2017 11:44:54 +0000 (20:44 +0900)
committerMu-Woong Lee <muwoong.lee@samsung.com>
Wed, 2 Aug 2017 02:48:04 +0000 (11:48 +0900)
Change-Id: Ic8e1f638d900c7d29804a93bcc1c09a80fde7f45
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
src/agent/AgentSocket.cpp

index e8d45b9..f9d6fb5 100644 (file)
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <errno.h>
 #include <fcntl.h>
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -152,27 +153,43 @@ bool AgentSocket::__readCommand(int msgsock)
 {
        uint16_t id = 0;
        uint8_t length = 0;
-       int rval = 0;
-       char buf[CTX_AGENT_COMMAND_LIMIT] = {0};
-
-       rval = read(msgsock, &id, sizeof(id));
-       IF_FAIL_RETURN_TAG(rval == sizeof(id), false, _E, "read() failed");
+       char command[CTX_AGENT_COMMAND_LIMIT] = {0};
+
+       auto safeRead = [&msgsock](char* buf, size_t count)->bool {
+               do {
+                       int rc = read(msgsock, buf, count);
+                       if (rc < 0) {
+                               if (errno == EAGAIN) {
+                                       continue;
+                               } else {
+                                       _E("Socket read error: %d", errno);
+                                       return false;
+                               }
+                       }
+                       count -= rc;
+                       buf += rc;
+               } while (count > 0);
+               return true;
+       };
+
+       bool success;
+
+       success = safeRead(reinterpret_cast<char*>(&id), sizeof(id));
+       IF_FAIL_RETURN(success, false);
 
        if (id == TERM_MSG_ID) {
                _D("Stop listening...");
                return false;
        }
 
-       rval = read(msgsock, &length, sizeof(length));
-       IF_FAIL_RETURN_TAG(rval == sizeof(length), false, _E, "read() failed");
-
-       rval = read(msgsock, buf, length);
-       IF_FAIL_RETURN_TAG(rval == static_cast<int>(length), false, _E, "read() failed");
-
+       success = safeRead(reinterpret_cast<char*>(&length), sizeof(length));
+       IF_FAIL_RETURN(success, false);
+       IF_FAIL_RETURN_TAG(length > 0 && length <= CTX_AGENT_COMMAND_LIMIT, false, _E, "Invalid command");
 
-       buf[length] = '\0';
+       success = safeRead(command, length);
+       IF_FAIL_RETURN(success, false);
 
-       CommandInfo* info = new CommandInfo(&__pluginLoader, id, length, buf);
+       CommandInfo* info = new CommandInfo(&__pluginLoader, id, length, command);
        g_idle_add(__send_command, info);
 
        return true;