[channels,location] add value range checks

When reading a enum value from network, first check the value range and
abort with a log message if an invalid value is found
This commit is contained in:
akallabeth
2026-01-09 09:20:03 +01:00
parent 508a0db07c
commit ecbfe4a19a

View File

@@ -137,7 +137,25 @@ static UINT location_server_recv_client_ready(LocationServerContext* context, wS
if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
return ERROR_NO_DATA;
Stream_Read_UINT32(s, pdu.protocolVersion);
{
const UINT32 version = Stream_Get_UINT32(s);
switch (version)
{
case RDPLOCATION_PROTOCOL_VERSION_100:
pdu.protocolVersion = RDPLOCATION_PROTOCOL_VERSION_100;
break;
case RDPLOCATION_PROTOCOL_VERSION_200:
pdu.protocolVersion = RDPLOCATION_PROTOCOL_VERSION_200;
break;
default:
pdu.protocolVersion = RDPLOCATION_PROTOCOL_VERSION_200;
WLog_WARN(TAG,
"Received unsupported protocol version %" PRIu32
", setting to highest supported %u",
version, pdu.protocolVersion);
break;
}
}
if (Stream_GetRemainingLength(s) >= 4)
Stream_Read_UINT32(s, pdu.flags);
@@ -157,7 +175,7 @@ static UINT location_server_recv_base_location3d(LocationServerContext* context,
double speed = 0.0;
double heading = 0.0;
double horizontalAccuracy = 0.0;
LOCATIONSOURCE source = 0;
LOCATIONSOURCE source = LOCATIONSOURCE_IP;
WINPR_ASSERT(context);
WINPR_ASSERT(s);
@@ -178,7 +196,21 @@ static UINT location_server_recv_base_location3d(LocationServerContext* context,
!Stream_CheckAndLogRequiredLength(TAG, s, 1))
return FALSE;
Stream_Read_UINT8(s, source);
{
const UINT8 src = Stream_Get_UINT8(s);
switch (src)
{
case LOCATIONSOURCE_IP:
case LOCATIONSOURCE_WIFI:
case LOCATIONSOURCE_CELL:
case LOCATIONSOURCE_GNSS:
break;
default:
WLog_ERR(TAG, "Invalid LOCATIONSOURCE value %" PRIu8 "", src);
return FALSE;
}
source = (LOCATIONSOURCE)src;
}
pdu.speed = &speed;
pdu.heading = &heading;
@@ -307,27 +339,30 @@ static UINT location_process_message(location_server* location)
if (!Stream_CheckAndLogRequiredLength(TAG, s, LOCATION_HEADER_SIZE))
return ERROR_NO_DATA;
Stream_Read_UINT16(s, header.pduType);
Stream_Read_UINT32(s, header.pduLength);
switch (header.pduType)
{
case PDUTYPE_CLIENT_READY:
error = location_server_recv_client_ready(&location->context, s, &header);
break;
case PDUTYPE_BASE_LOCATION3D:
error = location_server_recv_base_location3d(&location->context, s, &header);
break;
case PDUTYPE_LOCATION2D_DELTA:
error = location_server_recv_location2d_delta(&location->context, s, &header);
break;
case PDUTYPE_LOCATION3D_DELTA:
error = location_server_recv_location3d_delta(&location->context, s, &header);
break;
default:
WLog_ERR(TAG, "location_process_message: unknown or invalid pduType %" PRIu8 "",
header.pduType);
break;
const UINT16 pduType = Stream_Get_UINT16(s);
header.pduType = (LOCATION_PDUTYPE)pduType;
header.pduLength = Stream_Get_UINT32(s);
switch (pduType)
{
case PDUTYPE_CLIENT_READY:
error = location_server_recv_client_ready(&location->context, s, &header);
break;
case PDUTYPE_BASE_LOCATION3D:
error = location_server_recv_base_location3d(&location->context, s, &header);
break;
case PDUTYPE_LOCATION2D_DELTA:
error = location_server_recv_location2d_delta(&location->context, s, &header);
break;
case PDUTYPE_LOCATION3D_DELTA:
error = location_server_recv_location3d_delta(&location->context, s, &header);
break;
default:
WLog_ERR(TAG, "location_process_message: unknown or invalid pduType %" PRIu16 "",
pduType);
break;
}
}
out: