mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-24 16:11:31 +00:00
[client] lgmp: bound pointer payloads
This commit is contained in:
@@ -48,6 +48,13 @@
|
|||||||
((KVMFR_R_HEARTBEAT_MS * 3U) * 1000U)
|
((KVMFR_R_HEARTBEAT_MS * 3U) * 1000U)
|
||||||
#define LGMP_RECOVERY_LIVE_TIMEOUT_US \
|
#define LGMP_RECOVERY_LIVE_TIMEOUT_US \
|
||||||
((KVMFR_R_HEARTBEAT_MS * 4U) * 1000U)
|
((KVMFR_R_HEARTBEAT_MS * 4U) * 1000U)
|
||||||
|
#define LGMP_CURSOR_MAX_WIDTH 512U
|
||||||
|
#define LGMP_CURSOR_MAX_HEIGHT 512U
|
||||||
|
#define LGMP_CURSOR_MAX_SHAPE_SIZE \
|
||||||
|
((size_t)LGMP_CURSOR_MAX_WIDTH * LGMP_CURSOR_MAX_HEIGHT * 4U)
|
||||||
|
#define LGMP_CURSOR_MAX_MESSAGE_SIZE \
|
||||||
|
(sizeof(KVMFRCursor) + LGMP_CURSOR_MAX_SHAPE_SIZE + \
|
||||||
|
sizeof(KVMFRColorTransform))
|
||||||
|
|
||||||
struct DMAFrameInfo
|
struct DMAFrameInfo
|
||||||
{
|
{
|
||||||
@@ -2263,6 +2270,43 @@ static void lgmp_releaseFrame(LG_Transport * this, LG_TransportFrame * frame)
|
|||||||
memset(frame, 0, sizeof(*frame));
|
memset(frame, 0, sizeof(*frame));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool lgmp_cursorShapeSize(const KVMFRCursor * cursor,
|
||||||
|
size_t * shapeSize)
|
||||||
|
{
|
||||||
|
if (!cursor->width || !cursor->height || !cursor->pitch ||
|
||||||
|
cursor->width > LGMP_CURSOR_MAX_WIDTH)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
size_t rowBytes;
|
||||||
|
uint32_t decodedHeight;
|
||||||
|
switch (cursor->type)
|
||||||
|
{
|
||||||
|
case CURSOR_TYPE_COLOR:
|
||||||
|
case CURSOR_TYPE_MASKED_COLOR:
|
||||||
|
rowBytes = (size_t)cursor->width * 4U;
|
||||||
|
decodedHeight = cursor->height;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CURSOR_TYPE_MONOCHROME:
|
||||||
|
if (cursor->height & 1U)
|
||||||
|
return false;
|
||||||
|
rowBytes = ((size_t)cursor->width + 7U) / 8U;
|
||||||
|
decodedHeight = cursor->height / 2U;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!decodedHeight || decodedHeight > LGMP_CURSOR_MAX_HEIGHT ||
|
||||||
|
cursor->pitch < rowBytes ||
|
||||||
|
cursor->pitch > LGMP_CURSOR_MAX_SHAPE_SIZE / cursor->height)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*shapeSize = (size_t)cursor->height * cursor->pitch;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static LG_TransportStatus lgmp_nextPointer(LG_Transport * this,
|
static LG_TransportStatus lgmp_nextPointer(LG_Transport * this,
|
||||||
LG_TransportPointer * result)
|
LG_TransportPointer * result)
|
||||||
{
|
{
|
||||||
@@ -2304,7 +2348,8 @@ static LG_TransportStatus lgmp_nextPointer(LG_Transport * this,
|
|||||||
lgmp_clearPointerQueue(this, pointerQueue);
|
lgmp_clearPointerQueue(this, pointerQueue);
|
||||||
if (status == LG_TRANSPORT_OK)
|
if (status == LG_TRANSPORT_OK)
|
||||||
{
|
{
|
||||||
if (message.size < sizeof(KVMFRCursor))
|
if (!message.mem || message.size < sizeof(KVMFRCursor) ||
|
||||||
|
message.size > LGMP_CURSOR_MAX_MESSAGE_SIZE)
|
||||||
{
|
{
|
||||||
const LG_TransportStatus done =
|
const LG_TransportStatus done =
|
||||||
lgmp_donePointerMessage(this, pointerQueue);
|
lgmp_donePointerMessage(this, pointerQueue);
|
||||||
@@ -2313,44 +2358,44 @@ static LG_TransportStatus lgmp_nextPointer(LG_Transport * this,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const KVMFRCursor * cursor = (const KVMFRCursor *)message.mem;
|
const size_t messageSize = message.size;
|
||||||
shapeSize = message.udata & CURSOR_FLAG_SHAPE ?
|
if (messageSize > this->pointerDataSize)
|
||||||
(size_t)cursor->height * cursor->pitch : 0;
|
|
||||||
transformSize =
|
|
||||||
message.udata & CURSOR_FLAG_COLOR_TRANSFORM ?
|
|
||||||
sizeof(KVMFRColorTransform) : 0;
|
|
||||||
if (shapeSize > message.size - sizeof(*cursor) ||
|
|
||||||
transformSize > message.size - sizeof(*cursor) - shapeSize)
|
|
||||||
{
|
{
|
||||||
const LG_TransportStatus done =
|
void * data = realloc(this->pointerData, messageSize);
|
||||||
lgmp_donePointerMessage(this, pointerQueue);
|
if (!data)
|
||||||
status = done == LG_TRANSPORT_DISCONNECTED ?
|
status = LG_TRANSPORT_ERROR;
|
||||||
done : LG_TRANSPORT_ERROR;
|
else
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const size_t needed = sizeof(*cursor) + shapeSize + transformSize;
|
|
||||||
if (needed > this->pointerDataSize)
|
|
||||||
{
|
{
|
||||||
void * data = realloc(this->pointerData, needed);
|
this->pointerData = data;
|
||||||
if (!data)
|
this->pointerDataSize = messageSize;
|
||||||
status = LG_TRANSPORT_ERROR;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->pointerData = data;
|
|
||||||
this->pointerDataSize = needed;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (status == LG_TRANSPORT_OK)
|
}
|
||||||
{
|
|
||||||
memcpy(this->pointerData, message.mem, needed);
|
if (status == LG_TRANSPORT_OK)
|
||||||
|
{
|
||||||
|
memcpy(this->pointerData, message.mem, messageSize);
|
||||||
|
const KVMFRCursor * cursor =
|
||||||
|
(const KVMFRCursor *)this->pointerData;
|
||||||
|
const bool hasShape = message.udata & CURSOR_FLAG_SHAPE;
|
||||||
|
if (hasShape && !lgmp_cursorShapeSize(cursor, &shapeSize))
|
||||||
|
status = LG_TRANSPORT_ERROR;
|
||||||
|
transformSize =
|
||||||
|
message.udata & CURSOR_FLAG_COLOR_TRANSFORM ?
|
||||||
|
sizeof(KVMFRColorTransform) : 0;
|
||||||
|
|
||||||
|
const size_t payloadSize = messageSize - sizeof(*cursor);
|
||||||
|
if (status == LG_TRANSPORT_OK &&
|
||||||
|
(shapeSize > payloadSize ||
|
||||||
|
transformSize > payloadSize - shapeSize))
|
||||||
|
status = LG_TRANSPORT_ERROR;
|
||||||
|
else if (status == LG_TRANSPORT_OK)
|
||||||
pointerFlags = (uint32_t)message.udata;
|
pointerFlags = (uint32_t)message.udata;
|
||||||
}
|
|
||||||
const LG_TransportStatus done =
|
|
||||||
lgmp_donePointerMessage(this, pointerQueue);
|
|
||||||
if (status == LG_TRANSPORT_OK)
|
|
||||||
status = done;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const LG_TransportStatus done =
|
||||||
|
lgmp_donePointerMessage(this, pointerQueue);
|
||||||
|
if (status == LG_TRANSPORT_OK)
|
||||||
|
status = done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user