CVE-2020-11089 (C, published 2020-05-29T20:15Z)
Description: value: In FreeRDP before 2.1.0, there is an out-of-bound read in irp functions (parallel_process_irp_create, serial_process_irp_create, drive_process_irp_write, printer_process_irp_write, rdpei_recv_pdu, serial_process_irp_write). This has been fixed in 2.1.0.
Severity: MEDIUM (CVSS v3 base score: 5.5)
Weakness: CWE-125 \u2014 Out-of-bounds Read
The product reads data past the end, or before the beginning, of the intended buffer.
Repository: https://github.com/FreeRDP/FreeRDP
Files changed:
channels/drive/client/drive_main.c
channels/printer/client/printer_main.c
channels/rdpei/client/rdpei_main.c
channels/serial/client/serial_main.c
libfreerdp/core/gateway/rdg.c
libfreerdp/core/nego.c
Commit message: Fixed oob read in irp_write and similar


Vulnerable code:
	else if (!drive_file_write(file, Stream_Pointer(irp->input), Length))

		error = printjob->Write(printjob, Stream_Pointer(irp->input), Length);
	if (Stream_GetRemainingLength(irp->input) < PathLength)
	Stream_Seek(irp->input, PathLength); /* Path (variable) */
	Stream_Seek(irp->input, 20);            /* Padding (20 bytes) */
	if (CommWriteFile(serial->hComm, Stream_Pointer(irp->input), Length, &nbWritten, NULL))
	if ((packetLength > INT_MAX) || !Stream_EnsureCapacity(s, packetLength))
static void nego_process_negotiation_request(rdpNego* nego, wStream* s);
static void nego_process_negotiation_response(rdpNego* nego, wStream* s);
static void nego_process_negotiation_failure(rdpNego* nego, wStream* s);
				nego_process_negotiation_response(nego, s);
				nego_process_negotiation_failure(nego, s);
		nego_process_negotiation_request(nego, s);
void nego_process_negotiation_request(rdpNego* nego, wStream* s)
void nego_process_negotiation_response(rdpNego* nego, wStream* s)
		return;
void nego_process_negotiation_failure(rdpNego* nego, wStream* s)

Fixed code:
	void* ptr;
	ptr = Stream_Pointer(irp->input);
	if (!Stream_SafeSeek(irp->input, Length))
		return ERROR_INVALID_DATA;
	else if (!drive_file_write(file, ptr, Length))
	void* ptr;

	if (Stream_GetRemainingLength(irp->input) < 32)
		return ERROR_INVALID_DATA;
	ptr = Stream_Pointer(irp->input);
	if (!Stream_SafeSeek(irp->input, Length))
		return ERROR_INVALID_DATA;
		error = printjob->Write(printjob, ptr, Length);
	if (Stream_GetRemainingLength(s) < 6)
		return ERROR_INVALID_DATA;

	if (!Stream_SafeSeek(irp->input, PathLength)) /* Path (variable) */
	void* ptr;
	if (!Stream_SafeSeek(irp->input, 20))   /* Padding (20 bytes) */
		return ERROR_INVALID_DATA;

	ptr = Stream_Pointer(irp->input);
	if (!Stream_SafeSeek(irp->input, Length))
		return ERROR_INVALID_DATA;
	if (CommWriteFile(serial->hComm, ptr, Length, &nbWritten, NULL))
	if ((packetLength > INT_MAX) || !Stream_EnsureCapacity(s, packetLength) ||
	    (packetLength < header))
static BOOL nego_process_negotiation_request(rdpNego* nego, wStream* s);
static BOOL nego_process_negotiation_response(rdpNego* nego, wStream* s);
static BOOL nego_process_negotiation_failure(rdpNego* nego, wStream* s);
				if (!nego_process_negotiation_response(nego, s))
					return -1;
				if (!nego_process_negotiation_failure(nego, s))
					return -1;
		if (!nego_process_negotiation_request(nego, s))
			return FALSE;
BOOL nego_process_negotiation_request(rdpNego* nego, wStream* s)

	if (Stream_GetRemainingLength(s) < 7)
		return FALSE;
	return TRUE;
BOOL nego_process_negotiation_response(rdpNego* nego, wStream* s)
		return FALSE;
	return TRUE;
BOOL nego_process_negotiation_failure(rdpNego* nego, wStream* s)
	if (Stream_GetRemainingLength(s) < 7)
		return FALSE;
	return TRUE;