Skip to content

Commit 02d000c

Browse files
authored
[dns-client] fix double-free of mSavedResponse on duplicate response (openthread#13060)
Fix a double-free of `mSavedResponse` in `Dns::Client` when processing duplicate DNS responses matching an active query. When an SRV/TXT query needs to resolve a host address (AAAA), the DNS client allocates a chained `newQuery` to handle it. If duplicate responses are processed before the query chain is finalized, they trigger multiple AAAA resolution allocations for the same parent query. Because the new query inherits `mSavedResponse` from the parent query's `QueryInfo`, multiple chained queries end up aliasing/sharing the same cloned `mSavedResponse` message. During finalization, `FreeQuery` walks the chain and frees `mSavedResponse` for each query, leading to a double-free of the shared `Message` and free-list/heap corruption. This commit resolves the issue by: 1. Rejecting duplicate responses early in `ParseResponse` if a response has already been received and saved for the query (`info.mSavedResponse != nullptr`), returning `kErrorDrop`. 2. Initializing the `mSavedResponse` field of the `QueryInfo` struct to `nullptr` before allocating the host resolution query (`newQuery`) to prevent it from inheriting a potentially non-null saved response from its parent.
1 parent 7e646d1 commit 02d000c

1 file changed

Lines changed: 2 additions & 0 deletions

File tree

src/core/net/dns_client.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,6 +1497,7 @@ Error Client::ParseResponse(const Message &aResponseMessage, Query *&aQuery, Err
14971497
VerifyOrExit(aQuery != nullptr, error = kErrorNotFound);
14981498

14991499
info.ReadFrom(*aQuery);
1500+
VerifyOrExit(info.mSavedResponse == nullptr, error = kErrorDrop);
15001501

15011502
queryName.SetFromMessage(*aQuery, kNameOffsetInQuery);
15021503

@@ -1872,6 +1873,7 @@ void Client::ResolveHostAddressIfNeeded(Query &aQuery, const Message &aResponseM
18721873
info.mMessageId = 0;
18731874
info.mTransmissionCount = 0;
18741875
info.mMainQuery = &FindMainQuery(aQuery);
1876+
info.mSavedResponse = nullptr;
18751877

18761878
SuccessOrExit(AllocateQuery(info, nullptr, hostName, newQuery));
18771879
IgnoreError(SendQuery(*newQuery, info, /* aUpdateTimer */ true));

0 commit comments

Comments
 (0)