From: Tomasz Swierczek Date: Wed, 17 Apr 2024 11:48:46 +0000 (+0200) Subject: Add mitigation for DDOS attack X-Git-Tag: accepted/tizen/8.0/unified/20240419.170006~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a21ae6f2e45a3a91e988bc1bda35de874b4237f7;p=platform%2Fcore%2Fsecurity%2Fsecurity-manager.git Add mitigation for DDOS attack 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 --- diff --git a/src/common/channel.cpp b/src/common/channel.cpp index 79664c83..3cb5850a 100644 --- a/src/common/channel.cpp +++ b/src/common/channel.cpp @@ -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 #include +#include #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; } } } diff --git a/src/common/connection.cpp b/src/common/connection.cpp index 73fdfa22..3721c9e6 100644 --- a/src/common/connection.cpp +++ b/src/common/connection.cpp @@ -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; } } } diff --git a/src/server/main/socket-manager.cpp b/src/server/main/socket-manager.cpp index b6f0a6af..63e493df 100644 --- a/src/server/main/socket-manager.cpp +++ b/src/server/main/socket-manager.cpp @@ -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; - 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), - 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; + 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), + 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; } }