From e6fca2c0218ecc5f8884d3e80a2982127ff00955 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 27 Feb 2026 20:59:11 +0100 Subject: [PATCH] [winpr,stream] Fix Stream_SetPosition return checks --- channels/audin/client/audin_main.c | 3 +- channels/cliprdr/client/cliprdr_main.c | 11 +-- channels/cliprdr/server/cliprdr_main.c | 12 ++-- channels/disp/server/disp_main.c | 3 +- channels/drdynvc/client/drdynvc_main.c | 37 +++++++--- channels/encomsp/client/encomsp_main.c | 33 ++++++--- channels/encomsp/server/encomsp_main.c | 3 +- channels/gfxredir/server/gfxredir_main.c | 3 +- channels/location/client/location_main.c | 3 +- channels/rail/client/rail_orders.c | 13 ++-- channels/rail/rail_common.c | 5 +- channels/rail/rail_common.h | 3 +- channels/rail/server/rail_main.c | 10 ++- channels/rdpdr/client/irp.c | 12 ++-- channels/rdpdr/client/rdpdr_main.c | 18 ++++- channels/rdpei/client/rdpei_main.c | 3 +- channels/rdpgfx/client/rdpgfx_main.c | 6 +- channels/rdpgfx/server/rdpgfx_main.c | 18 +++-- channels/rdpsnd/server/rdpsnd_main.c | 41 +++++++++--- channels/tsmf/client/tsmf_codec.c | 3 +- channels/tsmf/client/tsmf_ifman.c | 9 ++- .../urbdrc/client/libusb/libusb_udevice.c | 5 +- channels/urbdrc/common/urbdrc_helpers.c | 3 +- libfreerdp/codec/zgfx.c | 12 ++-- libfreerdp/core/capabilities.c | 33 +++++---- libfreerdp/core/connection.c | 16 +++-- libfreerdp/core/fastpath.c | 6 +- libfreerdp/core/gateway/rpc_bind.c | 6 +- libfreerdp/core/gateway/rpc_client.c | 12 ++-- libfreerdp/core/gateway/rts.c | 3 +- libfreerdp/core/gcc.c | 9 +-- libfreerdp/core/license.c | 6 +- libfreerdp/core/mcs.c | 12 ++-- libfreerdp/core/nego.c | 49 +++++++------- libfreerdp/core/nla.c | 3 +- libfreerdp/core/peer.c | 5 +- libfreerdp/core/rdp.c | 23 +++++-- libfreerdp/core/redirection.c | 12 ++-- libfreerdp/core/streamdump.c | 3 +- libfreerdp/core/update.c | 67 ++++++++++--------- libfreerdp/emu/scard/smartcard_virtual_gids.c | 4 +- libfreerdp/utils/rdpdr_utils.c | 3 +- libfreerdp/utils/smartcard_call.c | 6 +- server/Sample/sfreerdp.c | 6 +- server/proxy/channels/pf_channel_rdpdr.c | 45 +++++++------ server/proxy/channels/pf_channel_smartcard.c | 3 +- .../modules/bitmap-filter/bitmap-filter.cpp | 6 +- winpr/include/winpr/stream.h | 1 + winpr/libwinpr/sspi/NTLM/ntlm.c | 8 +-- winpr/libwinpr/sspi/NTLM/ntlm_compute.c | 10 ++- winpr/libwinpr/sspi/NTLM/ntlm_message.c | 15 +++-- winpr/libwinpr/utils/test/TestStream.c | 6 +- 52 files changed, 414 insertions(+), 233 deletions(-) diff --git a/channels/audin/client/audin_main.c b/channels/audin/client/audin_main.c index 9eb71a47a..12b0aa749 100644 --- a/channels/audin/client/audin_main.c +++ b/channels/audin/client/audin_main.c @@ -279,7 +279,8 @@ static UINT audin_process_formats(AUDIN_PLUGIN* audin, AUDIN_CHANNEL_CALLBACK* c Stream_Write_UINT8(out, MSG_SNDIN_FORMATS); /* Header (1 byte) */ Stream_Write_UINT32(out, callback->formats_count); /* NumFormats (4 bytes) */ Stream_Write_UINT32(out, cbSizeFormatsPacket); /* cbSizeFormatsPacket (4 bytes) */ - Stream_SetPosition(out, cbSizeFormatsPacket); + if (!Stream_SetPosition(out, cbSizeFormatsPacket)) + goto out; error = audin_channel_write_and_free(callback, out, FALSE); out: diff --git a/channels/cliprdr/client/cliprdr_main.c b/channels/cliprdr/client/cliprdr_main.c index 2fdb3dbc0..9640a93cb 100644 --- a/channels/cliprdr/client/cliprdr_main.c +++ b/channels/cliprdr/client/cliprdr_main.c @@ -60,7 +60,7 @@ CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr) */ static UINT cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s) { - UINT status = CHANNEL_RC_OK; + UINT status = ERROR_INVALID_DATA; WINPR_ASSERT(cliprdr); WINPR_ASSERT(s); @@ -71,16 +71,16 @@ static UINT cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s) const uint32_t dataLen = WINPR_ASSERTING_INT_CAST(uint32_t, pos - 8UL); - Stream_SetPosition(s, 4); + if (!Stream_SetPosition(s, 4)) + goto fail; Stream_Write_UINT32(s, dataLen); - Stream_SetPosition(s, pos); + if (!Stream_SetPosition(s, pos)) + goto fail; WLog_Print(cliprdr->log, WLOG_DEBUG, "Cliprdr Sending (%" PRIuz " bytes)", pos); if (!cliprdr) - { status = CHANNEL_RC_BAD_INIT_HANDLE; - } else { WINPR_ASSERT(cliprdr->channelEntryPoints.pVirtualChannelWriteEx); @@ -89,6 +89,7 @@ static UINT cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s) (UINT32)Stream_GetPosition(s), s); } +fail: if (status != CHANNEL_RC_OK) { Stream_Free(s, TRUE); diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c index ac9339891..f40033f58 100644 --- a/channels/cliprdr/server/cliprdr_main.c +++ b/channels/cliprdr/server/cliprdr_main.c @@ -94,7 +94,8 @@ static UINT cliprdr_server_packet_send(CliprdrServerPrivate* cliprdr, wStream* s } dataLen = (UINT32)(pos - 8); - Stream_SetPosition(s, 4); + if (!Stream_SetPosition(s, 4)) + goto fail; Stream_Write_UINT32(s, dataLen); WINPR_ASSERT(pos <= UINT32_MAX); @@ -1116,7 +1117,8 @@ static UINT cliprdr_server_read(CliprdrServerContext* context) return CHANNEL_RC_NO_MEMORY; } - Stream_SetPosition(s, position); + if (!Stream_SetPosition(s, position)) + return ERROR_INVALID_DATA; if (Stream_GetPosition(s) < (header.dataLen + CLIPRDR_HEADER_LENGTH)) { @@ -1147,9 +1149,11 @@ static UINT cliprdr_server_read(CliprdrServerContext* context) if (Stream_GetPosition(s) >= (header.dataLen + CLIPRDR_HEADER_LENGTH)) { - Stream_SetPosition(s, (header.dataLen + CLIPRDR_HEADER_LENGTH)); + if (!Stream_SetPosition(s, (header.dataLen + CLIPRDR_HEADER_LENGTH))) + return ERROR_INVALID_DATA; Stream_SealLength(s); - Stream_SetPosition(s, CLIPRDR_HEADER_LENGTH); + if (!Stream_SetPosition(s, CLIPRDR_HEADER_LENGTH)) + return ERROR_INVALID_DATA; if ((error = cliprdr_server_receive_pdu(context, s, &header))) { diff --git a/channels/disp/server/disp_main.c b/channels/disp/server/disp_main.c index 06bd6a11b..def5866da 100644 --- a/channels/disp/server/disp_main.c +++ b/channels/disp/server/disp_main.c @@ -251,7 +251,8 @@ static UINT disp_server_receive_pdu(DispServerContext* context, wStream* s) { WLog_ERR(TAG, "Unexpected DISP pdu end: Actual: %" PRIuz ", Expected: %" PRIuz "", end, (beg + header.length)); - Stream_SetPosition(s, (beg + header.length)); + if (!Stream_SetPosition(s, (beg + header.length))) + return ERROR_INVALID_DATA; } return error; diff --git a/channels/drdynvc/client/drdynvc_main.c b/channels/drdynvc/client/drdynvc_main.c index fee3f6940..cae4c649a 100644 --- a/channels/drdynvc/client/drdynvc_main.c +++ b/channels/drdynvc/client/drdynvc_main.c @@ -966,7 +966,6 @@ static UINT drdynvc_send(drdynvcPlugin* drdynvc, wStream* s) static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, const BYTE* data, UINT32 dataSize, BOOL* close) { - wStream* data_out = nullptr; size_t pos = 0; UINT8 cbChId = 0; UINT8 cbLen = 0; @@ -981,7 +980,7 @@ static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, const B WLog_Print(drdynvc->log, WLOG_TRACE, "write_data: ChannelId=%" PRIu32 " size=%" PRIu32 "", ChannelId, dataSize); - data_out = StreamPool_Take(dvcman->pool, CHANNEL_CHUNK_LENGTH); + wStream* data_out = StreamPool_Take(dvcman->pool, CHANNEL_CHUNK_LENGTH); if (!data_out) { @@ -989,7 +988,11 @@ static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, const B return CHANNEL_RC_NO_MEMORY; } - Stream_SetPosition(data_out, 1); + if (!Stream_SetPosition(data_out, 1)) + { + Stream_Release(data_out); + return ERROR_INVALID_DATA; + } cbChId = drdynvc_write_variable_uint(data_out, ChannelId); pos = Stream_GetPosition(data_out); @@ -1003,7 +1006,11 @@ static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, const B { Stream_ResetPosition(data_out); Stream_Write_UINT8(data_out, (DATA_PDU << 4) | cbChId); - Stream_SetPosition(data_out, pos); + if (!Stream_SetPosition(data_out, pos)) + { + Stream_Release(data_out); + return ERROR_INVALID_DATA; + } Stream_Write(data_out, data, dataSize); status = drdynvc_send(drdynvc, data_out); } @@ -1016,7 +1023,11 @@ static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, const B const INT32 pdu = (DATA_FIRST_PDU << 4) | cbChId | (cbLen << 2); Stream_Write_UINT8(data_out, WINPR_ASSERTING_INT_CAST(UINT8, pdu)); - Stream_SetPosition(data_out, pos); + if (!Stream_SetPosition(data_out, pos)) + { + Stream_Release(data_out); + return ERROR_INVALID_DATA; + } { WINPR_ASSERT(pos <= CHANNEL_CHUNK_LENGTH); @@ -1039,12 +1050,21 @@ static UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, const B return CHANNEL_RC_NO_MEMORY; } - Stream_SetPosition(data_out, 1); + if (!Stream_SetPosition(data_out, 1)) + { + Stream_Release(data_out); + return ERROR_INVALID_DATA; + } + cbChId = drdynvc_write_variable_uint(data_out, ChannelId); pos = Stream_GetPosition(data_out); Stream_ResetPosition(data_out); Stream_Write_UINT8(data_out, (DATA_PDU << 4) | cbChId); - Stream_SetPosition(data_out, pos); + if (!Stream_SetPosition(data_out, pos)) + { + Stream_Release(data_out); + return ERROR_INVALID_DATA; + } uint32_t chunkLength = dataSize; @@ -1246,7 +1266,8 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, UINT8 Sp, UIN } Stream_Write_UINT8(data_out, (CREATE_REQUEST_PDU << 4) | cbChId); - Stream_SetPosition(s, 1); + if (!Stream_SetPosition(s, 1)) + return ERROR_INVALID_DATA; Stream_Copy(s, data_out, pos - 1); channel = diff --git a/channels/encomsp/client/encomsp_main.c b/channels/encomsp/client/encomsp_main.c index c24aed857..1d271065d 100644 --- a/channels/encomsp/client/encomsp_main.c +++ b/channels/encomsp/client/encomsp_main.c @@ -176,7 +176,8 @@ static UINT encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(body - end))) return ERROR_INVALID_DATA; - Stream_SetPosition(s, body); + if (!Stream_SetPosition(s, body)) + return ERROR_INVALID_DATA; } IFCALLRET(context->FilterUpdated, error, context, &pdu); @@ -237,7 +238,8 @@ static UINT encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(body - end))) return ERROR_INVALID_DATA; - Stream_SetPosition(s, body); + if (!Stream_SetPosition(s, body)) + return ERROR_INVALID_DATA; } IFCALLRET(context->ApplicationCreated, error, context, &pdu); @@ -290,7 +292,8 @@ static UINT encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(body - end))) return ERROR_INVALID_DATA; - Stream_SetPosition(s, body); + if (!Stream_SetPosition(s, body)) + return ERROR_INVALID_DATA; } IFCALLRET(context->ApplicationRemoved, error, context, &pdu); @@ -352,7 +355,8 @@ static UINT encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(body - end))) return ERROR_INVALID_DATA; - Stream_SetPosition(s, body); + if (!Stream_SetPosition(s, body)) + return ERROR_INVALID_DATA; } IFCALLRET(context->WindowCreated, error, context, &pdu); @@ -405,7 +409,8 @@ static UINT encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(body - end))) return ERROR_INVALID_DATA; - Stream_SetPosition(s, body); + if (!Stream_SetPosition(s, body)) + return ERROR_INVALID_DATA; } IFCALLRET(context->WindowRemoved, error, context, &pdu); @@ -458,7 +463,8 @@ static UINT encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(body - end))) return ERROR_INVALID_DATA; - Stream_SetPosition(s, body); + if (!Stream_SetPosition(s, body)) + return ERROR_INVALID_DATA; } IFCALLRET(context->ShowWindow, error, context, &pdu); @@ -520,7 +526,8 @@ static UINT encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(body - end))) return ERROR_INVALID_DATA; - Stream_SetPosition(s, body); + if (!Stream_SetPosition(s, body)) + return ERROR_INVALID_DATA; } IFCALLRET(context->ParticipantCreated, error, context, &pdu); @@ -572,7 +579,8 @@ static UINT encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(body - end))) return ERROR_INVALID_DATA; - Stream_SetPosition(s, body); + if (!Stream_SetPosition(s, body)) + return ERROR_INVALID_DATA; } IFCALLRET(context->ParticipantRemoved, error, context, &pdu); @@ -626,7 +634,8 @@ static UINT encomsp_recv_change_participant_control_level_pdu(encomspPlugin* enc if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(body - end))) return ERROR_INVALID_DATA; - Stream_SetPosition(s, body); + if (!Stream_SetPosition(s, body)) + return ERROR_INVALID_DATA; } IFCALLRET(context->ChangeParticipantControlLevel, error, context, &pdu); @@ -713,7 +722,8 @@ static UINT encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStr if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(body - end))) return ERROR_INVALID_DATA; - Stream_SetPosition(s, body); + if (!Stream_SetPosition(s, body)) + return ERROR_INVALID_DATA; } IFCALLRET(context->GraphicsStreamPaused, error, context, &pdu); @@ -762,7 +772,8 @@ static UINT encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wSt if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)(body - end))) return ERROR_INVALID_DATA; - Stream_SetPosition(s, body); + if (!Stream_SetPosition(s, body)) + return ERROR_INVALID_DATA; } IFCALLRET(context->GraphicsStreamResumed, error, context, &pdu); diff --git a/channels/encomsp/server/encomsp_main.c b/channels/encomsp/server/encomsp_main.c index 0bfb4a0c1..dc2591930 100644 --- a/channels/encomsp/server/encomsp_main.c +++ b/channels/encomsp/server/encomsp_main.c @@ -84,7 +84,8 @@ static UINT encomsp_recv_change_participant_control_level_pdu(EncomspServerConte if (!Stream_CheckAndLogRequiredLength(TAG, s, (size_t)((beg + header->Length) - end))) return ERROR_INVALID_DATA; - Stream_SetPosition(s, (beg + header->Length)); + if (!Stream_SetPosition(s, (beg + header->Length))) + return ERROR_INVALID_DATA; } IFCALLRET(context->ChangeParticipantControlLevel, error, context, &pdu); diff --git a/channels/gfxredir/server/gfxredir_main.c b/channels/gfxredir/server/gfxredir_main.c index 6dcc9dd55..5f4ed7ef2 100644 --- a/channels/gfxredir/server/gfxredir_main.c +++ b/channels/gfxredir/server/gfxredir_main.c @@ -179,7 +179,8 @@ static UINT gfxredir_server_receive_pdu(GfxRedirServerContext* context, wStream* { WLog_ERR(TAG, "Unexpected GFXREDIR pdu end: Actual: %" PRIuz ", Expected: %" PRIuz "", end, (beg + header.length)); - Stream_SetPosition(s, (beg + header.length)); + if (!Stream_SetPosition(s, (beg + header.length))) + return ERROR_INVALID_DATA; } return error; diff --git a/channels/location/client/location_main.c b/channels/location/client/location_main.c index 1cd01b222..6c6fb95bc 100644 --- a/channels/location/client/location_main.c +++ b/channels/location/client/location_main.c @@ -103,7 +103,8 @@ static UINT location_channel_send(IWTSVirtualChannel* channel, wStream* s) if (len > UINT32_MAX) return ERROR_INTERNAL_ERROR; - Stream_SetPosition(s, 2); + if (!Stream_SetPosition(s, 2)) + return ERROR_INVALID_DATA; Stream_Write_UINT32(s, (UINT32)len); WINPR_ASSERT(channel); diff --git a/channels/rail/client/rail_orders.c b/channels/rail/client/rail_orders.c index 4f43077c8..6b4e62051 100644 --- a/channels/rail/client/rail_orders.c +++ b/channels/rail/client/rail_orders.c @@ -42,7 +42,6 @@ static BOOL rail_is_feature_supported(const rdpContext* context, UINT32 featureM UINT rail_send_pdu(railPlugin* rail, wStream* s, UINT16 orderType) { char buffer[128] = WINPR_C_ARRAY_INIT; - UINT16 orderLength = 0; if (!rail || !s) { @@ -50,13 +49,19 @@ UINT rail_send_pdu(railPlugin* rail, wStream* s, UINT16 orderType) return ERROR_INVALID_PARAMETER; } - orderLength = (UINT16)Stream_GetPosition(s); + const UINT16 orderLength = (UINT16)Stream_GetPosition(s); Stream_ResetPosition(s); - rail_write_pdu_header(s, orderType, orderLength); - Stream_SetPosition(s, orderLength); + if (!rail_write_pdu_header(s, orderType, orderLength)) + goto fail; + if (!Stream_SetPosition(s, orderLength)) + goto fail; WLog_Print(rail->log, WLOG_DEBUG, "Sending %s PDU, length: %" PRIu16 "", rail_get_order_type_string_full(orderType, buffer, sizeof(buffer)), orderLength); return rail_send_channel_data(rail, s); + +fail: + Stream_Free(s, TRUE); + return ERROR_INVALID_DATA; } /** diff --git a/channels/rail/rail_common.c b/channels/rail/rail_common.c index c98afba80..b5c796f1c 100644 --- a/channels/rail/rail_common.c +++ b/channels/rail/rail_common.c @@ -113,10 +113,13 @@ UINT rail_read_pdu_header(wStream* s, UINT16* orderType, UINT16* orderLength) return CHANNEL_RC_OK; } -void rail_write_pdu_header(wStream* s, UINT16 orderType, UINT16 orderLength) +BOOL rail_write_pdu_header(wStream* s, UINT16 orderType, UINT16 orderLength) { + if (!Stream_EnsureRemainingCapacity(s, 4)) + return FALSE; Stream_Write_UINT16(s, orderType); /* orderType (2 bytes) */ Stream_Write_UINT16(s, orderLength); /* orderLength (2 bytes) */ + return TRUE; } wStream* rail_pdu_init(size_t length) diff --git a/channels/rail/rail_common.h b/channels/rail/rail_common.h index df6106f63..0ddea64fb 100644 --- a/channels/rail/rail_common.h +++ b/channels/rail/rail_common.h @@ -72,8 +72,9 @@ WINPR_ATTR_NODISCARD FREERDP_LOCAL wStream* rail_pdu_init(size_t length); WINPR_ATTR_NODISCARD FREERDP_LOCAL UINT rail_read_pdu_header(wStream* s, UINT16* orderType, UINT16* orderLength); +WINPR_ATTR_NODISCARD FREERDP_LOCAL -void rail_write_pdu_header(wStream* s, UINT16 orderType, UINT16 orderLength); +BOOL rail_write_pdu_header(wStream* s, UINT16 orderType, UINT16 orderLength); WINPR_ATTR_NODISCARD FREERDP_LOCAL UINT rail_write_unicode_string(wStream* s, const RAIL_UNICODE_STRING* unicode_string); diff --git a/channels/rail/server/rail_main.c b/channels/rail/server/rail_main.c index 686427f32..7a4b41bd0 100644 --- a/channels/rail/server/rail_main.c +++ b/channels/rail/server/rail_main.c @@ -71,11 +71,17 @@ static UINT rail_server_send_pdu(RailServerContext* context, wStream* s, UINT16 orderLength = (UINT16)Stream_GetPosition(s); Stream_ResetPosition(s); - rail_write_pdu_header(s, orderType, orderLength); - Stream_SetPosition(s, orderLength); + if (!rail_write_pdu_header(s, orderType, orderLength)) + goto fail; + if (!Stream_SetPosition(s, orderLength)) + goto fail; WLog_DBG(TAG, "Sending %s PDU, length: %" PRIu16 "", rail_get_order_type_string_full(orderType, buffer, sizeof(buffer)), orderLength); return rail_send(context, s, orderLength); + +fail: + Stream_Free(s, TRUE); + return ERROR_INVALID_DATA; } /** diff --git a/channels/rdpdr/client/irp.c b/channels/rdpdr/client/irp.c index b235b3201..adc0660ab 100644 --- a/channels/rdpdr/client/irp.c +++ b/channels/rdpdr/client/irp.c @@ -68,14 +68,18 @@ static UINT irp_complete(IRP* irp) rdpdrPlugin* rdpdr = (rdpdrPlugin*)irp->devman->plugin; WINPR_ASSERT(rdpdr); + UINT error = ERROR_INVALID_DATA; + const size_t pos = Stream_GetPosition(irp->output); - Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4); + if (!Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4)) + goto fail; Stream_Write_INT32(irp->output, irp->IoStatus); /* IoStatus (4 bytes) */ - Stream_SetPosition(irp->output, pos); + if (!Stream_SetPosition(irp->output, pos)) + goto fail; - const UINT error = rdpdr_send(rdpdr, irp->output); + error = rdpdr_send(rdpdr, irp->output); irp->output = nullptr; - +fail: irp_free(irp); return error; } diff --git a/channels/rdpdr/client/rdpdr_main.c b/channels/rdpdr/client/rdpdr_main.c index 7b51f6c47..8ed716aa4 100644 --- a/channels/rdpdr/client/rdpdr_main.c +++ b/channels/rdpdr/client/rdpdr_main.c @@ -1482,9 +1482,17 @@ static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use return CHANNEL_RC_OK; } pos = Stream_GetPosition(s); - Stream_SetPosition(s, count_pos); + if (!Stream_SetPosition(s, count_pos)) + { + Stream_Release(s); + return ERROR_INVALID_DATA; + } Stream_Write_UINT32(s, arg.count); - Stream_SetPosition(s, pos); + if (!Stream_SetPosition(s, pos)) + { + Stream_Release(s); + return ERROR_INVALID_DATA; + } Stream_SealLength(s); return rdpdr_send(rdpdr, s); } @@ -1514,7 +1522,11 @@ static UINT dummy_irp_response(rdpdrPlugin* rdpdr, wStream* s) return CHANNEL_RC_NO_MEMORY; } - Stream_SetPosition(s, 4); /* see "rdpdr_process_receive" */ + if (!Stream_SetPosition(s, 4)) /* see "rdpdr_process_receive" */ + { + Stream_Release(output); + return ERROR_INVALID_DATA; + } const uint32_t DeviceId = Stream_Get_UINT32(s); /* DeviceId (4 bytes) */ const uint32_t FileId = Stream_Get_UINT32(s); /* FileId (4 bytes) */ diff --git a/channels/rdpei/client/rdpei_main.c b/channels/rdpei/client/rdpei_main.c index 10d005964..f727b1eed 100644 --- a/channels/rdpei/client/rdpei_main.c +++ b/channels/rdpei/client/rdpei_main.c @@ -233,7 +233,8 @@ static UINT rdpei_send_pdu(GENERIC_CHANNEL_CALLBACK* callback, wStream* s, UINT1 Stream_ResetPosition(s); Stream_Write_UINT16(s, eventId); /* eventId (2 bytes) */ Stream_Write_UINT32(s, (UINT32)pduLength); /* pduLength (4 bytes) */ - Stream_SetPosition(s, Stream_Length(s)); + if (!Stream_SetPosition(s, Stream_Length(s))) + return ERROR_INVALID_DATA; const UINT status = callback->channel->Write(callback->channel, (UINT32)Stream_Length(s), Stream_Buffer(s), nullptr); #ifdef WITH_DEBUG_RDPEI diff --git a/channels/rdpgfx/client/rdpgfx_main.c b/channels/rdpgfx/client/rdpgfx_main.c index c18a91dd2..925d9ab17 100644 --- a/channels/rdpgfx/client/rdpgfx_main.c +++ b/channels/rdpgfx/client/rdpgfx_main.c @@ -2001,7 +2001,8 @@ static UINT rdpgfx_recv_pdu(GENERIC_CHANNEL_CALLBACK* callback, wStream* s) { WLog_Print(gfx->log, WLOG_ERROR, "Error while processing GFX cmdId: %s (0x%04" PRIX16 ")", rdpgfx_get_cmd_id_string(header.cmdId), header.cmdId); - Stream_SetPosition(s, (beg + header.pduLength)); + if (!Stream_SetPosition(s, (beg + header.pduLength))) + return ERROR_INVALID_DATA; return error; } @@ -2012,7 +2013,8 @@ static UINT rdpgfx_recv_pdu(GENERIC_CHANNEL_CALLBACK* callback, wStream* s) WLog_Print(gfx->log, WLOG_ERROR, "Unexpected gfx pdu end: Actual: %" PRIuz ", Expected: %" PRIuz, end, (beg + header.pduLength)); - Stream_SetPosition(s, (beg + header.pduLength)); + if (!Stream_SetPosition(s, (beg + header.pduLength))) + return ERROR_INVALID_DATA; } return error; diff --git a/channels/rdpgfx/server/rdpgfx_main.c b/channels/rdpgfx/server/rdpgfx_main.c index 40208425f..15a3701c4 100644 --- a/channels/rdpgfx/server/rdpgfx_main.c +++ b/channels/rdpgfx/server/rdpgfx_main.c @@ -102,10 +102,10 @@ static inline BOOL rdpgfx_server_packet_complete_header(wStream* s, size_t start if ((start > UINT32_MAX) || (current < start)) return FALSE; /* Fill actual length */ - Stream_SetPosition(s, start + RDPGFX_HEADER_SIZE - sizeof(UINT32)); + if (!Stream_SetPosition(s, start + RDPGFX_HEADER_SIZE - sizeof(UINT32))) + return FALSE; Stream_Write_UINT32(s, (UINT32)(current - start)); /* pduLength (4 bytes) */ - Stream_SetPosition(s, current); - return TRUE; + return Stream_SetPosition(s, current); } /** @@ -312,7 +312,11 @@ static UINT rdpgfx_send_reset_graphics_pdu(RdpgfxServerContext* context, } /* pad (total size must be 340 bytes) */ - Stream_SetPosition(s, RDPGFX_RESET_GRAPHICS_PDU_SIZE); + if (!Stream_SetPosition(s, RDPGFX_RESET_GRAPHICS_PDU_SIZE)) + { + Stream_Free(s, TRUE); + return ERROR_INVALID_DATA; + } return rdpgfx_server_single_packet_send(context, s); } @@ -764,7 +768,8 @@ static UINT rdpgfx_write_surface_command(wLog* log, wStream* s, const RDPGFX_SUR if (bitmapDataLength > UINT32_MAX) return ERROR_INTERNAL_ERROR; - Stream_SetPosition(s, bitmapDataStart - sizeof(UINT32)); + if (!Stream_SetPosition(s, bitmapDataStart - sizeof(UINT32))) + return ERROR_INVALID_DATA; if (!Stream_EnsureRemainingCapacity(s, 4)) return ERROR_INTERNAL_ERROR; Stream_Write_UINT32(s, (UINT32)bitmapDataLength); /* bitmapDataLength (4 bytes) */ @@ -1481,7 +1486,8 @@ static UINT rdpgfx_server_receive_pdu(RdpgfxServerContext* context, wStream* s) WLog_Print(context->priv->log, WLOG_ERROR, "Unexpected gfx pdu end: Actual: %" PRIuz ", Expected: %" PRIuz "", end, (beg + header.pduLength)); - Stream_SetPosition(s, (beg + header.pduLength)); + if (!Stream_SetPosition(s, (beg + header.pduLength))) + return ERROR_INVALID_DATA; } return error; diff --git a/channels/rdpsnd/server/rdpsnd_main.c b/channels/rdpsnd/server/rdpsnd_main.c index 79a48cb4b..8322704ff 100644 --- a/channels/rdpsnd/server/rdpsnd_main.c +++ b/channels/rdpsnd/server/rdpsnd_main.c @@ -89,9 +89,11 @@ static UINT rdpsnd_server_send_formats(RdpsndServerContext* context) goto fail; WINPR_ASSERT(pos >= 4); - Stream_SetPosition(s, 2); + if (!Stream_SetPosition(s, 2)) + goto fail; Stream_Write_UINT16(s, (UINT16)(pos - 4)); - Stream_SetPosition(s, pos); + if (!Stream_SetPosition(s, pos)) + goto fail; WINPR_ASSERT(context->priv); @@ -457,7 +459,8 @@ static UINT rdpsnd_server_training(RdpsndServerContext* context, UINT16 timestam if ((end < 4) || (end > UINT16_MAX)) return ERROR_INTERNAL_ERROR; - Stream_SetPosition(s, 2); + if (!Stream_SetPosition(s, 2)) + return ERROR_INTERNAL_ERROR; Stream_Write_UINT16(s, (UINT16)(end - 4)); status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_BufferAs(s, char), @@ -536,9 +539,11 @@ static UINT rdpsnd_server_send_wave_pdu(RdpsndServerContext* context, UINT16 wTi const size_t pos = end - start + 8ULL; if (pos > UINT16_MAX) return ERROR_INTERNAL_ERROR; - Stream_SetPosition(s, 2); + if (!Stream_SetPosition(s, 2)) + return ERROR_INTERNAL_ERROR; Stream_Write_UINT16(s, (UINT16)pos); - Stream_SetPosition(s, end); + if (!Stream_SetPosition(s, end)) + return ERROR_INTERNAL_ERROR; if (!WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_BufferAs(s, char), (UINT32)(start + 4), &written)) @@ -554,9 +559,17 @@ static UINT rdpsnd_server_send_wave_pdu(RdpsndServerContext* context, UINT16 wTi goto out; } - Stream_SetPosition(s, start); + if (!Stream_SetPosition(s, start)) + { + error = ERROR_INTERNAL_ERROR; + goto out; + } Stream_Write_UINT32(s, 0); /* bPad */ - Stream_SetPosition(s, start); + if (!Stream_SetPosition(s, start)) + { + error = ERROR_INTERNAL_ERROR; + goto out; + } WINPR_ASSERT((end - start) <= UINT32_MAX); if (!WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Pointer(s), @@ -643,7 +656,11 @@ static UINT rdpsnd_server_send_wave2_pdu(RdpsndServerContext* context, UINT16 fo goto out; } - Stream_SetPosition(s, 2); + if (!Stream_SetPosition(s, 2)) + { + error = ERROR_INTERNAL_ERROR; + goto out; + } Stream_Write_UINT16(s, (UINT16)(end - 4)); status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_BufferAs(s, char), @@ -835,9 +852,11 @@ static UINT rdpsnd_server_close(RdpsndServerContext* context) Stream_Seek_UINT16(s); const size_t pos = Stream_GetPosition(s); WINPR_ASSERT(pos >= 4); - Stream_SetPosition(s, 2); + if (!Stream_SetPosition(s, 2)) + return ERROR_INVALID_DATA; Stream_Write_UINT16(s, WINPR_ASSERTING_INT_CAST(uint16_t, pos - 4)); - Stream_SetPosition(s, pos); + if (!Stream_SetPosition(s, pos)) + return ERROR_INVALID_DATA; const size_t len = Stream_GetPosition(s); WINPR_ASSERT(len <= UINT32_MAX); @@ -1099,7 +1118,7 @@ void rdpsnd_server_context_reset(RdpsndServerContext* context) context->priv->expectedBytes = 4; context->priv->waitingHeader = TRUE; - Stream_SetPosition(context->priv->input_stream, 0); + Stream_ResetPosition(context->priv->input_stream); } void rdpsnd_server_context_free(RdpsndServerContext* context) diff --git a/channels/tsmf/client/tsmf_codec.c b/channels/tsmf/client/tsmf_codec.c index 49b56e53c..e3d583e38 100644 --- a/channels/tsmf/client/tsmf_codec.c +++ b/channels/tsmf/client/tsmf_codec.c @@ -594,7 +594,8 @@ BOOL tsmf_codec_check_media_type(const char* decoder_name, wStream* s) pos = Stream_GetPosition(s); if (decoderAvailable) ret = tsmf_codec_parse_media_type(&mediatype, s); - Stream_SetPosition(s, pos); + if (!Stream_SetPosition(s, pos)) + return FALSE; if (ret) { diff --git a/channels/tsmf/client/tsmf_ifman.c b/channels/tsmf/client/tsmf_ifman.c index 4192b67ce..3c4f0ab83 100644 --- a/channels/tsmf/client/tsmf_ifman.c +++ b/channels/tsmf/client/tsmf_ifman.c @@ -81,7 +81,8 @@ UINT tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman) const size_t xpos = Stream_GetPosition(ifman->output); Stream_Copy(ifman->input, ifman->output, ifman->input_size); - Stream_SetPosition(ifman->output, xpos); + if (!Stream_SetPosition(ifman->output, xpos)) + return ERROR_INVALID_DATA; if (!Stream_CheckAndLogRequiredLength(TAG, ifman->output, 4)) return ERROR_INVALID_DATA; @@ -133,7 +134,8 @@ UINT tsmf_ifman_exchange_capability_request(TSMF_IFMAN* ifman) break; } - Stream_SetPosition(ifman->output, pos + cbCapabilityLength); + if (!Stream_SetPosition(ifman->output, pos + cbCapabilityLength)) + return ERROR_INVALID_DATA; } Stream_Write_UINT32(ifman->output, 0); /* Result */ @@ -504,7 +506,8 @@ UINT tsmf_ifman_update_geometry_info(TSMF_IFMAN* ifman) Stream_Read_UINT32(ifman->input, Height); Stream_Read_UINT32(ifman->input, Left); Stream_Read_UINT32(ifman->input, Top); - Stream_SetPosition(ifman->input, pos + numGeometryInfo); + if (!Stream_SetPosition(ifman->input, pos + numGeometryInfo)) + return ERROR_INVALID_DATA; Stream_Read_UINT32(ifman->input, cbVisibleRect); const UINT32 num_rects = cbVisibleRect / 16; DEBUG_TSMF("numGeometryInfo %" PRIu32 " Width %" PRIu32 " Height %" PRIu32 " Left %" PRIu32 diff --git a/channels/urbdrc/client/libusb/libusb_udevice.c b/channels/urbdrc/client/libusb/libusb_udevice.c index d70fab4e9..cb7178556 100644 --- a/channels/urbdrc/client/libusb/libusb_udevice.c +++ b/channels/urbdrc/client/libusb/libusb_udevice.c @@ -265,8 +265,9 @@ static void LIBUSB_CALL func_iso_callback(struct libusb_transfer* transfer) { UINT32 index = 0; BYTE* dataStart = Stream_Pointer(user_data->data); - Stream_SetPosition(user_data->data, - 40); /* TS_URB_ISOCH_TRANSFER_RESULT IsoPacket offset */ + if (!Stream_SetPosition(user_data->data, + 40)) /* TS_URB_ISOCH_TRANSFER_RESULT IsoPacket offset */ + return; for (uint32_t i = 0; i < WINPR_ASSERTING_INT_CAST(uint32_t, transfer->num_iso_packets); i++) diff --git a/channels/urbdrc/common/urbdrc_helpers.c b/channels/urbdrc/common/urbdrc_helpers.c index 7730a7f98..61ded4f48 100644 --- a/channels/urbdrc/common/urbdrc_helpers.c +++ b/channels/urbdrc/common/urbdrc_helpers.c @@ -409,7 +409,8 @@ void urbdrc_dump_message(wLog* log, BOOL client, BOOL write, wStream* s) Stream_Read_UINT32(s, InterfaceId); Stream_Read_UINT32(s, MessageId); Stream_Read_UINT32(s, FunctionId); - Stream_SetPosition(s, pos); + if (!Stream_SetPosition(s, pos)) + WLog_Print(log, WLOG_ERROR, "Stream_SetPosition(%" PRIuz ") failed", pos); WLog_Print(log, WLOG_DEBUG, "[%-5s] %s [%08" PRIx32 "] InterfaceId=%08" PRIx32 ", MessageId=%08" PRIx32 diff --git a/libfreerdp/codec/zgfx.c b/libfreerdp/codec/zgfx.c index 7a8ed4448..b48e94e9b 100644 --- a/libfreerdp/codec/zgfx.c +++ b/libfreerdp/codec/zgfx.c @@ -568,9 +568,11 @@ int zgfx_compress_to_stream(ZGFX_CONTEXT* WINPR_RESTRICT zgfx, wStream* WINPR_RE const size_t DstSize = Stream_GetPosition(sDst) - posDataStart; if (DstSize > UINT32_MAX) return -1; - Stream_SetPosition(sDst, posDstSize); + if (!Stream_SetPosition(sDst, posDstSize)) + return -1; Stream_Write_UINT32(sDst, (UINT32)DstSize); - Stream_SetPosition(sDst, posDataStart + DstSize); + if (!Stream_SetPosition(sDst, posDataStart + DstSize)) + return -1; } pSrcData += SrcSize; @@ -581,9 +583,11 @@ int zgfx_compress_to_stream(ZGFX_CONTEXT* WINPR_RESTRICT zgfx, wStream* WINPR_RE /* fill back segmentCount */ if (posSegmentCount) { - Stream_SetPosition(sDst, posSegmentCount); + if (!Stream_SetPosition(sDst, posSegmentCount)) + return -1; Stream_Write_UINT16(sDst, WINPR_ASSERTING_INT_CAST(uint16_t, fragment)); - Stream_SetPosition(sDst, Stream_Length(sDst)); + if (!Stream_SetPosition(sDst, Stream_Length(sDst))) + return -1; } return status; diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c index eaa4b2665..5f97c14fd 100644 --- a/libfreerdp/core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -147,10 +147,10 @@ static BOOL rdp_capability_set_finish(wStream* s, size_t header, UINT16 type) const size_t length = footer - header; if ((Stream_Capacity(s) < header + 4ULL) || (length > UINT16_MAX)) return FALSE; - Stream_SetPosition(s, header); + if (!Stream_SetPosition(s, header)) + return FALSE; rdp_write_capability_set_header(s, (UINT16)length, type); - Stream_SetPosition(s, footer); - return TRUE; + return Stream_SetPosition(s, footer); } static BOOL rdp_apply_general_capability_set(rdpSettings* settings, const rdpSettings* src) @@ -3946,7 +3946,9 @@ BOOL rdp_print_capability_sets(wLog* log, wStream* s, size_t start, BOOL receivi size_t pos = Stream_GetPosition(s); - Stream_SetPosition(s, start); + if (!Stream_SetPosition(s, start)) + goto fail; + if (receiving) { if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4)) @@ -4170,7 +4172,9 @@ BOOL rdp_print_capability_sets(wLog* log, wStream* s, size_t start, BOOL receivi rc = TRUE; fail: - Stream_SetPosition(s, pos); + if (!Stream_SetPosition(s, pos)) + return FALSE; + return rc; } #endif @@ -4692,18 +4696,21 @@ static BOOL rdp_write_demand_active(wLog* log, wStream* s, rdpSettings* settings } em = Stream_GetPosition(s); - Stream_SetPosition(s, lm); /* go back to lengthCombinedCapabilities */ + if (!Stream_SetPosition(s, lm)) /* go back to lengthCombinedCapabilities */ + return FALSE; lengthCombinedCapabilities = (em - bm); if (lengthCombinedCapabilities > UINT16_MAX) return FALSE; Stream_Write_UINT16( s, (UINT16)lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ - Stream_SetPosition(s, bm); /* go back to numberCapabilities */ + if (!Stream_SetPosition(s, bm)) /* go back to numberCapabilities */ + return FALSE; Stream_Write_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ #ifdef WITH_DEBUG_CAPABILITIES rdp_print_capability_sets(log, s, bm, FALSE); #endif - Stream_SetPosition(s, em); + if (!Stream_SetPosition(s, em)) + return FALSE; Stream_Write_UINT32(s, 0); /* sessionId */ return TRUE; } @@ -4931,20 +4938,20 @@ static BOOL rdp_write_confirm_active(wLog* log, wStream* s, rdpSettings* setting } em = Stream_GetPosition(s); - Stream_SetPosition(s, lm); /* go back to lengthCombinedCapabilities */ + if (!Stream_SetPosition(s, lm)) /* go back to lengthCombinedCapabilities */ + return FALSE; lengthCombinedCapabilities = (em - bm); if (lengthCombinedCapabilities > UINT16_MAX) return FALSE; Stream_Write_UINT16( s, (UINT16)lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ - Stream_SetPosition(s, bm); /* go back to numberCapabilities */ + if (!Stream_SetPosition(s, bm)) /* go back to numberCapabilities */ + return FALSE; Stream_Write_UINT16(s, numberCapabilities); /* numberCapabilities (2 bytes) */ #ifdef WITH_DEBUG_CAPABILITIES rdp_print_capability_sets(log, s, bm, FALSE); #endif - Stream_SetPosition(s, em); - - return TRUE; + return Stream_SetPosition(s, em); } BOOL rdp_send_confirm_active(rdpRdp* rdp) diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index d2ca1c1a9..3a8032e49 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -1191,14 +1191,17 @@ state_run_t rdp_handle_message_channel(rdpRdp* rdp, wStream* s, UINT16 channelId BOOL rdp_client_connect_auto_detect(rdpRdp* rdp, wStream* s, DWORD logLevel) { + BOOL res = TRUE; WINPR_ASSERT(rdp); WINPR_ASSERT(rdp->mcs); - const size_t pos = Stream_GetPosition(s); + size_t pos = Stream_GetPosition(s); UINT16 length = 0; UINT16 channelId = 0; - if (rdp_read_header(rdp, s, &length, &channelId)) + if (!rdp_read_header(rdp, s, &length, &channelId)) + res = FALSE; + else { const UINT16 messageChannelId = rdp->mcs->messageChannelId; /* If the MCS message channel has been joined... */ @@ -1207,18 +1210,21 @@ BOOL rdp_client_connect_auto_detect(rdpRdp* rdp, wStream* s, DWORD logLevel) if (rdp->mcs->messageChannelJoined && (channelId == messageChannelId)) { const state_run_t rc = rdp_handle_message_channel(rdp, s, channelId, length); - return state_run_success(rc); + res = state_run_success(rc); + pos = Stream_GetPosition(s); } else { wLog* log = WLog_Get(TAG); WLog_Print(log, logLevel, "expected messageChannelId=%" PRIu16 ", got %" PRIu16, messageChannelId, channelId); + res = FALSE; } } - Stream_SetPosition(s, pos); - return FALSE; + if (!Stream_SetPosition(s, pos)) + res = FALSE; + return res; } state_run_t rdp_client_connect_license(rdpRdp* rdp, wStream* s) diff --git a/libfreerdp/core/fastpath.c b/libfreerdp/core/fastpath.c index 801098af7..38ae0329a 100644 --- a/libfreerdp/core/fastpath.c +++ b/libfreerdp/core/fastpath.c @@ -1131,9 +1131,11 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, size_t * the data first and then store the header. */ WINPR_ASSERT(length < UINT16_MAX); - Stream_SetPosition(s, 1); + if (!Stream_SetPosition(s, 1)) + goto fail; Stream_Write_UINT16_BE(s, 0x8000 | (UINT16)length); - Stream_SetPosition(s, length); + if (!Stream_SetPosition(s, length)) + goto fail; Stream_SealLength(s); } diff --git a/libfreerdp/core/gateway/rpc_bind.c b/libfreerdp/core/gateway/rpc_bind.c index b0d1deb57..f2e9cba06 100644 --- a/libfreerdp/core/gateway/rpc_bind.c +++ b/libfreerdp/core/gateway/rpc_bind.c @@ -346,9 +346,11 @@ BOOL rpc_recv_bind_ack_pdu(rdpRpc* rpc, wStream* s) /* Get the correct offset in the input data and pass that on as input buffer. * rts_read_pdu_header did already do consistency checks */ end = Stream_GetPosition(s); - Stream_SetPosition(s, pos + header.common.frag_length - header.common.auth_length); + if (!Stream_SetPosition(s, pos + header.common.frag_length - header.common.auth_length)) + goto fail; auth_data = Stream_ConstPointer(s); - Stream_SetPosition(s, end); + if (!Stream_SetPosition(s, end)) + goto fail; buffer.cbBuffer = header.common.auth_length; buffer.pvBuffer = malloc(buffer.cbBuffer); diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index 16f0b51b8..bb807e250 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -424,7 +424,8 @@ static int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment) if (Stream_Length(fragment) < StubOffset + 4) goto fail; - Stream_SetPosition(fragment, StubOffset); + if (!Stream_SetPosition(fragment, StubOffset)) + goto fail; Stream_Read_UINT32(fragment, rpc->result); utils_abort_connect(context->rdp); @@ -470,7 +471,8 @@ static int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment) if (Stream_Length(fragment) < StubOffset + StubLength) goto fail; - Stream_SetPosition(fragment, StubOffset); + if (!Stream_SetPosition(fragment, StubOffset)) + goto fail; Stream_Write(pdu->s, Stream_ConstPointer(fragment), StubLength); rpc->StubFragCount++; @@ -493,7 +495,8 @@ static int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment) const rpcconn_response_hdr_t* response = &header.response; if (Stream_Length(fragment) < StubOffset + StubLength) goto fail; - Stream_SetPosition(fragment, StubOffset); + if (!Stream_SetPosition(fragment, StubOffset)) + goto fail; rpc_client_receive_pipe_write(rpc->client, Stream_ConstPointer(fragment), StubLength); rpc->StubFragCount++; @@ -704,7 +707,8 @@ static SSIZE_T rpc_client_default_out_channel_recv(rdpRpc* rpc) if (rc == RTS_PDU_FAIL) return -1; - Stream_SetPosition(fragment, pos); + if (!Stream_SetPosition(fragment, pos)) + return -1; if (header.frag_length > rpc->max_recv_frag) { diff --git a/libfreerdp/core/gateway/rts.c b/libfreerdp/core/gateway/rts.c index 0b2d001ea..e0543177f 100644 --- a/libfreerdp/core/gateway/rts.c +++ b/libfreerdp/core/gateway/rts.c @@ -288,7 +288,8 @@ static BOOL rts_read_auth_verifier_no_checks(wStream* s, auth_verifier_co_t* aut { const size_t expected = header->frag_length - header->auth_length - 8; - Stream_SetPosition(s, expected); + if (!Stream_SetPosition(s, expected)) + return FALSE; if (!Stream_ConditionalCheckAndLogRequiredLength(TAG, s, 8, silent)) return FALSE; diff --git a/libfreerdp/core/gcc.c b/libfreerdp/core/gcc.c index b369e4b24..7a14d50fe 100644 --- a/libfreerdp/core/gcc.c +++ b/libfreerdp/core/gcc.c @@ -1834,14 +1834,15 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs) WINPR_ASSERT(end >= posHeader); const size_t diff = end - posHeader; WINPR_ASSERT(diff <= UINT16_MAX); - Stream_SetPosition(s, posHeader); + if (!Stream_SetPosition(s, posHeader)) + return FALSE; if (!gcc_write_user_data_header(s, SC_SECURITY, (UINT16)diff)) return FALSE; - Stream_SetPosition(s, posCertLen); + if (!Stream_SetPosition(s, posCertLen)) + return FALSE; WINPR_ASSERT(len <= UINT32_MAX); Stream_Write_UINT32(s, (UINT32)len); - Stream_SetPosition(s, end); - return TRUE; + return Stream_SetPosition(s, end); } /** diff --git a/libfreerdp/core/license.c b/libfreerdp/core/license.c index af746e1d3..bf20658e0 100644 --- a/libfreerdp/core/license.c +++ b/libfreerdp/core/license.c @@ -782,7 +782,8 @@ static BOOL license_send(rdpLicense* license, wStream* s, BYTE type, UINT16 sec_ WINPR_ASSERT(length <= UINT16_MAX + license->PacketHeaderLength); const UINT16 wMsgSize = (UINT16)(length - license->PacketHeaderLength); - Stream_SetPosition(s, license->PacketHeaderLength); + if (!Stream_SetPosition(s, license->PacketHeaderLength)) + return FALSE; BYTE flags = PREAMBLE_VERSION_3_0; /** @@ -805,7 +806,8 @@ static BOOL license_send(rdpLicense* license, wStream* s, BYTE type, UINT16 sec_ winpr_HexLogDump(license->log, WLOG_DEBUG, Stream_PointerAs(s, char) - LICENSE_PREAMBLE_LENGTH, wMsgSize); #endif - Stream_SetPosition(s, length); + if (!Stream_SetPosition(s, length)) + return FALSE; const BOOL ret = rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID, sec_flags); return ret; } diff --git a/libfreerdp/core/mcs.c b/libfreerdp/core/mcs.c index 742d85991..28797d66d 100644 --- a/libfreerdp/core/mcs.c +++ b/libfreerdp/core/mcs.c @@ -890,12 +890,14 @@ static BOOL mcs_send_connect_initial(rdpMcs* mcs) length = (em - bm); if (length > UINT16_MAX) goto out; - Stream_SetPosition(s, bm); + if (!Stream_SetPosition(s, bm)) + goto out; if (!tpkt_write_header(s, (UINT16)length)) goto out; if (!tpdu_write_data(s)) goto out; - Stream_SetPosition(s, em); + if (!Stream_SetPosition(s, em)) + goto out; Stream_SealLength(s); { @@ -1009,12 +1011,14 @@ BOOL mcs_send_connect_response(rdpMcs* mcs) length = (em - bm); if (length > UINT16_MAX) goto out; - Stream_SetPosition(s, bm); + if (!Stream_SetPosition(s, bm)) + goto out; if (!tpkt_write_header(s, (UINT16)length)) goto out; if (!tpdu_write_data(s)) goto out; - Stream_SetPosition(s, em); + if (!Stream_SetPosition(s, em)) + goto out; Stream_SealLength(s); { diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index 04fcd02cf..1dd385276 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -956,7 +956,8 @@ static BOOL nego_read_request_token_or_cookie(rdpNego* nego, wStream* s) if (!result) { - Stream_SetPosition(s, pos); + if (!Stream_SetPosition(s, pos)) + return FALSE; WLog_Print(nego->log, WLOG_ERROR, "invalid %s received", isToken ? "routing token" : "cookie"); } @@ -1154,12 +1155,14 @@ BOOL nego_send_negotiation_request(rdpNego* nego) goto fail; em = Stream_GetPosition(s); - Stream_SetPosition(s, bm); + if (!Stream_SetPosition(s, bm)) + goto fail; if (!tpkt_write_header(s, (UINT16)length)) goto fail; if (!tpdu_write_connection_request(s, (UINT16)length - 5)) goto fail; - Stream_SetPosition(s, em); + if (!Stream_SetPosition(s, em)) + goto fail; Stream_SealLength(s); rc = (transport_write(nego->transport, s) >= 0); fail: @@ -1489,11 +1492,7 @@ BOOL nego_process_negotiation_failure(rdpNego* nego, wStream* s) BOOL nego_send_negotiation_response(rdpNego* nego) { - UINT16 length = 0; - size_t bm = 0; - size_t em = 0; - BOOL status = 0; - wStream* s = nullptr; + BOOL status = FALSE; BYTE flags = 0; rdpContext* context = nullptr; rdpSettings* settings = nullptr; @@ -1505,7 +1504,7 @@ BOOL nego_send_negotiation_response(rdpNego* nego) settings = context->settings; WINPR_ASSERT(settings); - s = Stream_New(nullptr, 512); + wStream* s = Stream_New(nullptr, 512); if (!s) { @@ -1513,9 +1512,10 @@ BOOL nego_send_negotiation_response(rdpNego* nego) return FALSE; } - length = TPDU_CONNECTION_CONFIRM_LENGTH; - bm = Stream_GetPosition(s); - Stream_Seek(s, length); + UINT16 length = TPDU_CONNECTION_CONFIRM_LENGTH; + const size_t bm = Stream_GetPosition(s); + if (!Stream_SafeSeek(s, length)) + goto fail; if (nego->SelectedProtocol & PROTOCOL_FAILED_NEGO) { @@ -1548,19 +1548,22 @@ BOOL nego_send_negotiation_response(rdpNego* nego) length += 8; } - em = Stream_GetPosition(s); - Stream_SetPosition(s, bm); - status = tpkt_write_header(s, length); - if (status) - status = tpdu_write_connection_confirm(s, length - 5); + const size_t em = Stream_GetPosition(s); + if (!Stream_SetPosition(s, bm)) + goto fail; + if (!tpkt_write_header(s, length)) + goto fail; - if (status) - { - Stream_SetPosition(s, em); - Stream_SealLength(s); + if (!tpdu_write_connection_confirm(s, length - 5)) + goto fail; - status = (transport_write(nego->transport, s) >= 0); - } + if (!Stream_SetPosition(s, em)) + goto fail; + Stream_SealLength(s); + + status = (transport_write(nego->transport, s) >= 0); + +fail: Stream_Free(s, TRUE); if (status) diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index fd392034d..50f097b9b 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -1267,7 +1267,8 @@ static MSV1_0_REMOTE_SUPPLEMENTAL_CREDENTIAL* nla_read_NtlmCreds(WINPR_ATTR_UNUS if (!Stream_CheckAndLogRequiredLength(TAG, s, EncryptedCredsSize)) return nullptr; - Stream_SetPosition(s, pos); + if (!Stream_SetPosition(s, pos)) + return nullptr; MSV1_0_REMOTE_SUPPLEMENTAL_CREDENTIAL* ret = (MSV1_0_REMOTE_SUPPLEMENTAL_CREDENTIAL*)calloc( 1, sizeof(MSV1_0_REMOTE_SUPPLEMENTAL_CREDENTIAL) - 1 + EncryptedCredsSize); diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index c05860496..3e3f024a2 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -1189,7 +1189,10 @@ static state_run_t peer_recv_callback(rdpTransport* transport, wStream* s, void* const char* old = rdp_get_state_string(rdp); if (rc == STATE_RUN_TRY_AGAIN) - Stream_SetPosition(s, start); + { + if (!Stream_SetPosition(s, start)) + return STATE_RUN_FAILED; + } rc = peer_recv_callback_internal(transport, s, extra); const size_t len = Stream_GetRemainingLength(s); diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 368b84ab9..98213985f 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -849,7 +849,8 @@ BOOL rdp_send(rdpRdp* rdp, wStream* s, UINT16 channelId, UINT16 sec_flags) goto fail; length += pad; - Stream_SetPosition(s, length); + if (!Stream_SetPosition(s, length)) + goto fail; Stream_SealLength(s); } @@ -894,13 +895,15 @@ BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type, UINT16 channel_id, UINT1 Stream_Seek(s, sec_bytes); if (!rdp_write_share_control_header(rdp, s, length - sec_bytes, type, channel_id)) goto fail; - Stream_SetPosition(s, sec_hold); + if (!Stream_SetPosition(s, sec_hold)) + goto fail; if (!rdp_security_stream_out(rdp, s, length, sec_flags, &pad)) goto fail; length += pad; - Stream_SetPosition(s, length); + if (!Stream_SetPosition(s, length)) + goto fail; Stream_SealLength(s); } @@ -946,13 +949,15 @@ BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id, UI goto fail; if (!rdp_write_share_data_header(rdp, s, length - sec_bytes, type, rdp->settings->ShareId)) goto fail; - Stream_SetPosition(s, sec_hold); + if (!Stream_SetPosition(s, sec_hold)) + goto fail; if (!rdp_security_stream_out(rdp, s, length, sec_flags, &pad)) goto fail; length += pad; - Stream_SetPosition(s, length); + if (!Stream_SetPosition(s, length)) + goto fail; Stream_SealLength(s); } WLog_Print(rdp->log, WLOG_DEBUG, @@ -996,7 +1001,8 @@ BOOL rdp_send_message_channel_pdu(rdpRdp* rdp, wStream* s, UINT16 sec_flags) goto fail; length += pad; - Stream_SetPosition(s, length); + if (!Stream_SetPosition(s, length)) + goto fail; } Stream_SealLength(s); @@ -2203,7 +2209,10 @@ state_run_t rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra) WINPR_ASSERT(rdp); if (rc == STATE_RUN_TRY_AGAIN) - Stream_SetPosition(s, start); + { + if (!Stream_SetPosition(s, start)) + return STATE_RUN_FAILED; + } const char* old = rdp_get_state_string(rdp); const size_t orem = Stream_GetRemainingLength(s); diff --git a/libfreerdp/core/redirection.c b/libfreerdp/core/redirection.c index 1de5d3895..d28abadac 100644 --- a/libfreerdp/core/redirection.c +++ b/libfreerdp/core/redirection.c @@ -1081,9 +1081,11 @@ BOOL rdp_write_enhanced_security_redirection_packet(wStream* s, const rdpRedirec /* Write length field */ const size_t lend = Stream_GetPosition(s); - Stream_SetPosition(s, lstart); + if (!Stream_SetPosition(s, lstart)) + goto fail; Stream_Write_UINT32(s, length); - Stream_SetPosition(s, lend); + if (!Stream_SetPosition(s, lend)) + goto fail; } /* Padding 8 bytes */ @@ -1093,9 +1095,11 @@ BOOL rdp_write_enhanced_security_redirection_packet(wStream* s, const rdpRedirec { const size_t end = Stream_GetPosition(s); - Stream_SetPosition(s, lengthOffset); + if (!Stream_SetPosition(s, lengthOffset)) + goto fail; Stream_Write_UINT16(s, (UINT16)(end - start)); - Stream_SetPosition(s, end); + if (!Stream_SetPosition(s, end)) + goto fail; } } diff --git a/libfreerdp/core/streamdump.c b/libfreerdp/core/streamdump.c index cbd2b3afb..01829c69e 100644 --- a/libfreerdp/core/streamdump.c +++ b/libfreerdp/core/streamdump.c @@ -362,7 +362,8 @@ static int stream_dump_replay_transport_read(rdpTransport* transport, wStream* s const size_t start = Stream_GetPosition(s); do { - Stream_SetPosition(s, start); + if (!Stream_SetPosition(s, start)) + return -1; if (stream_dump_get(ctx, &flags, s, &ctx->dump->replayOffset, &ts) < 0) return -1; } while (flags & STREAM_MSG_SRV_RX); diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index 19b3e9973..fb2fc072f 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -1058,9 +1058,11 @@ static BOOL s_update_end_paint(rdpContext* context) update->us = nullptr; Stream_SealLength(s); - Stream_SetPosition(s, update->offsetOrders); + if (!Stream_SetPosition(s, update->offsetOrders)) + goto fail; Stream_Write_UINT16(s, update->numberOrders); /* numberOrders (2 bytes) */ - Stream_SetPosition(s, Stream_Length(s)); + if (!Stream_SetPosition(s, Stream_Length(s))) + goto fail; if (update->numberOrders > 0) { @@ -1245,7 +1247,9 @@ static int update_write_order_info(rdpContext* context, wStream* s, const ORDER_ const size_t position = Stream_GetPosition(s); const UINT8 controlFlags = (UINT8)orderInfo->controlFlags; - Stream_SetPosition(s, offset); + if (!Stream_SetPosition(s, offset)) + return -1; + Stream_Write_UINT8(s, controlFlags); /* controlFlags (1 byte) */ if (orderInfo->controlFlags & ORDER_TYPE_CHANGE) @@ -1258,7 +1262,8 @@ static int update_write_order_info(rdpContext* context, wStream* s, const ORDER_ return -1; if (!update_write_bounds(s, orderInfo)) return -1; - Stream_SetPosition(s, position); + if (!Stream_SetPosition(s, position)) + return -1; return 0; } @@ -1854,14 +1859,14 @@ static BOOL update_send_cache_bitmap(rdpContext* context, const CACHE_BITMAP_ORD const size_t orderLength = (em - bm) - 13; WINPR_ASSERT(orderLength <= UINT16_MAX); - Stream_SetPosition(s, bm); + if (!Stream_SetPosition(s, bm)) + return FALSE; Stream_Write_UINT8(s, ORDER_STANDARD | ORDER_SECONDARY); /* controlFlags (1 byte) */ Stream_Write_UINT16(s, (UINT16)orderLength); /* orderLength (2 bytes) */ Stream_Write_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ Stream_Write_UINT8(s, orderType); /* orderType (1 byte) */ - Stream_SetPosition(s, em); update->numberOrders++; - return TRUE; + return Stream_SetPosition(s, em); } static BOOL update_send_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORDER* cache_bitmap_v2) @@ -1905,14 +1910,14 @@ static BOOL update_send_cache_bitmap_v2(rdpContext* context, CACHE_BITMAP_V2_ORD const size_t orderLength = (em - bm) - 13; WINPR_ASSERT(orderLength <= UINT16_MAX); - Stream_SetPosition(s, bm); + if (!Stream_SetPosition(s, bm)) + return FALSE; Stream_Write_UINT8(s, ORDER_STANDARD | ORDER_SECONDARY); /* controlFlags (1 byte) */ Stream_Write_UINT16(s, (UINT16)orderLength); /* orderLength (2 bytes) */ Stream_Write_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ Stream_Write_UINT8(s, orderType); /* orderType (1 byte) */ - Stream_SetPosition(s, em); update->numberOrders++; - return TRUE; + return Stream_SetPosition(s, em); } static BOOL update_send_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORDER* cache_bitmap_v3) @@ -1949,14 +1954,14 @@ static BOOL update_send_cache_bitmap_v3(rdpContext* context, CACHE_BITMAP_V3_ORD const size_t orderLength = (em - bm) - 13; WINPR_ASSERT(orderLength <= UINT16_MAX); - Stream_SetPosition(s, bm); + if (!Stream_SetPosition(s, bm)) + return FALSE; Stream_Write_UINT8(s, ORDER_STANDARD | ORDER_SECONDARY); /* controlFlags (1 byte) */ Stream_Write_UINT16(s, (UINT16)orderLength); /* orderLength (2 bytes) */ Stream_Write_UINT16(s, extraFlags); /* extraFlags (2 bytes) */ Stream_Write_UINT8(s, orderType); /* orderType (1 byte) */ - Stream_SetPosition(s, em); update->numberOrders++; - return TRUE; + return Stream_SetPosition(s, em); } static BOOL update_send_cache_color_table(rdpContext* context, @@ -1992,14 +1997,14 @@ static BOOL update_send_cache_color_table(rdpContext* context, WINPR_ASSERT(em >= bm + 13); const size_t orderLength = (em - bm) - 13; WINPR_ASSERT(orderLength <= UINT16_MAX); - Stream_SetPosition(s, bm); + if (!Stream_SetPosition(s, bm)) + return FALSE; Stream_Write_UINT8(s, ORDER_STANDARD | ORDER_SECONDARY); /* controlFlags (1 byte) */ Stream_Write_UINT16(s, (UINT16)orderLength); /* orderLength (2 bytes) */ Stream_Write_UINT16(s, flags); /* extraFlags (2 bytes) */ Stream_Write_UINT8(s, ORDER_TYPE_CACHE_COLOR_TABLE); /* orderType (1 byte) */ - Stream_SetPosition(s, em); update->numberOrders++; - return TRUE; + return Stream_SetPosition(s, em); } static BOOL update_send_cache_glyph(rdpContext* context, const CACHE_GLYPH_ORDER* cache_glyph) @@ -2034,14 +2039,14 @@ static BOOL update_send_cache_glyph(rdpContext* context, const CACHE_GLYPH_ORDER WINPR_ASSERT(em >= bm + 13); const size_t orderLength = (em - bm) - 13; WINPR_ASSERT(orderLength <= UINT16_MAX); - Stream_SetPosition(s, bm); + if (!Stream_SetPosition(s, bm)) + return FALSE; Stream_Write_UINT8(s, ORDER_STANDARD | ORDER_SECONDARY); /* controlFlags (1 byte) */ Stream_Write_UINT16(s, (UINT16)orderLength); /* orderLength (2 bytes) */ Stream_Write_UINT16(s, flags); /* extraFlags (2 bytes) */ Stream_Write_UINT8(s, ORDER_TYPE_CACHE_GLYPH); /* orderType (1 byte) */ - Stream_SetPosition(s, em); update->numberOrders++; - return TRUE; + return Stream_SetPosition(s, em); } static BOOL update_send_cache_glyph_v2(rdpContext* context, @@ -2077,14 +2082,14 @@ static BOOL update_send_cache_glyph_v2(rdpContext* context, WINPR_ASSERT(em >= bm + 13); const size_t orderLength = (em - bm) - 13; WINPR_ASSERT(orderLength <= UINT16_MAX); - Stream_SetPosition(s, bm); + if (!Stream_SetPosition(s, bm)) + return FALSE; Stream_Write_UINT8(s, ORDER_STANDARD | ORDER_SECONDARY); /* controlFlags (1 byte) */ Stream_Write_UINT16(s, (UINT16)orderLength); /* orderLength (2 bytes) */ Stream_Write_UINT16(s, flags); /* extraFlags (2 bytes) */ Stream_Write_UINT8(s, ORDER_TYPE_CACHE_GLYPH); /* orderType (1 byte) */ - Stream_SetPosition(s, em); update->numberOrders++; - return TRUE; + return Stream_SetPosition(s, em); } static BOOL update_send_cache_brush(rdpContext* context, const CACHE_BRUSH_ORDER* cache_brush) @@ -2121,14 +2126,14 @@ static BOOL update_send_cache_brush(rdpContext* context, const CACHE_BRUSH_ORDER const size_t orderLength = (em - bm) - 13; WINPR_ASSERT(orderLength <= UINT16_MAX); - Stream_SetPosition(s, bm); + if (!Stream_SetPosition(s, bm)) + return FALSE; Stream_Write_UINT8(s, ORDER_STANDARD | ORDER_SECONDARY); /* controlFlags (1 byte) */ Stream_Write_UINT16(s, (UINT16)orderLength); /* orderLength (2 bytes) */ Stream_Write_UINT16(s, flags); /* extraFlags (2 bytes) */ Stream_Write_UINT8(s, ORDER_TYPE_CACHE_BRUSH); /* orderType (1 byte) */ - Stream_SetPosition(s, em); update->numberOrders++; - return TRUE; + return Stream_SetPosition(s, em); } /** @@ -2165,12 +2170,12 @@ static BOOL update_send_create_offscreen_bitmap_order( return FALSE; const size_t em = Stream_GetPosition(s); - Stream_SetPosition(s, bm); + if (!Stream_SetPosition(s, bm)) + return FALSE; Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(uint8_t, controlFlags)); /* controlFlags (1 byte) */ - Stream_SetPosition(s, em); update->numberOrders++; - return TRUE; + return Stream_SetPosition(s, em); } static BOOL update_send_switch_surface_order(rdpContext* context, @@ -2203,12 +2208,12 @@ static BOOL update_send_switch_surface_order(rdpContext* context, return FALSE; const size_t em = Stream_GetPosition(s); - Stream_SetPosition(s, bm); + if (!Stream_SetPosition(s, bm)) + return FALSE; Stream_Write_UINT8(s, WINPR_ASSERTING_INT_CAST(uint8_t, controlFlags)); /* controlFlags (1 byte) */ - Stream_SetPosition(s, em); update->numberOrders++; - return TRUE; + return Stream_SetPosition(s, em); } static BOOL update_send_pointer_system(rdpContext* context, diff --git a/libfreerdp/emu/scard/smartcard_virtual_gids.c b/libfreerdp/emu/scard/smartcard_virtual_gids.c index 7c5c3cbeb..42e77cf81 100644 --- a/libfreerdp/emu/scard/smartcard_virtual_gids.c +++ b/libfreerdp/emu/scard/smartcard_virtual_gids.c @@ -384,6 +384,9 @@ static BOOL vgids_ef_read_do(vgidsEF* ef, UINT16 doID, BYTE** data, DWORD* dataS /* Include Tag and length in result */ doSize += (UINT16)(Stream_GetPosition(ef->data) - curPos); + if (!Stream_SetPosition(ef->data, curPos)) + return FALSE; + outData = malloc(doSize); if (!outData) { @@ -391,7 +394,6 @@ static BOOL vgids_ef_read_do(vgidsEF* ef, UINT16 doID, BYTE** data, DWORD* dataS return FALSE; } - Stream_SetPosition(ef->data, curPos); Stream_Read(ef->data, outData, doSize); *data = outData; *dataSize = doSize; diff --git a/libfreerdp/utils/rdpdr_utils.c b/libfreerdp/utils/rdpdr_utils.c index 2f74b4a08..72927ebd0 100644 --- a/libfreerdp/utils/rdpdr_utils.c +++ b/libfreerdp/utils/rdpdr_utils.c @@ -494,7 +494,8 @@ static void rdpdr_dump_packet(wLog* log, DWORD lvl, wStream* s, const char* cust } // winpr_HexLogDump(log, lvl, Stream_Buffer(s), pos); - Stream_SetPosition(s, gpos); + if (!Stream_SetPosition(s, gpos)) + WLog_Print(log, WLOG_ERROR, "Stream_SetPosition(%" PRIuz ") failed", gpos); } void rdpdr_dump_received_packet(wLog* log, DWORD lvl, wStream* out, const char* custom) diff --git a/libfreerdp/utils/smartcard_call.c b/libfreerdp/utils/smartcard_call.c index 7c1d966b6..fc656eb97 100644 --- a/libfreerdp/utils/smartcard_call.c +++ b/libfreerdp/utils/smartcard_call.c @@ -1860,7 +1860,8 @@ LONG smartcard_irp_device_control_call(scard_call_context* ctx, wStream* out, NT objectBufferLength = outputBufferLength - RDPDR_DEVICE_IO_RESPONSE_LENGTH; WINPR_ASSERT(outputBufferLength <= UINT32_MAX); WINPR_ASSERT(objectBufferLength <= UINT32_MAX); - Stream_SetPosition(out, RDPDR_DEVICE_IO_RESPONSE_LENGTH); + if (!Stream_SetPosition(out, RDPDR_DEVICE_IO_RESPONSE_LENGTH)) + return SCARD_E_BAD_SEEK; /* [MS-RDPESC] 3.2.5.2 Processing Incoming Replies * @@ -1888,7 +1889,8 @@ LONG smartcard_irp_device_control_call(scard_call_context* ctx, wStream* out, NT smartcard_pack_private_type_header( out, (UINT32)objectBufferLength); /* PrivateTypeHeader (8 bytes) */ Stream_Write_INT32(out, result); /* Result (4 bytes) */ - Stream_SetPosition(out, Stream_Length(out)); + if (!Stream_SetPosition(out, Stream_Length(out))) + return SCARD_E_BAD_SEEK; return SCARD_S_SUCCESS; } diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index 569f7640a..4ea7d2a7f 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -584,7 +584,8 @@ static BOOL tf_peer_dump_rfx(freerdp_peer* client) record.data = Stream_Buffer(s); if (!pcap_get_next_record_content(pcap_rfx, &record)) break; - Stream_SetPosition(s, Stream_Capacity(s)); + if (!Stream_SetPosition(s, Stream_Capacity(s))) + goto fail; if (info->test_dump_rfx_realtime && test_sleep_tsdiff(&prev_seconds, &prev_useconds, record.header.ts_sec, @@ -671,7 +672,8 @@ static DWORD WINAPI tf_debug_channel_thread_func(LPVOID arg) } } - Stream_SetPosition(s, BytesReturned); + if (!Stream_SetPosition(s, BytesReturned)) + goto fail; WLog_DBG(TAG, "got %" PRIu32 " bytes", BytesReturned); } fail: diff --git a/server/proxy/channels/pf_channel_rdpdr.c b/server/proxy/channels/pf_channel_rdpdr.c index 6532db1e6..2aeeb92aa 100644 --- a/server/proxy/channels/pf_channel_rdpdr.c +++ b/server/proxy/channels/pf_channel_rdpdr.c @@ -1069,7 +1069,8 @@ static BOOL pf_channel_rdpdr_rewrite_device_list_to(wStream* s, UINT32 fromVersi Stream_SealLength(clone); Stream_ResetPosition(clone); - Stream_SetPosition(s, pos); + if (!Stream_SetPosition(s, pos)) + goto fail; } /* Skip device count */ @@ -1156,10 +1157,7 @@ static BOOL pf_channel_rdpdr_rewrite_device_list(pf_channel_client_context* rdpd Stream_Read_UINT16(s, component); Stream_Read_UINT16(s, packetid); if ((component != RDPDR_CTYP_CORE) || (packetid != PAKID_CORE_DEVICELIST_ANNOUNCE)) - { - Stream_SetPosition(s, pos); - return TRUE; - } + return Stream_SetPosition(s, pos); const pf_channel_server_context* srv = HashTable_GetItemValue(ps->interceptContextMap, RDPDR_SVC_CHANNEL_NAME); @@ -1179,8 +1177,7 @@ static BOOL pf_channel_rdpdr_rewrite_device_list(pf_channel_client_context* rdpd if (!pf_channel_rdpdr_rewrite_device_list_to(s, from, to)) return FALSE; - Stream_SetPosition(s, pos); - return TRUE; + return Stream_SetPosition(s, pos); } WINPR_ATTR_NODISCARD @@ -1201,7 +1198,8 @@ static BOOL pf_channel_rdpdr_client_send_to_server(pf_channel_client_context* rd if (!pf_channel_rdpdr_rewrite_device_list(rdpdr, ps, s, TRUE)) return FALSE; size_t len = Stream_Length(s); - Stream_SetPosition(s, len); + if (!Stream_SetPosition(s, len)) + return ERROR_INVALID_DATA; rdpdr_dump_send_packet(rdpdr->log, WLOG_TRACE, s, proxy_client_tx); WINPR_ASSERT(ps->context.peer); WINPR_ASSERT(ps->context.peer->SendChannelData); @@ -1294,7 +1292,8 @@ static BOOL filter_smartcard_io_requests(pf_channel_client_context* rdpdr, wStre rc = TRUE; fail: - Stream_SetPosition(s, pos); + if (!Stream_SetPosition(s, pos)) + return FALSE; return rc; } #endif @@ -1320,7 +1319,11 @@ BOOL pf_channel_send_client_queue(pClientContext* pc, pf_channel_client_context* continue; size_t len = Stream_Length(s); - Stream_SetPosition(s, len); + if (!Stream_SetPosition(s, len)) + { + Stream_Free(s, TRUE); + continue; + } rdpdr_dump_send_packet(rdpdr->log, WLOG_TRACE, s, proxy_server_tx " (queue) "); WINPR_ASSERT(pc->context.instance->SendChannelData); @@ -1610,8 +1613,8 @@ static BOOL filter_smartcard_device_list_remove(pf_channel_server_context* rdpdr memmove(dst, Stream_ConstPointer(s), (count - x - 1) * sizeof(UINT32)); count--; - Stream_SetPosition(s, pos); - Stream_Write_UINT32(s, count); + if (Stream_SetPosition(s, pos)) + Stream_Write_UINT32(s, count); return FALSE; } } @@ -1668,8 +1671,8 @@ static BOOL filter_smartcard_device_list_announce(pf_channel_server_context* rdp DeviceId); memmove(dst, Stream_ConstPointer(s), Stream_GetRemainingLength(s)); - Stream_SetPosition(s, pos); - Stream_Write_UINT32(s, count - 1); + if (Stream_SetPosition(s, pos)) + Stream_Write_UINT32(s, count - 1); return FALSE; } } @@ -1729,7 +1732,8 @@ static BOOL filter_smartcard_device_list_announce_request(pf_channel_server_cont rc = FALSE; fail: - Stream_SetPosition(s, pos); + if (!Stream_SetPosition(s, pos)) + return FALSE; return rc; } #endif @@ -1744,12 +1748,13 @@ static void* stream_copy(const void* obj) return nullptr; memcpy(Stream_Buffer(dst), Stream_ConstBuffer(src), Stream_Capacity(dst)); if (!Stream_SetLength(dst, Stream_Length(src))) - { - Stream_Free(dst, TRUE); - return nullptr; - } - Stream_SetPosition(dst, Stream_GetPosition(src)); + goto fail; + if (!Stream_SetPosition(dst, Stream_GetPosition(src))) + goto fail; return dst; +fail: + Stream_Free(dst, TRUE); + return nullptr; } static void stream_free(void* obj) diff --git a/server/proxy/channels/pf_channel_smartcard.c b/server/proxy/channels/pf_channel_smartcard.c index 56a290c80..c2af7fd00 100644 --- a/server/proxy/channels/pf_channel_smartcard.c +++ b/server/proxy/channels/pf_channel_smartcard.c @@ -100,8 +100,7 @@ static BOOL pf_channel_client_write_iostatus(wStream* out, const SMARTCARD_OPERA WINPR_ASSERT(cID == op->completionID); Stream_Write_INT32(out, ioStatus); - Stream_SetPosition(out, pos); - return TRUE; + return Stream_SetPosition(out, pos); } struct thread_arg diff --git a/server/proxy/modules/bitmap-filter/bitmap-filter.cpp b/server/proxy/modules/bitmap-filter/bitmap-filter.cpp index 80c634245..cf2838de7 100644 --- a/server/proxy/modules/bitmap-filter/bitmap-filter.cpp +++ b/server/proxy/modules/bitmap-filter/bitmap-filter.cpp @@ -319,7 +319,8 @@ class DynChannelState { WINPR_ASSERT(data); - Stream_SetPosition(data->data, startPosition); + if (!Stream_SetPosition(data->data, startPosition)) + return FALSE; if (!drdynvc_write_header(data->data, channelId)) return FALSE; @@ -384,7 +385,8 @@ class DynChannelState default: break; } - Stream_SetPosition(data->data, pos); + if (!Stream_SetPosition(data->data, pos)) + return FALSE; } } diff --git a/winpr/include/winpr/stream.h b/winpr/include/winpr/stream.h index 839cef953..efb5339dc 100644 --- a/winpr/include/winpr/stream.h +++ b/winpr/include/winpr/stream.h @@ -1333,6 +1333,7 @@ extern "C" _s->pointer = _s->buffer; } + WINPR_ATTR_NODISCARD WINPR_API BOOL Stream_SetPosition(wStream* _s, size_t _p); WINPR_API void Stream_SealLength(wStream* _s); diff --git a/winpr/libwinpr/sspi/NTLM/ntlm.c b/winpr/libwinpr/sspi/NTLM/ntlm.c index 96a74e52c..0bebe7468 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm.c @@ -1353,10 +1353,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle phContext, WINPR_HMAC_CTX* hmac = winpr_HMAC_New(); if (!winpr_HMAC_Init(hmac, WINPR_MD_MD5, context->RecvSigningKey, WINPR_MD5_DIGEST_LENGTH)) - { - winpr_HMAC_Free(hmac); - return SEC_E_INTERNAL_ERROR; - } + goto fail; winpr_Data_Write_UINT32(&seq_no, MessageSeqNo); if (!winpr_HMAC_Update(hmac, (BYTE*)&seq_no, 4)) @@ -1366,7 +1363,8 @@ static SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle phContext, if (!winpr_HMAC_Final(hmac, digest, WINPR_MD5_DIGEST_LENGTH)) goto fail; - winpr_RC4_Update(context->RecvRc4Seal, 8, digest, checksum); + if (!winpr_RC4_Update(context->RecvRc4Seal, 8, digest, checksum)) + goto fail; winpr_Data_Write_UINT32(signature, 1L); CopyMemory(&signature[4], checksum, 8); diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c index 8b66b8c45..527adc0f6 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c @@ -306,12 +306,10 @@ static BOOL ntlm_fetch_ntlm_v2_hash(NTLM_CONTEXT* context, BYTE* hash) WLog_VRB(TAG, "NTLM Hash:"); winpr_HexDump(TAG, WLOG_DEBUG, entry->NtHash, 16); #endif - NTOWFv2FromHashW(entry->NtHash, (LPWSTR)credentials->identity.User, - credentials->identity.UserLength * sizeof(WCHAR), - (LPWSTR)credentials->identity.Domain, - credentials->identity.DomainLength * sizeof(WCHAR), hash); - - rc = TRUE; + rc = NTOWFv2FromHashW(entry->NtHash, (LPWSTR)credentials->identity.User, + credentials->identity.UserLength * sizeof(WCHAR), + (LPWSTR)credentials->identity.Domain, + credentials->identity.DomainLength * sizeof(WCHAR), hash); fail: SamFreeEntry(sam, entry); diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_message.c b/winpr/libwinpr/sspi/NTLM/ntlm_message.c index 5f56ee597..799dcee5a 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_message.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_message.c @@ -367,7 +367,8 @@ static BOOL ntlm_read_message_fields_buffer(wStream* s, NTLM_MESSAGE_FIELDS* fie return FALSE; } - Stream_SetPosition(s, fields->BufferOffset); + if (!Stream_SetPosition(s, fields->BufferOffset)) + return FALSE; Stream_Read(s, fields->Buffer, fields->Len); } @@ -381,7 +382,8 @@ static BOOL ntlm_write_message_fields_buffer(wStream* s, const NTLM_MESSAGE_FIEL if (fields->Len > 0) { - Stream_SetPosition(s, fields->BufferOffset); + if (!Stream_SetPosition(s, fields->BufferOffset)) + return FALSE; if (!NTLM_CheckAndLogRequiredCapacity(TAG, (s), fields->Len, "NTLM_MESSAGE_FIELDS::Len")) return FALSE; @@ -480,13 +482,13 @@ static BOOL ntlm_write_message_integrity_check(wStream* s, size_t offset, const if (!NTLM_CheckAndLogRequiredCapacity(TAG, s, offset, "MessageIntegrityCheck::offset")) return FALSE; - Stream_SetPosition(s, offset); + if (!Stream_SetPosition(s, offset)) + return FALSE; if (!NTLM_CheckAndLogRequiredCapacity(TAG, s, size, "MessageIntegrityCheck::size")) return FALSE; Stream_Write(s, data, size); - Stream_SetPosition(s, pos); - return TRUE; + return Stream_SetPosition(s, pos); } SECURITY_STATUS ntlm_read_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer buffer) @@ -1078,7 +1080,8 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer CopyMemory(context->AuthenticateMessage.pvBuffer, Stream_Buffer(s), length); buffer->cbBuffer = (ULONG)length; - Stream_SetPosition(s, PayloadBufferOffset); + if (!Stream_SetPosition(s, PayloadBufferOffset)) + goto fail; if (flags & MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK) { diff --git a/winpr/libwinpr/utils/test/TestStream.c b/winpr/libwinpr/utils/test/TestStream.c index 6474b7103..c5d2bf341 100644 --- a/winpr/libwinpr/utils/test/TestStream.c +++ b/winpr/libwinpr/utils/test/TestStream.c @@ -168,7 +168,8 @@ static BOOL TestStream_Create(size_t count, BOOL selfAlloc) for (size_t pos = 0; pos < len; pos++) { - Stream_SetPosition(s, pos); + if (!Stream_SetPosition(s, pos)) + goto fail; Stream_SealLength(s); if (!TestStream_Verify(s, cap, pos, pos)) @@ -228,7 +229,8 @@ static BOOL TestStream_Extent(UINT32 maxSize) goto fail; } - Stream_SetPosition(s, i); + if (!Stream_SetPosition(s, i)) + goto fail; Stream_SealLength(s); if (!TestStream_Verify(s, i, i, i))