fix: clipboard buffer overrun using propose solution from kitknox
This commit is contained in:
parent
c8e0feab4e
commit
1c81886643
1 changed files with 19 additions and 0 deletions
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
#include "deskflow/IClipboard.h"
|
#include "deskflow/IClipboard.h"
|
||||||
|
|
||||||
|
#include "base/Log.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -19,6 +21,7 @@ void IClipboard::unmarshall(IClipboard *clipboard, const std::string_view &data,
|
||||||
assert(clipboard != nullptr);
|
assert(clipboard != nullptr);
|
||||||
|
|
||||||
const char *index = data.data();
|
const char *index = data.data();
|
||||||
|
const char *const end = index + data.size();
|
||||||
|
|
||||||
if (clipboard->open(time)) {
|
if (clipboard->open(time)) {
|
||||||
// clear existing data
|
// clear existing data
|
||||||
|
|
@ -26,10 +29,20 @@ void IClipboard::unmarshall(IClipboard *clipboard, const std::string_view &data,
|
||||||
|
|
||||||
// read the number of formats
|
// read the number of formats
|
||||||
const uint32_t numFormats = readUInt32(index);
|
const uint32_t numFormats = readUInt32(index);
|
||||||
|
if (end - index < 4) {
|
||||||
|
LOG_ERR("clipboard unmarshall: truncated header");
|
||||||
|
clipboard->close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
index += 4;
|
index += 4;
|
||||||
|
|
||||||
// read each format
|
// read each format
|
||||||
for (uint32_t i = 0; i < numFormats; ++i) {
|
for (uint32_t i = 0; i < numFormats; ++i) {
|
||||||
|
// need 8 bytes for format id + payload size
|
||||||
|
if (end - index < 8) {
|
||||||
|
LOG_ERR("clipboard unmarshall: truncated format header at %u/%u", i, numFormats);
|
||||||
|
break;
|
||||||
|
}
|
||||||
// get the format id
|
// get the format id
|
||||||
auto format = static_cast<IClipboard::Format>(readUInt32(index));
|
auto format = static_cast<IClipboard::Format>(readUInt32(index));
|
||||||
index += 4;
|
index += 4;
|
||||||
|
|
@ -38,6 +51,12 @@ void IClipboard::unmarshall(IClipboard *clipboard, const std::string_view &data,
|
||||||
uint32_t size = readUInt32(index);
|
uint32_t size = readUInt32(index);
|
||||||
index += 4;
|
index += 4;
|
||||||
|
|
||||||
|
// peer-supplied size must not exceed remaining buffer
|
||||||
|
if (size > static_cast<uint32_t>(end - index)) {
|
||||||
|
LOG_ERR("clipboard unmarshall: payload size %u exceeds remaining %zd", size, end - index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// save the data if it's a known format. if either the client
|
// save the data if it's a known format. if either the client
|
||||||
// or server supports more clipboard formats than the other
|
// or server supports more clipboard formats than the other
|
||||||
// then one of them will get a format >= TotalFormats here.
|
// then one of them will get a format >= TotalFormats here.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue