qemu: fix crash in qemud message process when we don't have enough data

This commit is contained in:
Simon Fels 2018-05-24 15:21:40 +02:00
commit 1eeeea111e
2 changed files with 19 additions and 11 deletions

View file

@ -23,7 +23,7 @@
namespace { namespace {
static constexpr const long header_size{4}; static constexpr const long header_size{4};
} } // namespace
namespace anbox { namespace anbox {
namespace qemu { namespace qemu {
@ -33,18 +33,17 @@ QemudMessageProcessor::QemudMessageProcessor(
QemudMessageProcessor::~QemudMessageProcessor() {} QemudMessageProcessor::~QemudMessageProcessor() {}
bool QemudMessageProcessor::process_data( bool QemudMessageProcessor::process_data(const std::vector<std::uint8_t> &data) {
const std::vector<std::uint8_t> &data) { for (const auto &byte : data)
for (const auto &byte : data) buffer_.push_back(byte); buffer_.push_back(byte);
process_commands(); return process_commands();
return true;
} }
void QemudMessageProcessor::process_commands() { bool QemudMessageProcessor::process_commands() {
while (true) { while (true) {
if (buffer_.size() < header_size) break; if (buffer_.size() < header_size)
break;
char header[header_size] = {0}; char header[header_size] = {0};
::memcpy(header, buffer_.data(), header_size); ::memcpy(header, buffer_.data(), header_size);
@ -52,6 +51,12 @@ void QemudMessageProcessor::process_commands() {
unsigned int body_size = 0; unsigned int body_size = 0;
::sscanf(header, "%04x", &body_size); ::sscanf(header, "%04x", &body_size);
// Double check that we have enough data to ready the whole body. If
// not we have to wait until we have everything.
size_t total_size = header_size + body_size;
if (buffer_.size() < total_size)
break;
std::string command; std::string command;
// Make sure we only copy as much bytes as we have to and not more // Make sure we only copy as much bytes as we have to and not more
command.insert(0, command.insert(0,
@ -64,8 +69,11 @@ void QemudMessageProcessor::process_commands() {
buffer_.erase(buffer_.begin(), buffer_.begin() + consumed); buffer_.erase(buffer_.begin(), buffer_.begin() + consumed);
const auto remaining = buffer_.size() - consumed; const auto remaining = buffer_.size() - consumed;
if (remaining <= 0) break; if (remaining <= 0)
break;
} }
return true;
} }
void QemudMessageProcessor::send_header(const size_t &size) { void QemudMessageProcessor::send_header(const size_t &size) {

View file

@ -40,7 +40,7 @@ class QemudMessageProcessor : public network::MessageProcessor {
std::shared_ptr<network::SocketMessenger> messenger_; std::shared_ptr<network::SocketMessenger> messenger_;
private: private:
void process_commands(); bool process_commands();
std::vector<std::uint8_t> buffer_; std::vector<std::uint8_t> buffer_;
}; };