Skip to content

Commit

Permalink
[Tizen] Fix memory leak when resolving mDNS (#21715)
Browse files Browse the repository at this point in the history
The TextEntry structure keeps const references for key and data - the
structure creator is responsible for resource management. We are going
to reuse memory region returned by dnssd_service_get_all_txt_record for
preparing text entries for ChipDnssdResolve callback.
  • Loading branch information
arkq authored Aug 9, 2022
1 parent 3439ad3 commit 10dcc87
Showing 1 changed file with 27 additions and 37 deletions.
64 changes: 27 additions & 37 deletions src/platform/Tizen/DnssdImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,47 +226,37 @@ gboolean BrowseAsync(GMainLoop * mainLoop, gpointer userData)
return true;
}

void ConvertTxtRecords(unsigned short txtLen, uint8_t * txtRecord, std::vector<TextEntry> & textEntries)
void GetTextEntries(unsigned short txtLen, uint8_t * txtRecord, std::vector<TextEntry> & textEntries)
{
if (txtLen <= 1)
{
ChipLogDetail(DeviceLayer, "DNSsd %s: No TXT records", __func__);
return;
}
VerifyOrReturn(txtLen > 1, ChipLogDetail(DeviceLayer, "DNSsd %s: No TXT records", __func__));
const uint8_t * txtRecordEnd = txtRecord + txtLen;

const uint8_t * ptr = txtRecord;
const uint8_t * max = txtRecord + txtLen;
char key[kDnssdKeyMaxSize + 1];
char value[kDnssdTextMaxSize + 1];

while (ptr < max)
while (txtRecord < txtRecordEnd)
{
const uint8_t * const end = ptr + 1 + ptr[0];
if (end > max)
{
ChipLogError(DeviceLayer, "DNSsd %s: Invalid TXT data", __func__);
return;
}
uint8_t txtRecordSize = txtRecord[0];
txtRecord++;

VerifyOrReturn(txtRecord + txtRecordSize <= txtRecordEnd,
ChipLogError(DeviceLayer, "DNSsd %s: Invalid TXT data", __func__));

char * buf = &key[0];
while (++ptr < end)
for (size_t i = 0; i < txtRecordSize; i++)
{
if (*ptr == '=')
{
*buf = 0;
buf = &value[0];
}
else
if (txtRecord[i] == '=')
{
*buf = *ptr;
++buf;
// NULL-terminate the key string
txtRecord[i] = '\0';

char * key = reinterpret_cast<char *>(txtRecord);
uint8_t * data = txtRecord + i + 1;
size_t dataSize = txtRecordSize - i - 1;
textEntries.push_back({ key, data, dataSize });

break;
}
}
*buf = 0;

auto valueLen = strlen(value);
auto valuePtr = reinterpret_cast<const uint8_t *>(strdup(value));
textEntries.push_back(TextEntry{ strdup(key), valuePtr, valueLen });
// Move to the next text entry
txtRecord += txtRecordSize;
}
}

Expand Down Expand Up @@ -330,13 +320,12 @@ void OnResolve(dnssd_error_e result, dnssd_service_h service, void * data)
ret = dnssd_service_get_port(service, &port);
VerifyOrExit(ret == DNSSD_ERROR_NONE, ChipLogError(DeviceLayer, "dnssd_service_get_port() failed. ret: %d", ret));

dnssdService.mPort = static_cast<uint16_t>(port);

ret = dnssd_service_get_all_txt_record(service, &txtLen, reinterpret_cast<void **>(&txtRecord));
VerifyOrExit(ret == DNSSD_ERROR_NONE, ChipLogError(DeviceLayer, "dnssd_service_get_all_txt_record() failed. ret: %d", ret));

ConvertTxtRecords(txtLen, txtRecord, textEntries);
g_free(txtRecord);

dnssdService.mPort = static_cast<uint16_t>(port);
GetTextEntries(txtLen, txtRecord, textEntries);
dnssdService.mTextEntries = textEntries.empty() ? nullptr : textEntries.data();
dnssdService.mTextEntrySize = textEntries.size();

Expand All @@ -346,6 +335,8 @@ void OnResolve(dnssd_error_e result, dnssd_service_h service, void * data)
rCtx->mCallback(rCtx->mCbContext, &dnssdService, chip::Span<chip::Inet::IPAddress>(&ipAddr, 1), CHIP_NO_ERROR);
}

g_free(txtRecord);

rCtx->mInstance->RemoveContext(rCtx);
return;

Expand Down Expand Up @@ -710,7 +701,6 @@ CHIP_ERROR ChipDnssdPublishService(const DnssdService * service, DnssdPublishCal
return chip::DeviceLayer::ThreadStackMgr().AddSrpService(service->mName, regtype.c_str(), service->mPort, subTypes,
textEntries);
}

#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT

return DnssdTizen::GetInstance().RegisterService(*service, callback, context);
Expand Down

0 comments on commit 10dcc87

Please sign in to comment.