[KERNEL32] Ensure the PebLock is always released in FlsFree

This commit is contained in:
Mark Jansen 2018-05-11 22:23:52 +02:00
parent b6e3cf3c03
commit 12654d2852
No known key found for this signature in database
GPG key ID: B39240EE84BEAE8B

View file

@ -1,12 +1,12 @@
/* /*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS System Libraries * PROJECT: ReactOS System Libraries
* FILE: dll/win32/kernel32/client/fiber.c * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Fiber Implementation * PURPOSE: Fiber Implementation
* PROGRAMMERS: * COPYRIGHT: Copyright 2005-2011 Alex Ionescu (alex@relsoft.net)
* Alex Ionescu (alex@relsoft.net) * Copyright 2003-2008 KJK::Hyperion (noog@libero.it)
* KJK::Hyperion <noog@libero.it> * Copyright 2018 Mark Jansen (mark.jansen@reactos.org)
*/ */
#include <k32.h> #include <k32.h>
#include <ndk/rtltypes.h> #include <ndk/rtltypes.h>
@ -410,36 +410,44 @@ FlsFree(DWORD dwFlsIndex)
RtlAcquirePebLock(); RtlAcquirePebLock();
ret = RtlAreBitsSet(Peb->FlsBitmap, dwFlsIndex, 1); _SEH2_TRY
if (ret)
{ {
PLIST_ENTRY Entry; ret = RtlAreBitsSet(Peb->FlsBitmap, dwFlsIndex, 1);
PFLS_CALLBACK_FUNCTION lpCallback; if (ret)
RtlClearBits(Peb->FlsBitmap, dwFlsIndex, 1);
lpCallback = Peb->FlsCallback[dwFlsIndex];
Peb->FlsCallback[dwFlsIndex] = NULL;
for (Entry = Peb->FlsListHead.Flink; Entry != &Peb->FlsListHead; Entry = Entry->Flink)
{ {
PRTL_FLS_DATA pFlsData; PLIST_ENTRY Entry;
PFLS_CALLBACK_FUNCTION lpCallback;
pFlsData = CONTAINING_RECORD(Entry, RTL_FLS_DATA, ListEntry); RtlClearBits(Peb->FlsBitmap, dwFlsIndex, 1);
if (pFlsData->Data[dwFlsIndex]) lpCallback = Peb->FlsCallback[dwFlsIndex];
for (Entry = Peb->FlsListHead.Flink; Entry != &Peb->FlsListHead; Entry = Entry->Flink)
{ {
if (lpCallback) PRTL_FLS_DATA pFlsData;
pFlsData = CONTAINING_RECORD(Entry, RTL_FLS_DATA, ListEntry);
if (pFlsData->Data[dwFlsIndex])
{ {
lpCallback(pFlsData->Data[dwFlsIndex]); if (lpCallback)
{
lpCallback(pFlsData->Data[dwFlsIndex]);
}
pFlsData->Data[dwFlsIndex] = NULL;
} }
pFlsData->Data[dwFlsIndex] = NULL;
} }
Peb->FlsCallback[dwFlsIndex] = NULL;
}
else
{
SetLastError(ERROR_INVALID_PARAMETER);
} }
} }
else _SEH2_FINALLY
{ {
SetLastError(ERROR_INVALID_PARAMETER); RtlReleasePebLock();
} }
RtlReleasePebLock(); _SEH2_END;
return ret; return ret;
} }