diff options
author | Alexander <alexanderkent@users.noreply.github.com> | 2023-11-07 14:11:29 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-07 14:11:29 -0800 |
commit | f6263d1e5a95e48e826bb56fe92eedb7f98b522a (patch) | |
tree | eb4e42146c0a5726aefce9a5eef19883cf4c41e0 | |
parent | e7d42a4f69bfed9b2c1817ca5686dd721abfe1db (diff) | |
download | ot-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.cpp | 18 | ||||
-rw-r--r-- | tests/unit/test_pskc.cpp | 16 |
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); +} |