mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-10-21 22:02:37 +00:00
Harden encryption fragment completion against queue slot reuse
Capture the parent before releasing a fragment slot on Windows and Unix. This removes the completion code's dependency on the first-fragment slot holding up the ring until the requester observes completion.
This commit is contained in:
@@ -192,6 +192,7 @@ static void SetWorkItemState (EncryptionThreadPoolWorkItem *workItem, WorkItemSt
|
||||
static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
|
||||
{
|
||||
EncryptionThreadPoolWorkItem *workItem;
|
||||
EncryptionThreadPoolWorkItem *firstFragment;
|
||||
if (threadArg)
|
||||
{
|
||||
#ifdef DEVICE_DRIVER
|
||||
@@ -333,14 +334,16 @@ static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
|
||||
TC_THROW_FATAL_EXCEPTION;
|
||||
}
|
||||
|
||||
if (workItem != workItem->FirstFragment)
|
||||
// Keep the parent reference before releasing this queue slot.
|
||||
firstFragment = workItem->FirstFragment;
|
||||
if (workItem != firstFragment)
|
||||
{
|
||||
SetWorkItemState (workItem, WorkItemFree);
|
||||
TC_SET_EVENT (WorkItemCompletedEvent);
|
||||
}
|
||||
|
||||
if (InterlockedDecrement (&workItem->FirstFragment->OutstandingFragmentCount) == 0)
|
||||
TC_SET_EVENT (workItem->FirstFragment->ItemCompletedEvent);
|
||||
if (InterlockedDecrement (&firstFragment->OutstandingFragmentCount) == 0)
|
||||
TC_SET_EVENT (firstFragment->ItemCompletedEvent);
|
||||
}
|
||||
|
||||
#ifdef DEVICE_DRIVER
|
||||
|
||||
@@ -375,14 +375,16 @@ namespace VeraCrypt
|
||||
continue;
|
||||
}
|
||||
|
||||
if (workItem != workItem->FirstFragment)
|
||||
// Keep the parent reference before releasing this queue slot.
|
||||
WorkItem *firstFragment = workItem->FirstFragment;
|
||||
if (workItem != firstFragment)
|
||||
{
|
||||
workItem->State.Set (WorkItem::State::Free);
|
||||
WorkItemCompletedEvent.Signal();
|
||||
}
|
||||
|
||||
if (workItem->FirstFragment->OutstandingFragmentCount.Decrement() == 0)
|
||||
workItem->FirstFragment->ItemCompletedEvent.Signal();
|
||||
if (firstFragment->OutstandingFragmentCount.Decrement() == 0)
|
||||
firstFragment->ItemCompletedEvent.Signal();
|
||||
}
|
||||
}
|
||||
catch (exception &e)
|
||||
|
||||
Reference in New Issue
Block a user