diff options
| author | Dan Engelbrecht <[email protected]> | 2022-12-08 11:29:35 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-12-08 02:29:35 -0800 |
| commit | 0daab9dd69c3ed786d4a10894cf1d732ce622883 (patch) | |
| tree | 72aad48fd880ebc6faae8c32be815ad32aa68dcc /zenhttp/httpasio.cpp | |
| parent | Fix logging of number of read entries from log/index file for stores (#204) (diff) | |
| download | zen-0daab9dd69c3ed786d4a10894cf1d732ce622883.tar.xz zen-0daab9dd69c3ed786d4a10894cf1d732ce622883.zip | |
Fix http parsing crash (#205)
* Don't continue parsing http requests if we get an error.
* changelog
Diffstat (limited to 'zenhttp/httpasio.cpp')
| -rw-r--r-- | zenhttp/httpasio.cpp | 65 |
1 files changed, 36 insertions, 29 deletions
diff --git a/zenhttp/httpasio.cpp b/zenhttp/httpasio.cpp index 68984c86d..450b5a1fc 100644 --- a/zenhttp/httpasio.cpp +++ b/zenhttp/httpasio.cpp @@ -187,7 +187,6 @@ private: char m_HeaderBuffer[1024]; std::string m_NormalizedUrl; - void AppendInputBytes(const char* Data, size_t Bytes); void AppendCurrentHeader(); int OnMessageBegin(); @@ -200,8 +199,6 @@ private: static HttpRequest* GetThis(http_parser* Parser) { return reinterpret_cast<HttpRequest*>(Parser->data); } static http_parser_settings s_ParserSettings; - - void TerminateConnection(); }; struct HttpResponse @@ -419,6 +416,10 @@ HttpServerConnection::OnDataReceived(const asio::error_code& Ec, [[maybe_unused] const asio::const_buffer& InputBuffer = m_RequestBuffer.data(); size_t Result = m_RequestData.ConsumeData((const char*)InputBuffer.data(), InputBuffer.size()); + if (Result == ~0ull) + { + return OnError(); + } m_RequestBuffer.consume(Result); } @@ -639,30 +640,12 @@ HttpRequest::ConsumeData(const char* InputData, size_t DataSize) if (HttpErrno && HttpErrno != HPE_INVALID_EOF_STATE) { ZEN_WARN("HTTP parser error {} ('{}'). Closing connection", http_errno_name(HttpErrno), http_errno_description(HttpErrno)); - TerminateConnection(); - return DataSize; + return ~0ull; } return ConsumedBytes; } -void -HttpRequest::AppendInputBytes(const char* Data, size_t Bytes) -{ - const size_t RemainingBufferSpace = sizeof m_HeaderBuffer + m_HeaderBuffer - m_HeaderCursor; - - if (RemainingBufferSpace >= Bytes) - { - memcpy(m_HeaderCursor, Data, Bytes); - m_HeaderCursor += Bytes; - - return; - } - - // Terribad, but better than buffer overflow - TerminateConnection(); -} - int HttpRequest::OnUrl(const char* Data, size_t Bytes) { @@ -672,7 +655,16 @@ HttpRequest::OnUrl(const char* Data, size_t Bytes) m_Url = m_HeaderCursor; } - AppendInputBytes(Data, Bytes); + const size_t RemainingBufferSpace = sizeof m_HeaderBuffer + m_HeaderBuffer - m_HeaderCursor; + + if (RemainingBufferSpace < Bytes) + { + ZEN_WARN("HTTP parser does not have enough space for incoming request, need {} more bytes", Bytes - RemainingBufferSpace); + return 1; + } + + memcpy(m_HeaderCursor, Data, Bytes); + m_HeaderCursor += Bytes; m_UrlLength += Bytes; return 0; @@ -694,6 +686,13 @@ HttpRequest::OnHeader(const char* Data, size_t Bytes) m_CurrentHeaderName = m_HeaderCursor; } + const size_t RemainingBufferSpace = sizeof m_HeaderBuffer + m_HeaderBuffer - m_HeaderCursor; + if (RemainingBufferSpace < Bytes) + { + ZEN_WARN("HTTP parser does not have enough space for incoming header name, need {} more bytes", Bytes - RemainingBufferSpace); + return 1; + } + memcpy(m_HeaderCursor, Data, Bytes); m_HeaderCursor += Bytes; m_CurrentHeaderNameLength += Bytes; @@ -753,6 +752,13 @@ HttpRequest::OnHeaderValue(const char* Data, size_t Bytes) m_CurrentHeaderValue = m_HeaderCursor; } + const size_t RemainingBufferSpace = sizeof m_HeaderBuffer + m_HeaderBuffer - m_HeaderCursor; + if (RemainingBufferSpace < Bytes) + { + ZEN_WARN("HTTP parser does not have enough space for incoming header value, need {} more bytes", Bytes - RemainingBufferSpace); + return 1; + } + memcpy(m_HeaderCursor, Data, Bytes); m_HeaderCursor += Bytes; m_CurrentHeaderValueLength += Bytes; @@ -760,12 +766,6 @@ HttpRequest::OnHeaderValue(const char* Data, size_t Bytes) return 0; } -void -HttpRequest::TerminateConnection() -{ - m_Connection.TerminateConnection(); -} - static void NormalizeUrlPath(const char* Url, size_t UrlLength, std::string& NormalizedUrl) { @@ -875,6 +875,12 @@ HttpRequest::OnHeadersComplete() int HttpRequest::OnBody(const char* Data, size_t Bytes) { + if (m_BodyPosition + Bytes > m_BodyBuffer.Size()) + { + ZEN_WARN("HTTP parser incoming body is larger than content size, need {} more bytes", + (m_BodyPosition + Bytes) - m_BodyBuffer.Size()); + return 1; + } memcpy(reinterpret_cast<uint8_t*>(m_BodyBuffer.MutableData()) + m_BodyPosition, Data, Bytes); m_BodyPosition += Bytes; @@ -883,6 +889,7 @@ HttpRequest::OnBody(const char* Data, size_t Bytes) if (m_BodyPosition != m_BodyBuffer.Size()) { ZEN_WARN("Body mismatch! {} != {}", m_BodyPosition, m_BodyBuffer.Size()); + return 1; } } |