diff --git a/channels/ainput/server/ainput_main.c b/channels/ainput/server/ainput_main.c index eb1740d9a..78296da5f 100644 --- a/channels/ainput/server/ainput_main.c +++ b/channels/ainput/server/ainput_main.c @@ -478,7 +478,9 @@ static UINT ainput_process_message(ainput_server* ainput) goto out; } - Stream_SetLength(s, ActualBytesReturned); + if (!Stream_SetLength(s, ActualBytesReturned)) + goto out; + { const UINT16 MessageId = Stream_Get_UINT16(s); diff --git a/channels/audin/server/audin.c b/channels/audin/server/audin.c index c6259110c..614d1198d 100644 --- a/channels/audin/server/audin.c +++ b/channels/audin/server/audin.c @@ -400,7 +400,12 @@ static DWORD WINAPI audin_server_thread_func(LPVOID arg) break; } - Stream_SetLength(s, BytesReturned); + if (!Stream_SetLength(s, BytesReturned)) + { + error = ERROR_INTERNAL_ERROR; + break; + } + if (!Stream_CheckAndLogRequiredLengthWLog(audin->log, s, SNDIN_HEADER_SIZE)) { error = ERROR_INTERNAL_ERROR; diff --git a/channels/disp/server/disp_main.c b/channels/disp/server/disp_main.c index d100bbba2..06bd6a11b 100644 --- a/channels/disp/server/disp_main.c +++ b/channels/disp/server/disp_main.c @@ -322,7 +322,9 @@ static UINT disp_server_handle_messages(DispServerContext* context) return ERROR_INTERNAL_ERROR; } - Stream_SetLength(s, BytesReturned); + if (!Stream_SetLength(s, BytesReturned)) + return ERROR_INTERNAL_ERROR; + Stream_ResetPosition(s); while (Stream_GetPosition(s) < Stream_Length(s)) diff --git a/channels/gfxredir/server/gfxredir_main.c b/channels/gfxredir/server/gfxredir_main.c index 93dd38fa9..6dcc9dd55 100644 --- a/channels/gfxredir/server/gfxredir_main.c +++ b/channels/gfxredir/server/gfxredir_main.c @@ -252,7 +252,9 @@ static UINT gfxredir_server_handle_messages(GfxRedirServerContext* context) return ERROR_INTERNAL_ERROR; } - Stream_SetLength(s, BytesReturned); + if (!Stream_SetLength(s, BytesReturned)) + return ERROR_INTERNAL_ERROR; + Stream_ResetPosition(s); while (Stream_GetPosition(s) < Stream_Length(s)) diff --git a/channels/location/server/location_main.c b/channels/location/server/location_main.c index fd9429db5..45bcaf7b3 100644 --- a/channels/location/server/location_main.c +++ b/channels/location/server/location_main.c @@ -348,7 +348,9 @@ static UINT location_process_message(location_server* location) goto out; } - Stream_SetLength(s, BytesReturned); + if (!Stream_SetLength(s, BytesReturned)) + goto out; + if (!Stream_CheckAndLogRequiredLength(TAG, s, LOCATION_HEADER_SIZE)) return ERROR_NO_DATA; diff --git a/channels/rdpdr/server/rdpdr_main.c b/channels/rdpdr/server/rdpdr_main.c index 23b5d8763..630b373c6 100644 --- a/channels/rdpdr/server/rdpdr_main.c +++ b/channels/rdpdr/server/rdpdr_main.c @@ -2250,7 +2250,11 @@ static DWORD WINAPI rdpdr_server_thread(LPVOID arg) if (BytesReturned >= RDPDR_HEADER_LENGTH) { Stream_ResetPosition(s); - Stream_SetLength(s, BytesReturned); + if (!Stream_SetLength(s, BytesReturned)) + { + error = ERROR_INTERNAL_ERROR; + goto out_stream; + } while (Stream_GetRemainingLength(s) >= RDPDR_HEADER_LENGTH) { diff --git a/channels/rdpecam/server/camera_device_enumerator_main.c b/channels/rdpecam/server/camera_device_enumerator_main.c index da005a1bd..29c7c1659 100644 --- a/channels/rdpecam/server/camera_device_enumerator_main.c +++ b/channels/rdpecam/server/camera_device_enumerator_main.c @@ -298,7 +298,9 @@ static UINT enumerator_process_message(enumerator_server* enumerator) goto out; } - Stream_SetLength(s, BytesReturned); + if (!Stream_SetLength(s, BytesReturned)) + return ERROR_INTERNAL_ERROR; + if (!Stream_CheckAndLogRequiredLength(TAG, s, CAM_HEADER_SIZE)) return ERROR_NO_DATA; diff --git a/channels/rdpecam/server/camera_device_main.c b/channels/rdpecam/server/camera_device_main.c index d2112860b..f37ab7bd2 100644 --- a/channels/rdpecam/server/camera_device_main.c +++ b/channels/rdpecam/server/camera_device_main.c @@ -504,7 +504,9 @@ static UINT device_process_message(device_server* device) goto out; } - Stream_SetLength(s, BytesReturned); + if (!Stream_SetLength(s, BytesReturned)) + goto out; + if (!Stream_CheckAndLogRequiredLength(TAG, s, CAM_HEADER_SIZE)) return ERROR_NO_DATA; diff --git a/channels/rdpemsc/server/mouse_cursor_main.c b/channels/rdpemsc/server/mouse_cursor_main.c index 6dcbef654..c15f5046a 100644 --- a/channels/rdpemsc/server/mouse_cursor_main.c +++ b/channels/rdpemsc/server/mouse_cursor_main.c @@ -271,7 +271,9 @@ static UINT mouse_cursor_process_message(mouse_cursor_server* mouse_cursor) goto out; } - Stream_SetLength(s, BytesReturned); + if (!Stream_SetLength(s, BytesReturned)) + goto out; + if (!Stream_CheckAndLogRequiredLength(TAG, s, RDPEMSC_HEADER_SIZE)) return ERROR_NO_DATA; diff --git a/channels/rdpgfx/server/rdpgfx_main.c b/channels/rdpgfx/server/rdpgfx_main.c index 26068cb06..40208425f 100644 --- a/channels/rdpgfx/server/rdpgfx_main.c +++ b/channels/rdpgfx/server/rdpgfx_main.c @@ -1869,7 +1869,9 @@ UINT rdpgfx_server_handle_messages(RdpgfxServerContext* context) return ERROR_INTERNAL_ERROR; } - Stream_SetLength(s, BytesReturned); + if (!Stream_SetLength(s, BytesReturned)) + return ERROR_INTERNAL_ERROR; + Stream_ResetPosition(s); while (Stream_GetPosition(s) < Stream_Length(s)) diff --git a/channels/telemetry/server/telemetry_main.c b/channels/telemetry/server/telemetry_main.c index 59c6f86ed..dee6a827c 100644 --- a/channels/telemetry/server/telemetry_main.c +++ b/channels/telemetry/server/telemetry_main.c @@ -181,7 +181,9 @@ static UINT telemetry_process_message(telemetry_server* telemetry) goto out; } - Stream_SetLength(s, BytesReturned); + if (!Stream_SetLength(s, BytesReturned)) + goto out; + if (!Stream_CheckAndLogRequiredLength(TAG, s, 2)) return ERROR_NO_DATA; diff --git a/libfreerdp/codec/dsp.c b/libfreerdp/codec/dsp.c index bf6c63f61..dfbdd6779 100644 --- a/libfreerdp/codec/dsp.c +++ b/libfreerdp/codec/dsp.c @@ -287,7 +287,9 @@ static BOOL freerdp_dsp_resample(FREERDP_DSP_CONTEXT* WINPR_RESTRICT context, error = soxr_process(context->sox, src, sframes, &idone, Stream_Buffer(context->common.resample), Stream_Capacity(context->common.resample) / rbytes, &odone); - Stream_SetLength(context->common.resample, odone * rbytes); + if (!Stream_SetLength(context->common.resample, odone * rbytes)) + return FALSE; + *data = Stream_Buffer(context->common.resample); *length = Stream_Length(context->common.resample); return (error == 0) != 0; diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index 723625b78..2e4fe80b8 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -268,7 +268,11 @@ BOOL freerdp_connect(freerdp* instance) record.data = Stream_Buffer(s); if (!pcap_get_next_record_content(update->pcap_rfx, &record)) break; - Stream_SetLength(s, record.length); + if (!Stream_SetLength(s, record.length)) + { + status = FALSE; + continue; + } Stream_ResetPosition(s); if (!update_begin_paint(&update->common)) diff --git a/libfreerdp/core/gateway/rdg.c b/libfreerdp/core/gateway/rdg.c index 53d831f7f..67279f544 100644 --- a/libfreerdp/core/gateway/rdg.c +++ b/libfreerdp/core/gateway/rdg.c @@ -430,30 +430,26 @@ static wStream* rdg_receive_packet(rdpRdg* rdg) return nullptr; if (!rdg_read_all(rdg->context, rdg->tlsOut, Stream_Buffer(s), header, &rdg->transferEncoding)) - { - Stream_Free(s, TRUE); - return nullptr; - } + goto fail; Stream_Seek(s, 4); Stream_Read_UINT32(s, packetLength); if ((packetLength > INT_MAX) || !Stream_EnsureCapacity(s, packetLength) || (packetLength < header)) - { - Stream_Free(s, TRUE); - return nullptr; - } + goto fail; if (!rdg_read_all(rdg->context, rdg->tlsOut, Stream_Buffer(s) + header, packetLength - header, &rdg->transferEncoding)) - { - Stream_Free(s, TRUE); - return nullptr; - } + goto fail; - Stream_SetLength(s, packetLength); + if (!Stream_SetLength(s, packetLength)) + goto fail; return s; + +fail: + Stream_Free(s, TRUE); + return nullptr; } static BOOL rdg_send_handshake(rdpRdg* rdg) diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index 543740901..16f0b51b8 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -88,33 +88,15 @@ static const char* rpc_client_state_str(RPC_CLIENT_STATE state) return str; } -static void rpc_pdu_reset(RPC_PDU* pdu) +WINPR_ATTR_NODISCARD +static BOOL rpc_pdu_reset(RPC_PDU* pdu) { + WINPR_ASSERT(pdu); pdu->Type = 0; pdu->Flags = 0; pdu->CallId = 0; Stream_ResetPosition(pdu->s); - Stream_SetLength(pdu->s, 0); -} - -static RPC_PDU* rpc_pdu_new(void) -{ - RPC_PDU* pdu = nullptr; - pdu = (RPC_PDU*)malloc(sizeof(RPC_PDU)); - - if (!pdu) - return nullptr; - - pdu->s = Stream_New(nullptr, 4096); - - if (!pdu->s) - { - free(pdu); - return nullptr; - } - - rpc_pdu_reset(pdu); - return pdu; + return Stream_SetLength(pdu->s, 0); } static void rpc_pdu_free(RPC_PDU* pdu) @@ -126,6 +108,29 @@ static void rpc_pdu_free(RPC_PDU* pdu) free(pdu); } +WINPR_ATTR_MALLOC(rpc_pdu_free, 1) +static RPC_PDU* rpc_pdu_new(void) +{ + RPC_PDU* pdu = (RPC_PDU*)calloc(1, sizeof(RPC_PDU)); + + if (!pdu) + return nullptr; + + pdu->s = Stream_New(nullptr, 4096); + + if (!pdu->s) + goto fail; + + if (!rpc_pdu_reset(pdu)) + goto fail; + + return pdu; + +fail: + rpc_pdu_free(pdu); + return nullptr; +} + static int rpc_client_receive_pipe_write(RpcClient* client, const BYTE* buffer, size_t length) { int status = 0; @@ -477,7 +482,8 @@ static int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment) if (rpc_client_recv_pdu(rpc, pdu) < 0) goto fail; - rpc_pdu_reset(pdu); + if (!rpc_pdu_reset(pdu)) + goto fail; rpc->StubFragCount = 0; rpc->StubCallId = 0; } @@ -517,7 +523,8 @@ static int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment) if (rpc_client_recv_pdu(rpc, pdu) < 0) goto fail; - rpc_pdu_reset(pdu); + if (!rpc_pdu_reset(pdu)) + goto fail; } else { @@ -543,7 +550,8 @@ static int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment) if (rpc_client_recv_pdu(rpc, pdu) < 0) goto fail; - rpc_pdu_reset(pdu); + if (!rpc_pdu_reset(pdu)) + goto fail; goto success; } else if (header.common.ptype == PTYPE_FAULT) diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 2f3549e1c..368b84ab9 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -1551,7 +1551,9 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, UINT16* pLength, UINT16 securityFlags) if (!security_fips_check_signature(Stream_ConstPointer(s), (size_t)padLength, sig, 8, rdp)) goto unlock; - Stream_SetLength(s, Stream_Length(s) - pad); + if (!Stream_SetLength(s, Stream_Length(s) - pad)) + goto unlock; + *pLength = (UINT16)padLength; } else diff --git a/libfreerdp/core/test/TestStreamDump.c b/libfreerdp/core/test/TestStreamDump.c index 8c5a8981b..e7d55db41 100644 --- a/libfreerdp/core/test/TestStreamDump.c +++ b/libfreerdp/core/test/TestStreamDump.c @@ -48,7 +48,8 @@ static BOOL test_entry_read_write(void) if (winpr_RAND(Stream_Buffer(sw), Stream_Capacity(sw)) < 0) goto fail; entrysize += Stream_Capacity(sw); - Stream_SetLength(sw, Stream_Capacity(sw)); + if (!Stream_SetLength(sw, Stream_Capacity(sw))) + goto fail; fp = fopen(name, "wb"); if (!fp) diff --git a/libfreerdp/emu/scard/smartcard_virtual_gids.c b/libfreerdp/emu/scard/smartcard_virtual_gids.c index b9fec815c..7c5c3cbeb 100644 --- a/libfreerdp/emu/scard/smartcard_virtual_gids.c +++ b/libfreerdp/emu/scard/smartcard_virtual_gids.c @@ -279,7 +279,8 @@ static vgidsEF* vgids_ef_new(vgidsContext* ctx, USHORT id) WLog_ERR(TAG, "Failed to create file data stream"); goto create_failed; } - Stream_SetLength(ef->data, 0); + if (!Stream_SetLength(ef->data, 0)) + goto create_failed; if (!ArrayList_Append(ctx->files, ef)) { @@ -1129,7 +1130,9 @@ static BOOL vgids_perform_digital_signature(vgidsContext* context) goto sign_failed; } - Stream_SetLength(context->responseData, sigSize); + if (!Stream_SetLength(context->responseData, sigSize)) + goto sign_failed; + EVP_PKEY_CTX_free(ctx); break; } @@ -1204,9 +1207,8 @@ static BOOL vgids_perform_decrypt(vgidsContext* context) goto decrypt_failed; } - Stream_SetLength(context->responseData, outlen); + rc = Stream_SetLength(context->responseData, outlen); } - rc = TRUE; decrypt_failed: EVP_PKEY_CTX_free(ctx); diff --git a/server/proxy/channels/pf_channel_rdpdr.c b/server/proxy/channels/pf_channel_rdpdr.c index 6e8c95c1a..6532db1e6 100644 --- a/server/proxy/channels/pf_channel_rdpdr.c +++ b/server/proxy/channels/pf_channel_rdpdr.c @@ -1743,7 +1743,11 @@ static void* stream_copy(const void* obj) if (!dst) return nullptr; memcpy(Stream_Buffer(dst), Stream_ConstBuffer(src), Stream_Capacity(dst)); - Stream_SetLength(dst, Stream_Length(src)); + if (!Stream_SetLength(dst, Stream_Length(src))) + { + Stream_Free(dst, TRUE); + return nullptr; + } Stream_SetPosition(dst, Stream_GetPosition(src)); return dst; } diff --git a/winpr/libwinpr/utils/collections/StreamPool.c b/winpr/libwinpr/utils/collections/StreamPool.c index a6b24cd8f..eaa9094ab 100644 --- a/winpr/libwinpr/utils/collections/StreamPool.c +++ b/winpr/libwinpr/utils/collections/StreamPool.c @@ -247,7 +247,8 @@ wStream* StreamPool_Take(wStreamPool* pool, size_t size) else if (s) { Stream_ResetPosition(s); - Stream_SetLength(s, Stream_Capacity(s)); + if (!Stream_SetLength(s, Stream_Capacity(s))) + goto out_fail; StreamPool_ShiftAvailable(pool, foundIndex); }