[spinel] fix wrong arguments for various data types in Logger (#12557)

This commit fixes improper argument usage for SPINEL_DATATYPE_DATA_WLEN_S,
SPINEL_DATATYPE_DATA_S, SPINEL_DATATYPE_EUI64_S, and SPINEL_DATATYPE_UTF8_S
in Logger::LogSpinelFrame.

Key changes:
- Use pointer-to-pointer for data and unsigned int pointer for length
  when using spinel_datatype_unpack with data types.
- Switch to spinel_datatype_unpack_in_place() when unpacking into local
  buffers or structures (e.g., for EUI-64 addresses and MAC keys).
- Remove redundant length arguments for SPINEL_DATATYPE_UTF8_S.
- Refactor SPINEL_PROP_RCP_MAC_KEY to use otMacKey and in-place unpacking.

These fixes prevent potential crashes, stack corruption, and incorrect
data parsing in the Spinel logging utility.
This commit is contained in:
Yakun Xu
2026-02-25 21:44:29 -06:00
committed by GitHub
parent 3758ac4b48
commit ec1eb19656
+27 -23
View File
@@ -446,6 +446,7 @@ void Logger::LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx)
uint16_t flags;
int8_t noiseFloor;
unsigned int receiveError;
unsigned int psduLength;
unpacked = spinel_datatype_unpack(data, len,
SPINEL_DATATYPE_DATA_WLEN_S // Frame
@@ -459,10 +460,12 @@ void Logger::LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx)
) SPINEL_DATATYPE_STRUCT_S( // Vendor-data
SPINEL_DATATYPE_UINT_PACKED_S // Receive error
),
&frame.mPsdu, &frame.mLength, &frame.mInfo.mRxInfo.mRssi, &noiseFloor,
&flags, &frame.mChannel, &frame.mInfo.mRxInfo.mLqi,
nullptr, &psduLength, &frame.mInfo.mRxInfo.mRssi, &noiseFloor, &flags,
&frame.mChannel, &frame.mInfo.mRxInfo.mLqi,
&frame.mInfo.mRxInfo.mTimestamp, &receiveError);
VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
frame.mLength = static_cast<uint16_t>(psduLength);
start += Snprintf(start, static_cast<uint32_t>(end - start), ", len:%u, rssi:%d ...", frame.mLength,
frame.mInfo.mRxInfo.mRssi);
OT_UNUSED_VARIABLE(start); // Avoid static analysis error
@@ -476,10 +479,11 @@ void Logger::LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx)
}
else if (cmd == SPINEL_CMD_PROP_VALUE_SET)
{
bool csmaCaEnabled;
bool isHeaderUpdated;
bool isARetx;
bool skipAes;
unsigned int psduLength;
bool csmaCaEnabled;
bool isHeaderUpdated;
bool isARetx;
bool skipAes;
unpacked = spinel_datatype_unpack(
data, len,
@@ -493,11 +497,13 @@ void Logger::LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx)
SPINEL_DATATYPE_BOOL_S // SkipAes
SPINEL_DATATYPE_UINT32_S // TxDelay
SPINEL_DATATYPE_UINT32_S, // TxDelayBaseTime
&frame.mPsdu, &frame.mLength, &frame.mChannel, &frame.mInfo.mTxInfo.mMaxCsmaBackoffs,
nullptr, &psduLength, &frame.mChannel, &frame.mInfo.mTxInfo.mMaxCsmaBackoffs,
&frame.mInfo.mTxInfo.mMaxFrameRetries, &csmaCaEnabled, &isHeaderUpdated, &isARetx, &skipAes,
&frame.mInfo.mTxInfo.mTxDelay, &frame.mInfo.mTxInfo.mTxDelayBaseTime);
VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
frame.mLength = static_cast<uint16_t>(psduLength);
start += Snprintf(start, static_cast<uint32_t>(end - start),
", len:%u, channel:%u, maxbackoffs:%u, maxretries:%u ...", frame.mLength, frame.mChannel,
frame.mInfo.mTxInfo.mMaxCsmaBackoffs, frame.mInfo.mTxInfo.mMaxFrameRetries);
@@ -547,9 +553,8 @@ void Logger::LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx)
case SPINEL_PROP_NEST_STREAM_MFG:
{
const char *output;
size_t outputLen;
unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UTF8_S, &output, &outputLen);
unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_UTF8_S, &output);
VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
start += Snprintf(start, static_cast<uint32_t>(end - start), ", diag:%s", output);
}
@@ -566,11 +571,11 @@ void Logger::LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx)
otMacKey nextKey;
unsigned int nextKeyLen = sizeof(otMacKey);
unpacked = spinel_datatype_unpack(data, len,
SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_DATA_WLEN_S
SPINEL_DATATYPE_DATA_WLEN_S SPINEL_DATATYPE_DATA_WLEN_S,
&keyIdMode, &keyId, prevKey.m8, &prevKeyLen, currKey.m8, &currKeyLen,
nextKey.m8, &nextKeyLen);
unpacked = spinel_datatype_unpack_in_place(
data, len,
SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_DATA_WLEN_S SPINEL_DATATYPE_DATA_WLEN_S
SPINEL_DATATYPE_DATA_WLEN_S,
&keyIdMode, &keyId, prevKey.m8, &prevKeyLen, currKey.m8, &currKeyLen, nextKey.m8, &nextKeyLen);
VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
start += Snprintf(start, static_cast<uint32_t>(end - start),
", keyIdMode:%u, keyId:%u, prevKey:***, currKey:***, nextKey:***", keyIdMode, keyId);
@@ -681,11 +686,10 @@ void Logger::LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx)
case SPINEL_PROP_MAC_SCAN_MASK:
{
constexpr uint8_t kNumChannels = 16;
uint8_t channels[kNumChannels];
spinel_size_t size;
const uint8_t *channels;
spinel_size_t size;
unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_DATA_S, channels, &size);
unpacked = spinel_datatype_unpack(data, len, SPINEL_DATATYPE_DATA_S, &channels, &size);
VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
start += Snprintf(start, static_cast<uint32_t>(end - start), ", channels:");
@@ -702,7 +706,7 @@ void Logger::LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx)
uint8_t m8[OT_EXT_ADDRESS_SIZE];
uint8_t flags;
unpacked = spinel_datatype_unpack(
unpacked = spinel_datatype_unpack_in_place(
data, len, SPINEL_DATATYPE_UINT16_S SPINEL_DATATYPE_EUI64_S SPINEL_DATATYPE_UINT8_S, &saddr, m8, &flags);
VerifyOrExit(unpacked > 0, error = OT_ERROR_PARSE);
@@ -716,10 +720,10 @@ void Logger::LogSpinelFrame(const uint8_t *aFrame, uint16_t aLength, bool aTx)
{
if (cmd == SPINEL_CMD_PROP_VALUE_INSERT)
{
uint8_t channel;
int16_t actualPower;
uint8_t *rawPowerSetting;
unsigned int rawPowerSettingLength;
uint8_t channel;
int16_t actualPower;
const uint8_t *rawPowerSetting;
unsigned int rawPowerSettingLength;
unpacked = spinel_datatype_unpack(
data, len, SPINEL_DATATYPE_UINT8_S SPINEL_DATATYPE_INT16_S SPINEL_DATATYPE_DATA_WLEN_S, &channel,