mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
[dns] check for null character in read label (#13187)
This commit updates `Name::LabelIterator::ReadLabel()` to explicitly check that the read label from the message does not contain any embedded `kNullChar` (`\0`) characters. It uses `StringLength()` to verify that the length of the string matches the expected label length. If a null character is found before the end of the label, `kErrorParse` is returned to prevent potential string truncation issues or misinterpretation of the label name. This broader check replaces a recent fix in `PtrRecord::ReadPtrName()` from #13183 which only verified that the first label was not empty or malformed by checking for a single-character label with a null byte. By enforcing this validation centrally at the `ReadLabel()` level, we now ensure that labels of any length are properly protected against embedded null characters across all DNS record types.
This commit is contained in:
committed by
GitHub
parent
15e1c233bf
commit
b2093f4f9e
@@ -639,6 +639,9 @@ Error Name::LabelIterator::ReadLabel(char *aLabelBuffer, uint8_t &aLabelLength,
|
|||||||
aLabelBuffer[mLabelLength] = kNullChar;
|
aLabelBuffer[mLabelLength] = kNullChar;
|
||||||
aLabelLength = mLabelLength;
|
aLabelLength = mLabelLength;
|
||||||
|
|
||||||
|
// Check that there is no `kNullChar` (`\0`) in the read label.
|
||||||
|
VerifyOrExit(StringLength(aLabelBuffer, mLabelLength) == mLabelLength, error = kErrorParse);
|
||||||
|
|
||||||
if (!aAllowDotCharInLabel)
|
if (!aAllowDotCharInLabel)
|
||||||
{
|
{
|
||||||
VerifyOrExit(StringFind(aLabelBuffer, kLabelSeparatorChar) == nullptr, error = kErrorParse);
|
VerifyOrExit(StringFind(aLabelBuffer, kLabelSeparatorChar) == nullptr, error = kErrorParse);
|
||||||
@@ -1592,10 +1595,6 @@ Error PtrRecord::ReadPtrName(const Message &aMessage,
|
|||||||
aOffset = startOffset + sizeof(PtrRecord);
|
aOffset = startOffset + sizeof(PtrRecord);
|
||||||
SuccessOrExit(error = Name::ReadLabel(aMessage, aOffset, aLabelBuffer, aLabelBufferSize));
|
SuccessOrExit(error = Name::ReadLabel(aMessage, aOffset, aLabelBuffer, aLabelBufferSize));
|
||||||
|
|
||||||
// The first label of a PTR target (the service-instance or host label)
|
|
||||||
// must be non-empty.
|
|
||||||
VerifyOrExit(aLabelBuffer[0] != kNullChar, error = kErrorParse);
|
|
||||||
|
|
||||||
if (aNameBuffer != nullptr)
|
if (aNameBuffer != nullptr)
|
||||||
{
|
{
|
||||||
SuccessOrExit(error = Name::ReadName(aMessage, aOffset, aNameBuffer, aNameBufferSize));
|
SuccessOrExit(error = Name::ReadName(aMessage, aOffset, aNameBuffer, aNameBufferSize));
|
||||||
|
|||||||
@@ -161,6 +161,14 @@ void TestDnsName(void)
|
|||||||
{"_s1._sub._srv._udp.default.service.arpa.", "_s1", "_sub._srv._udp", "default.service.arpa.", true},
|
{"_s1._sub._srv._udp.default.service.arpa.", "_s1", "_sub._srv._udp", "default.service.arpa.", true},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef uint8_t EncodedNameWithNullChar[6];
|
||||||
|
|
||||||
|
static const EncodedNameWithNullChar kEncodedNamesWithNullChar[] = {
|
||||||
|
{4, 0, 'a', 'b', 'c', 0}, // Null char at the start of the label
|
||||||
|
{4, 'a', 0, 'c', 'd', 0}, // Null char in the middle of the label
|
||||||
|
{4, 'a', 'b', 'c', 0, 0} // Null char in the end of the label
|
||||||
|
};
|
||||||
|
|
||||||
printf("================================================================\n");
|
printf("================================================================\n");
|
||||||
printf("TestDnsName()\n");
|
printf("TestDnsName()\n");
|
||||||
|
|
||||||
@@ -626,6 +634,22 @@ void TestDnsName(void)
|
|||||||
"012345678901234567890123456789012345678901234567890123456789012") ==
|
"012345678901234567890123456789012345678901234567890123456789012") ==
|
||||||
kErrorInvalidArgs);
|
kErrorInvalidArgs);
|
||||||
|
|
||||||
|
printf("----------------------------------------------------------------\n");
|
||||||
|
printf("Name::ReadLabel() when there is null-char \'\\0\' in the label\n");
|
||||||
|
|
||||||
|
for (const EncodedNameWithNullChar &encodedName : kEncodedNamesWithNullChar)
|
||||||
|
{
|
||||||
|
SuccessOrQuit(message->SetLength(0));
|
||||||
|
SuccessOrQuit(message->AppendBytes(encodedName, sizeof(encodedName)));
|
||||||
|
|
||||||
|
SuccessOrQuit(message->Read(0, buffer, message->GetLength()));
|
||||||
|
DumpBuffer("EncodedName", buffer, message->GetLength());
|
||||||
|
|
||||||
|
offset = 0;
|
||||||
|
labelLength = sizeof(label);
|
||||||
|
VerifyOrQuit(Dns::Name::ReadLabel(*message, offset, label, labelLength) == kErrorParse);
|
||||||
|
}
|
||||||
|
|
||||||
message->Free();
|
message->Free();
|
||||||
testFreeInstance(instance);
|
testFreeInstance(instance);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user