From 0f9cdb395adc2b8f357af75cce2a3bb0da11522b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Fri, 14 Nov 2025 20:38:25 +0100 Subject: [PATCH] [RPCRT4] Better handle buffers reallocation failure case (#8461) Addendum to commit 7f1075986f (PR #8305). Addresses review comment https://github.com/reactos/reactos/pull/8305#discussion_r2505628716 In `expand_pointer_table_if_necessary()`, if any of the `RefIdToPointer` `XlatTable` or `StateTable` buffers failed to be reallocated, the `realloc()` call would return NULL while the underlying buffer still be valid. Directly assigning the reallocation result to the pointers would then leak the buffers. With this fix, the `realloc()` result is stored in a temporary pointer. If the result is NULL, we free the original buffer, since the intended code behaviour is to reset all the tables. If the result is a valid pointer to the reallocated buffer, then we can use it instead. --- dll/win32/rpcrt4/ndr_fullpointer.c | 29 +++++++++++++++++++++++++++++ media/doc/WINESYNC.txt | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/dll/win32/rpcrt4/ndr_fullpointer.c b/dll/win32/rpcrt4/ndr_fullpointer.c index 39e1b18c828..455c424cc3d 100644 --- a/dll/win32/rpcrt4/ndr_fullpointer.c +++ b/dll/win32/rpcrt4/ndr_fullpointer.c @@ -86,12 +86,41 @@ static void expand_pointer_table_if_necessary(PFULL_PTR_XLAT_TABLES pXlatTables, { if (RefId >= pXlatTables->RefIdToPointer.NumberOfEntries) { +#ifdef __REACTOS__ + void* ptrNew; + ptrNew = realloc(pXlatTables->RefIdToPointer.XlatTable, sizeof(void *) * RefId * 2); + if (!ptrNew) + { + ERR("Couldn't reallocate RefIdToPointer.XlatTable from %lu to %lu entries\n", + pXlatTables->RefIdToPointer.NumberOfEntries, RefId * 2); + free(pXlatTables->RefIdToPointer.XlatTable); + } + pXlatTables->RefIdToPointer.XlatTable = ptrNew; + if (ptrNew) + { + ptrNew = realloc(pXlatTables->RefIdToPointer.StateTable, RefId * 2); + if (!ptrNew) + { + ERR("Couldn't reallocate RefIdToPointer.StateTable from %lu to %lu entries\n", + pXlatTables->RefIdToPointer.NumberOfEntries, RefId * 2); + free(pXlatTables->RefIdToPointer.StateTable); + } + pXlatTables->RefIdToPointer.StateTable = ptrNew; + } +#else pXlatTables->RefIdToPointer.XlatTable = realloc(pXlatTables->RefIdToPointer.XlatTable, sizeof(void *) * RefId * 2); pXlatTables->RefIdToPointer.StateTable = realloc(pXlatTables->RefIdToPointer.StateTable, RefId * 2); +#endif if (!pXlatTables->RefIdToPointer.XlatTable || !pXlatTables->RefIdToPointer.StateTable) { +#ifdef __REACTOS__ + free(pXlatTables->RefIdToPointer.XlatTable); + free(pXlatTables->RefIdToPointer.StateTable); + pXlatTables->RefIdToPointer.XlatTable = NULL; + pXlatTables->RefIdToPointer.StateTable = NULL; +#endif pXlatTables->RefIdToPointer.NumberOfEntries = 0; return; } diff --git a/media/doc/WINESYNC.txt b/media/doc/WINESYNC.txt index dbda7d7e6ae..fe9c49ccc4b 100644 --- a/media/doc/WINESYNC.txt +++ b/media/doc/WINESYNC.txt @@ -173,7 +173,7 @@ dll/win32/regapi # Synced to WineStaging-5.7 dll/win32/resutils # Synced to WineStaging-3.3 dll/win32/riched20 # Synced to Wine-10.0 dll/win32/riched32 # Synced to WineStaging-3.3 -dll/win32/rpcrt4 # Synced to WineStaging-4.18 +dll/win32/rpcrt4 # Synced to Wine-10.0 dll/win32/rsabase # Synced to WineStaging-3.3 dll/win32/rsaenh # Synced to WineStaging-2.9 dll/win32/sccbase # Synced to WineStaging-4.18