aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander <alexanderkent@users.noreply.github.com>2023-11-07 14:11:29 -0800
committerGitHub <noreply@github.com>2023-11-07 14:11:29 -0800
commitf6263d1e5a95e48e826bb56fe92eedb7f98b522a (patch)
treeeb4e42146c0a5726aefce9a5eef19883cf4c41e0
parente7d42a4f69bfed9b2c1817ca5686dd721abfe1db (diff)
downloadot-br-posix-f6263d1e5a95e48e826bb56fe92eedb7f98b522a.tar.gz
[ot-client] fix buffer overflow in `OpenThreadClient::Execute` (#2083)
This commit addresses a potential buffer overflow in the OpenThreadClient::Execute method. The original implementation did not properly check the size of the data being written to mBuffer, leading to potential buffer overflows. Changes: * Modified the vsnprintf function call to write to &mBuffer[1] with a size limit of sizeof(mBuffer) - 2, leaving room for newline characters at both ends. * Added a check to ensure that the total size of the data (including the two newline characters) does not exceed sizeof(mBuffer). * Improved error handling for the socket write operation (count != ret) instead of (count < ret) as the function seems to expect the entire command to be sent in one go (and logs an error otherwise). Testing: * Manually tested forming a network with various params * Added unit test for truncated network name in PSKc
-rw-r--r--src/web/web-service/ot_client.cpp18
-rw-r--r--tests/unit/test_pskc.cpp16
2 files changed, 25 insertions, 9 deletions
diff --git a/src/web/web-service/ot_client.cpp b/src/web/web-service/ot_client.cpp
index 3020bc04..0ca01b5d 100644
--- a/src/web/web-service/ot_client.cpp
+++ b/src/web/web-service/ot_client.cpp
@@ -147,31 +147,31 @@ char *OpenThreadClient::Execute(const char *aFormat, ...)
DiscardRead();
va_start(args, aFormat);
- ret = vsnprintf(&mBuffer[1], sizeof(mBuffer) - 1, aFormat, args);
+ ret = vsnprintf(&mBuffer[1], sizeof(mBuffer) - 2, aFormat, args);
va_end(args);
if (ret < 0)
{
otbrLogErr("Failed to generate command: %s", strerror(errno));
+ ExitNow();
}
-
- mBuffer[0] = '\n';
- ret++;
-
- if (ret == sizeof(mBuffer))
+ if (static_cast<size_t>(ret) >= sizeof(mBuffer) - 2)
{
otbrLogErr("Command exceeds maximum limit: %d", kBufferSize);
+ ExitNow();
}
- mBuffer[ret] = '\n';
- ret++;
+ mBuffer[0] = '\n';
+ mBuffer[ret + 1] = '\n';
+ ret += 2;
count = write(mSocket, mBuffer, ret);
- if (count < ret)
+ if (count != ret)
{
mBuffer[ret] = '\0';
otbrLogErr("Failed to send command: %s", mBuffer);
+ ExitNow();
}
for (int i = 0; i < mTimeout; ++i)
diff --git a/tests/unit/test_pskc.cpp b/tests/unit/test_pskc.cpp
index 3b28cb55..12fb6eaa 100644
--- a/tests/unit/test_pskc.cpp
+++ b/tests/unit/test_pskc.cpp
@@ -46,3 +46,19 @@ TEST(Pskc, Test123456_0001020304050607_OpenThread)
pskc = mPSKc.ComputePskc(extpanid, "OpenThread", "123456");
MEMCMP_EQUAL(expected, pskc, sizeof(expected));
}
+
+TEST(Pskc, Test_TruncatedNetworkNamePskc_OpenThread)
+{
+ uint8_t extpanid[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
+ const uint8_t *pskc = nullptr;
+ uint8_t expected[OT_PSKC_LENGTH];
+
+ // First run with shorter network name (max)
+ pskc = mPSKc.ComputePskc(extpanid, "OpenThread123456", "123456");
+ memcpy(expected, pskc, OT_PSKC_LENGTH);
+
+ // Second run with longer network name that gets truncated
+ pskc = mPSKc.ComputePskc(extpanid, "OpenThread123456NetworkNameThatExceedsBuffer", "123456");
+
+ MEMCMP_EQUAL(expected, pskc, OT_PSKC_LENGTH);
+}