[BUG] Heap-Use-After-Free (UAF) in tv-casting-app when deleting a fabric after casting
Opened this issue · 0 comments
Reproduction steps
-
Build the
tv-casting-app
with AddressSanitizer (ASAN) enabled. -
Open Terminal 1 and start the
tv-casting-app
:$ ./tv-casting-app
-
Open Terminal 2 and start the
tv-app
:$ ./tv-app
-
In the
tv-casting-app
shell, send a cast request:tv-casting-app > cast request 0
-
In the
tv-app
shell, respond with:tv-app > controller ux ok
-
In the
tv-casting-app
, print the list of fabrics and delete a specific fabric:tv-casting-app > cast print-fabrics tv-casting-app > cast delete-fabric <fabricId>
-
Observe the ASAN output in
tv-casting-app
indicating a heap-use-after-free issue.
tv-casting-app UAF.txt
Summary
A heap-use-after-free (UAF) issue occurs in the tv-casting-app
when the delete-fabric
command is executed. After removing a fabric, the system attempts to access a freed ReadClient
object.
Analysis and Description
The issue arises from a lifecycle mismatch between fabric cleanup and the ReadClient
object references. The sequence of events leading to the issue is as follows:
-
Fabric Removal (FabricTable.cpp):
-
The
Delete()
method ofFabricTable
is called, which iterates through its delegates and invokesOnFabricRemoved()
:CHIP_ERROR FabricTable::Delete(FabricIndex fabricIndex) { if (mDelegateListRoot != nullptr) { FabricTable::Delegate * delegate = mDelegateListRoot; while (delegate) { FabricTable::Delegate * nextDelegate = delegate->next; delegate->OnFabricRemoved(*this, fabricIndex); delegate = nextDelegate; } } }
-
-
ReadClient Cleanup (InteractionModelEngine.cpp):
-
The
OnFabricRemoved()
method loops through activeReadClient
objects and callsClose()
:void InteractionModelEngine::OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) { for (auto * readClient = mpActiveReadClientList; readClient != nullptr; readClient = readClient->GetNextClient()) { if (readClient->GetFabricIndex() == fabricIndex) { readClient->Close(CHIP_ERROR_IM_FABRIC_DELETED, false); } } }
-
-
ReadClient Deallocation (ReadClient.cpp):
-
The
Close()
method triggers the callbackmpCallback.OnDone(this)
, marking theReadClient
for destruction:void ReadClient::Close(CHIP_ERROR aError, bool allowResubscription) { ... mpCallback.OnDone(this); }
-
-
Use of Freed Memory:
-
Despite being destroyed, the
ReadClient
remains in thempActiveReadClientList
. Subsequent iterations inOnFabricRemoved()
access the dangling pointer. Specifically, thereadClient->GetNextClient()
call accesses thempNext
pointer of the destroyedReadClient
object, leading to a UAF:ReadClient * GetNextClient() { return mpNext; }
-
This happens because
GetNextClient()
does not verify the validity of thempNext
pointer, which now points to a deallocated memory region.
-
Bug prevalence
always
GitHub hash of the SDK that was being used
Platform
core
Platform Version(s)
all versions
Anything else?
No response