Skip to content

Commit 9301bfe

Browse files
committed
Fixed #6007: Boundary checks in rdp_read_flow_control_pdu
1 parent 58dc36b commit 9301bfe

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

Diff for: libfreerdp/core/rdp.c

+16-7
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ const char* DATA_PDU_TYPE_STRINGS[80] = {
102102
"?" /* 0x41 - 0x46 */
103103
};
104104

105-
static void rdp_read_flow_control_pdu(wStream* s, UINT16* type);
105+
static BOOL rdp_read_flow_control_pdu(wStream* s, UINT16* type);
106106
static void rdp_write_share_control_header(wStream* s, UINT16 length, UINT16 type,
107107
UINT16 channel_id);
108108
static void rdp_write_share_data_header(wStream* s, UINT16 length, BYTE type, UINT32 share_id);
@@ -145,29 +145,33 @@ void rdp_write_security_header(wStream* s, UINT16 flags)
145145

146146
BOOL rdp_read_share_control_header(wStream* s, UINT16* length, UINT16* type, UINT16* channel_id)
147147
{
148+
UINT16 len;
148149
if (Stream_GetRemainingLength(s) < 2)
149150
return FALSE;
150151

151152
/* Share Control Header */
152-
Stream_Read_UINT16(s, *length); /* totalLength */
153+
Stream_Read_UINT16(s, len); /* totalLength */
154+
155+
*length = len;
153156

154157
/* If length is 0x8000 then we actually got a flow control PDU that we should ignore
155158
http://msdn.microsoft.com/en-us/library/cc240576.aspx */
156-
if (*length == 0x8000)
159+
if (len == 0x8000)
157160
{
158-
rdp_read_flow_control_pdu(s, type);
161+
if (!rdp_read_flow_control_pdu(s, type))
162+
return FALSE;
159163
*channel_id = 0;
160164
*length = 8; /* Flow control PDU is 8 bytes */
161165
return TRUE;
162166
}
163167

164-
if (((size_t)*length - 2) > Stream_GetRemainingLength(s))
168+
if ((len < 4) || ((len - 2) > Stream_GetRemainingLength(s)))
165169
return FALSE;
166170

167171
Stream_Read_UINT16(s, *type); /* pduType */
168172
*type &= 0x0F; /* type is in the 4 least significant bits */
169173

170-
if (*length > 4)
174+
if (len > 4)
171175
Stream_Read_UINT16(s, *channel_id); /* pduSource */
172176
else
173177
*channel_id = 0; /* Windows XP can send such short DEACTIVATE_ALL PDUs. */
@@ -1116,7 +1120,7 @@ int rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, wStream* s)
11161120
}
11171121
}
11181122

1119-
void rdp_read_flow_control_pdu(wStream* s, UINT16* type)
1123+
BOOL rdp_read_flow_control_pdu(wStream* s, UINT16* type)
11201124
{
11211125
/*
11221126
* Read flow control PDU - documented in FlowPDU section in T.128
@@ -1126,12 +1130,17 @@ void rdp_read_flow_control_pdu(wStream* s, UINT16* type)
11261130
* Switched the order of these two fields to match this observation.
11271131
*/
11281132
UINT8 pduType;
1133+
if (!type)
1134+
return FALSE;
1135+
if (Stream_GetRemainingLength(s) < 6)
1136+
return FALSE;
11291137
Stream_Read_UINT8(s, pduType); /* pduTypeFlow */
11301138
*type = pduType;
11311139
Stream_Seek_UINT8(s); /* pad8bits */
11321140
Stream_Seek_UINT8(s); /* flowIdentifier */
11331141
Stream_Seek_UINT8(s); /* flowNumber */
11341142
Stream_Seek_UINT16(s); /* pduSource */
1143+
return TRUE;
11351144
}
11361145

11371146
/**

0 commit comments

Comments
 (0)