Add mitigation for DDOS attack 59/309859/2
authorTomasz Swierczek <t.swierczek@samsung.com>
Wed, 17 Apr 2024 11:48:46 +0000 (13:48 +0200)
committerTomasz Swierczek <t.swierczek@samsung.com>
Wed, 17 Apr 2024 12:34:23 +0000 (14:34 +0200)
Adversary can send too big message to the daemon,
making it fail on allocation. Few places were required
to be enhanced with catch for std::bad_alloc & proper
graceful closing of connection instead of terminating
the process.

Change-Id: Id05dd3ee3d323a8d47ba93e33fae9d9bc6bb255d

src/common/channel.cpp
src/common/connection.cpp
src/server/main/socket-manager.cpp

index 79664c8358710344ea83a69dfc127c17af620502..3cb5850a1b5ec0c0a0871e7c43faf7262a30fb6b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2017-2024 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * This file is licensed under the terms of MIT License or the Apache License
  * Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
@@ -31,6 +31,7 @@
 #include <utility>
 
 #include <channel.h>
+#include <dpl/log/log.h>
 
 #define BUFFER_SIZE 4096
 
@@ -96,14 +97,19 @@ bool Channel::read(MessageBuffer &buffer)
         const auto s = TEMP_FAILURE_RETRY(::read(m_in, buffer.Ptr(), buffer.InputSize()));
         if (s <= 0)
             return false;
-        switch (buffer.InputDone(s)) {
-            case MessageBuffer::InputResult::ProtocolBroken:
-                return false;
-            case MessageBuffer::InputResult::Pending:
-                break;
-            case MessageBuffer::InputResult::Done:
-                buffer.ModeStreaming();
-                return true;
+        try {
+            switch (buffer.InputDone(s)) {
+                case MessageBuffer::InputResult::ProtocolBroken:
+                    return false;
+                case MessageBuffer::InputResult::Pending:
+                    break;
+                case MessageBuffer::InputResult::Done:
+                    buffer.ModeStreaming();
+                    return true;
+            }
+        } catch (const std::bad_alloc &e) {
+            LogError("Allocation problem in channel::read " << e.what());
+            return false;
         }
     }
 }
index 73fdfa22f8a625bb0ede026934c25a622264e89d..3721c9e65213c74b06231fe0fbac59dd5db8fb92 100644 (file)
@@ -207,14 +207,19 @@ int sendToServer(char const * const interface, MessageBuffer &buffer) {
                 LogErrno("read");
             return SECURITY_MANAGER_ERROR_SOCKET;
         }
-        switch (buffer.InputDone(temp)) {
-            case MessageBuffer::InputResult::ProtocolBroken:
-                return SECURITY_MANAGER_ERROR_SOCKET;
-            case MessageBuffer::InputResult::Pending:
-                break;
-            case MessageBuffer::InputResult::Done:
-                buffer.ModeStreaming();
-                return SECURITY_MANAGER_SUCCESS;
+        try {
+            switch (buffer.InputDone(temp)) {
+                case MessageBuffer::InputResult::ProtocolBroken:
+                    return SECURITY_MANAGER_ERROR_SOCKET;
+                case MessageBuffer::InputResult::Pending:
+                    break;
+                case MessageBuffer::InputResult::Done:
+                    buffer.ModeStreaming();
+                    return SECURITY_MANAGER_SUCCESS;
+            }
+        } catch (const std::bad_alloc &e) {
+            LogError("Allocation problem in sendToServer " << e.what());
+            return SECURITY_MANAGER_ERROR_SOCKET;
         }
     }
 }
index b6f0a6afa17f4aaa10627271fa6be4c2544aea45..63e493df852b32d823f140f6054763fe7d0bdee9 100644 (file)
@@ -180,31 +180,36 @@ void SocketManager::ReadyForRead(int sock) {
                 goto close;
         }
     } else {
-        switch (buffer.InputDone(size)) {
-            case MessageBuffer::InputResult::ProtocolBroken:
-                goto close;
-            case MessageBuffer::InputResult::Pending:
-                break;
-            case MessageBuffer::InputResult::Done:
-                buffer.ModeStreaming();
-
-                if (buffer.DeserializationDone()) {
-                    LogError("No priority, closing socket");
-                    goto close;
-                }
-                std::underlying_type_t<Priority> priority;
-                Deserialization::Deserialize(buffer, priority);
-                if (priority >= Priority::END) {
-                    LogError("Invalid priority: " << priority);
+        try {
+            switch (buffer.InputDone(size)) {
+                case MessageBuffer::InputResult::ProtocolBroken:
                     goto close;
-                }
-
-                FD_CLR(sock, &m_readSet); // the one and only call on this socket is complete
-                m_service->PutEvent(static_cast<Priority>(priority),
-                        ConnectionID{sock, desc.counter},
-                        Credentials::getCredentialsFromSocket(sock),
-                        std::move(buffer));
-                break;
+                case MessageBuffer::InputResult::Pending:
+                    break;
+                case MessageBuffer::InputResult::Done:
+                    buffer.ModeStreaming();
+
+                    if (buffer.DeserializationDone()) {
+                        LogError("No priority, closing socket");
+                        goto close;
+                    }
+                    std::underlying_type_t<Priority> priority;
+                    Deserialization::Deserialize(buffer, priority);
+                    if (priority >= Priority::END) {
+                        LogError("Invalid priority: " << priority);
+                        goto close;
+                    }
+
+                    FD_CLR(sock, &m_readSet); // the one and only call on this socket is complete
+                    m_service->PutEvent(static_cast<Priority>(priority),
+                            ConnectionID{sock, desc.counter},
+                            Credentials::getCredentialsFromSocket(sock),
+                            std::move(buffer));
+                    break;
+            }
+        } catch (const std::bad_alloc &e) {
+            LogError("Allocation problem in ReadyForRead " << e.what());
+            goto close;
         }
     }