diags: Add output buffer size limitation to avoid overflow issue (#442)

- add aOutputMaxLen parameter in each diagnostics feature process function
- use snprintf() to limit the size of output string
This commit is contained in:
Shu Chen
2016-08-22 12:38:29 -07:00
committed by Jonathan Hui
parent 4705b1625b
commit b5f97386ba
5 changed files with 49 additions and 47 deletions
+2 -2
View File
@@ -40,11 +40,11 @@
*/
static bool sDiagMode = false;
void otPlatDiagProcess(int argc, char *argv[], char *aOutput)
void otPlatDiagProcess(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
{
// add more plarform specific diagnostics features here
sprintf(aOutput, "diag feature '%s' is not supported\r\n", argv[0]);
snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
(void)argc;
}
+2 -2
View File
@@ -40,10 +40,10 @@
*/
static bool sDiagMode = false;
void otPlatDiagProcess(int argc, char *argv[], char *aOutput)
void otPlatDiagProcess(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
{
// no more diagnostics features for Posix platform
sprintf(aOutput, "diag feature '%s' is not supported\r\n", argv[0]);
snprintf(aOutput, aOutputMaxLen, "diag feature '%s' is not supported\r\n", argv[0]);
(void)argc;
}
+3 -1
View File
@@ -37,6 +37,7 @@
#define DIAG_H_
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
@@ -59,8 +60,9 @@ extern "C" {
* @param[in] argc The argument counter of diagnostics command line.
* @param[in] argv The argument vector of diagnostics command line.
* @param[out] aOutput The diagnostics execution result.
* @param[in] aOutputMaxLen The output buffer size.
*/
void otPlatDiagProcess(int argc, char *argv[], char *aOutput);
void otPlatDiagProcess(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen);
/**
* Set diagnostics mode.
+32 -32
View File
@@ -78,7 +78,7 @@ char *Diag::ProcessCmd(int argc, char *argv[])
if (argc == 0)
{
sprintf(sDiagOutput, "diagnostics mode is %s\r\n", otPlatDiagModeGet() ? "enabled" : "disabled");
snprintf(sDiagOutput, sizeof(sDiagOutput), "diagnostics mode is %s\r\n", otPlatDiagModeGet() ? "enabled" : "disabled");
}
else
{
@@ -86,7 +86,7 @@ char *Diag::ProcessCmd(int argc, char *argv[])
{
if (strcmp(argv[0], sCommands[i].mName) == 0)
{
sCommands[i].mCommand(argc - 1, &argv[1], sDiagOutput);
sCommands[i].mCommand(argc - 1, argc > 1 ? &argv[1] : NULL, sDiagOutput, sizeof(sDiagOutput));
break;
}
}
@@ -94,7 +94,7 @@ char *Diag::ProcessCmd(int argc, char *argv[])
// more platform specific features will be processed under platform layer
if (i == sizeof(sCommands) / sizeof(sCommands[0]))
{
otPlatDiagProcess(argc, argv, sDiagOutput);
otPlatDiagProcess(argc, argv, sDiagOutput, sizeof(sDiagOutput));
}
}
@@ -106,15 +106,15 @@ bool Diag::isEnabled()
return otPlatDiagModeGet();
}
void Diag::AppendErrorResult(ThreadError aError, char *aOutput)
void Diag::AppendErrorResult(ThreadError aError, char *aOutput, size_t aOutputMaxLen)
{
if (aError != kThreadError_None)
{
sprintf(aOutput, "failed\r\nstatus %#x\r\n", aError);
snprintf(aOutput, aOutputMaxLen, "failed\r\nstatus %#x\r\n", aError);
}
}
void Diag::ProcessStart(int argc, char *argv[], char *aOutput)
void Diag::ProcessStart(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
{
ThreadError error = kThreadError_None;
@@ -135,15 +135,15 @@ void Diag::ProcessStart(int argc, char *argv[], char *aOutput)
memset(&sStats, 0, sizeof(struct DiagStats));
sprintf(aOutput, "start diagnostics mode\r\nstatus 0x%02x\r\n", error);
snprintf(aOutput, aOutputMaxLen, "start diagnostics mode\r\nstatus 0x%02x\r\n", error);
exit:
(void)argc;
(void)argv;
AppendErrorResult(error, aOutput);
AppendErrorResult(error, aOutput, aOutputMaxLen);
}
void Diag::ProcessStop(int argc, char *argv[], char *aOutput)
void Diag::ProcessStop(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
{
ThreadError error = kThreadError_None;
@@ -153,14 +153,14 @@ void Diag::ProcessStop(int argc, char *argv[], char *aOutput)
otPlatDiagModeSet(false);
otPlatRadioSetPromiscuous(false);
sprintf(aOutput, "received packets: %d\r\nsent packets: %d\r\nfirst received packet: rssi=%d, lqi=%d\r\n\nstop diagnostics mode\r\nstatus 0x%02x\r\n",
snprintf(aOutput, aOutputMaxLen, "received packets: %d\r\nsent packets: %d\r\nfirst received packet: rssi=%d, lqi=%d\r\n\nstop diagnostics mode\r\nstatus 0x%02x\r\n",
static_cast<int>(sStats.received_packets), static_cast<int>(sStats.sent_packets), static_cast<int>(sStats.first_rssi),
static_cast<int>(sStats.first_lqi), error);
exit:
(void)argc;
(void)argv;
AppendErrorResult(error, aOutput);
AppendErrorResult(error, aOutput, aOutputMaxLen);
}
ThreadError Diag::ParseLong(char *argv, long &value)
@@ -191,7 +191,7 @@ void Diag::TxPacket()
otPlatRadioTransmit();
}
void Diag::ProcessChannel(int argc, char *argv[], char *aOutput)
void Diag::ProcessChannel(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
{
ThreadError error = kThreadError_None;
@@ -199,7 +199,7 @@ void Diag::ProcessChannel(int argc, char *argv[], char *aOutput)
if (argc == 0)
{
sprintf(aOutput, "channel: %d\r\n", sChannel);
snprintf(aOutput, aOutputMaxLen, "channel: %d\r\n", sChannel);
}
else
{
@@ -211,14 +211,14 @@ void Diag::ProcessChannel(int argc, char *argv[], char *aOutput)
// listen on the set channel immediately
otPlatRadioReceive(sChannel);
sprintf(aOutput, "set channel to %d\r\nstatus 0x%02x\r\n", sChannel, error);
snprintf(aOutput, aOutputMaxLen, "set channel to %d\r\nstatus 0x%02x\r\n", sChannel, error);
}
exit:
AppendErrorResult(error, aOutput);
AppendErrorResult(error, aOutput, aOutputMaxLen);
}
void Diag::ProcessPower(int argc, char *argv[], char *aOutput)
void Diag::ProcessPower(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
{
ThreadError error = kThreadError_None;
@@ -226,7 +226,7 @@ void Diag::ProcessPower(int argc, char *argv[], char *aOutput)
if (argc == 0)
{
sprintf(aOutput, "tx power: %d dBm\r\n", sTxPower);
snprintf(aOutput, aOutputMaxLen, "tx power: %d dBm\r\n", sTxPower);
}
else
{
@@ -234,14 +234,14 @@ void Diag::ProcessPower(int argc, char *argv[], char *aOutput)
SuccessOrExit(error = ParseLong(argv[0], value));
sTxPower = static_cast<int8_t>(value);
sprintf(aOutput, "set tx power to %d dBm\r\nstatus 0x%02x\r\n", sTxPower, error);
snprintf(aOutput, aOutputMaxLen, "set tx power to %d dBm\r\nstatus 0x%02x\r\n", sTxPower, error);
}
exit:
AppendErrorResult(error, aOutput);
AppendErrorResult(error, aOutput, aOutputMaxLen);
}
void Diag::ProcessSend(int argc, char *argv[], char *aOutput)
void Diag::ProcessSend(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
{
ThreadError error = kThreadError_None;
long value;
@@ -256,14 +256,14 @@ void Diag::ProcessSend(int argc, char *argv[], char *aOutput)
VerifyOrExit(value <= kMaxPHYPacketSize, error = kThreadError_InvalidArgs);
sTxLen = static_cast<uint8_t>(value);
sprintf(aOutput, "sending %#x packet(s), length %#x\r\nstatus 0x%02x\r\n", static_cast<int>(sTxPackets), static_cast<int>(sTxLen), error);
snprintf(aOutput, aOutputMaxLen, "sending %#x packet(s), length %#x\r\nstatus 0x%02x\r\n", static_cast<int>(sTxPackets), static_cast<int>(sTxLen), error);
TxPacket();
exit:
AppendErrorResult(error, aOutput);
AppendErrorResult(error, aOutput, aOutputMaxLen);
}
void Diag::ProcessRepeat(int argc, char *argv[], char *aOutput)
void Diag::ProcessRepeat(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
{
ThreadError error = kThreadError_None;
@@ -273,7 +273,7 @@ void Diag::ProcessRepeat(int argc, char *argv[], char *aOutput)
if (strcmp(argv[0], "stop") == 0)
{
otPlatAlarmStop();
sprintf(aOutput, "repeated packet transmission is stopped\r\nstatus 0x%02x\r\n", error);
snprintf(aOutput, aOutputMaxLen, "repeated packet transmission is stopped\r\nstatus 0x%02x\r\n", error);
}
else
{
@@ -290,42 +290,42 @@ void Diag::ProcessRepeat(int argc, char *argv[], char *aOutput)
uint32_t now = otPlatAlarmGetNow();
otPlatAlarmStartAt(now, sTxPeriod);
sprintf(aOutput, "sending packets of length %#x at the delay of %#x ms\r\nstatus 0x%02x\r\n", static_cast<int>(sTxLen), static_cast<int>(sTxPeriod), error);
snprintf(aOutput, aOutputMaxLen, "sending packets of length %#x at the delay of %#x ms\r\nstatus 0x%02x\r\n", static_cast<int>(sTxLen), static_cast<int>(sTxPeriod), error);
}
exit:
AppendErrorResult(error, aOutput);
AppendErrorResult(error, aOutput, aOutputMaxLen);
}
void Diag::ProcessSleep(int argc, char *argv[], char *aOutput)
void Diag::ProcessSleep(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
{
ThreadError error = kThreadError_None;
VerifyOrExit(otPlatDiagModeGet(), error = kThreadError_InvalidState);
otPlatRadioSleep();
sprintf(aOutput, "sleeping now...\r\n");
snprintf(aOutput, aOutputMaxLen, "sleeping now...\r\n");
exit:
(void)argc;
(void)argv;
AppendErrorResult(error, aOutput);
AppendErrorResult(error, aOutput, aOutputMaxLen);
}
void Diag::ProcessStats(int argc, char *argv[], char *aOutput)
void Diag::ProcessStats(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen)
{
ThreadError error = kThreadError_None;
VerifyOrExit(otPlatDiagModeGet(), error = kThreadError_InvalidState);
sprintf(aOutput, "received packets: %d\r\nsent packets: %d\r\nfirst received packet: rssi=%d, lqi=%d\r\n",
snprintf(aOutput, aOutputMaxLen, "received packets: %d\r\nsent packets: %d\r\nfirst received packet: rssi=%d, lqi=%d\r\n",
static_cast<int>(sStats.received_packets), static_cast<int>(sStats.sent_packets),
static_cast<int>(sStats.first_rssi), static_cast<int>(sStats.first_lqi));
exit:
(void)argc;
(void)argv;
AppendErrorResult(error, aOutput);
AppendErrorResult(error, aOutput, aOutputMaxLen);
}
void Diag::DiagTransmitDone(bool aRxPending, ThreadError aError)
+10 -10
View File
@@ -48,7 +48,7 @@ namespace Diagnostics {
struct Command
{
const char *mName; ///< A pointer to the command string.
void (*mCommand)(int argc, char *argv[], char *aOutput); ///< A function pointer to process the command.
void (*mCommand)(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen); ///< A function pointer to process the command.
};
struct DiagStats
@@ -71,15 +71,15 @@ public:
static void AlarmFired();
private:
static void AppendErrorResult(ThreadError error, char *aOutput);
static void ProcessSleep(int argc, char *argv[], char *aOutput);
static void ProcessStart(int argc, char *argv[], char *aOutput);
static void ProcessStop(int argc, char *argv[], char *aOutput);
static void ProcessSend(int argc, char *argv[], char *aOutput);
static void ProcessRepeat(int argc, char *argv[], char *aOutput);
static void ProcessStats(int argc, char *argv[], char *aOutput);
static void ProcessChannel(int argc, char *argv[], char *aOutput);
static void ProcessPower(int argc, char *argv[], char *aOutput);
static void AppendErrorResult(ThreadError error, char *aOutput, size_t aOutputMaxLen);
static void ProcessSleep(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen);
static void ProcessStart(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen);
static void ProcessStop(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen);
static void ProcessSend(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen);
static void ProcessRepeat(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen);
static void ProcessStats(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen);
static void ProcessChannel(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen);
static void ProcessPower(int argc, char *argv[], char *aOutput, size_t aOutputMaxLen);
static void TxPacket();
static ThreadError ParseLong(char *aString, long &aLong);