已开启
[安全整改] R6 问题单3:缓冲区与内存安全问题整改(32 项修复) #312
[安全整改] R6 问题单3:缓冲区与内存安全问题整改(32 项修复) #312
已开启
wuyike创建于 11 天前
共 32 个文件变更+123-38
@@ -23,6 +23,9 @@ namespace Nearlink {
23 23 
24bool HasWriteable(uint32_t operationIndication, size_t idx)24bool HasWriteable(uint32_t operationIndication, size_t idx)
25{25{
26+ if (idx >= 32) { // 32 位掩码移位越界 UB 防护
27+ return false;
28+ }
26 bool isWriteable = (operationIndication & (0x0100U << idx)) != 0;29 bool isWriteable = (operationIndication & (0x0100U << idx)) != 0;
27 return isWriteable;30 return isWriteable;
28}31}
@@ -1438,7 +1438,7 @@ uint8_t ASCService::GetBpsBitIndex(const RawAddress &device, uint64_t resultBps,
1438{1438{
1439 // 测试用码率参数1439 // 测试用码率参数
1440 int param = OHOS::system::GetIntParameter("persist.config.nearlink.audiobps", -1);1440 int param = OHOS::system::GetIntParameter("persist.config.nearlink.audiobps", -1);
1441- if ((param >= 0) && IsL2HC(codecId) && ((resultBps & (1 << param)) != 0)) {1441+ if ((param >= 0) && (param < 31) && IsL2HC(codecId) && ((resultBps & (1 << param)) != 0)) {
1442 HILOGI("[ASCService]GetBpsBitIndex param %{public}d resultBps %{public}d codecId %{public}d",1442 HILOGI("[ASCService]GetBpsBitIndex param %{public}d resultBps %{public}d codecId %{public}d",
1443 param, resultBps, codecId);1443 param, resultBps, codecId);
1444 1444 
@@ -1859,7 +1859,8 @@ uint8_t ASCService::SelectCodecSampleRatePolicy(const RawAddress &device, AscCod
1859 Qos qos = paramIn.qos;1859 Qos qos = paramIn.qos;
1860 // 测试用码率参数1860 // 测试用码率参数
1861 int param = OHOS::system::GetIntParameter("persist.config.nearlink.audiosample", -1);1861 int param = OHOS::system::GetIntParameter("persist.config.nearlink.audiosample", -1);
1862- if ((param >= 0) && IsMediaService(qos)) {1862+ if ((param >= static_cast<int>(ASC_SAMPLE_RATE_16KHZ)) && (param <= static_cast<int>(ASC_SAMPLE_RATE_96KHZ)) &&
1863+ IsMediaService(qos)) {
1863 HILOGI("[ASCService] param %{public}d qos %{public}d", param, qos);1864 HILOGI("[ASCService] param %{public}d qos %{public}d", param, qos);
1864 return param;1865 return param;
1865 }1866 }
@@ -1906,7 +1907,8 @@ uint8_t ASCService::SelectCodecBitDepthPolicy(const RawAddress &device, AscCodec
1906{1907{
1907 // 测试用码率参数1908 // 测试用码率参数
1908 int param = OHOS::system::GetIntParameter("persist.config.nearlink.audiodepth", -1);1909 int param = OHOS::system::GetIntParameter("persist.config.nearlink.audiodepth", -1);
1909- if ((param >= 0) && IsMediaService(paramIn.qos)) {1910+ if ((param >= static_cast<int>(ASC_SAMPLE_DEPTH_16BIT)) && (param <= static_cast<int>(ASC_SAMPLE_DEPTH_32BIT)) &&
1911+ IsMediaService(paramIn.qos)) {
1910 HILOGI("[ASCService] param %{public}d qos %{public}d", param, paramIn.qos);1912 HILOGI("[ASCService] param %{public}d qos %{public}d", param, paramIn.qos);
1911 return param;1913 return param;
1912 }1914 }
@@ -514,7 +514,7 @@ void CcpService::HandleVoipStop(const RawAddress &device)
514 return;514 return;
515 }515 }
516 NL_CHECK_RETURN(pimpl->currentVoipCallId_ != INVALID_CCP_VOIP_ID, "invalid callId.");516 NL_CHECK_RETURN(pimpl->currentVoipCallId_ != INVALID_CCP_VOIP_ID, "invalid callId.");
517- Telephony::CallAttributeInfo info;517+ Telephony::CallAttributeInfo info {};
518 info.callState = TelCallState::CALL_STATUS_DISCONNECTED;518 info.callState = TelCallState::CALL_STATUS_DISCONNECTED;
519 info.callId = pimpl->currentVoipCallId_;519 info.callId = pimpl->currentVoipCallId_;
520 HandleCallDetailChange(info);520 HandleCallDetailChange(info);
@@ -531,7 +531,7 @@ void CcpService::HandleVoipStop(const RawAddress &device)
531void CcpService::CreateVoipCallInfo()531void CcpService::CreateVoipCallInfo()
532{532{
533 // 呼出(这里只是模拟一个通话状态,来去电都可以)533 // 呼出(这里只是模拟一个通话状态,来去电都可以)
534- Telephony::CallAttributeInfo info;534+ Telephony::CallAttributeInfo info {};
535 info.callState = TelCallState::CALL_STATUS_DIALING;535 info.callState = TelCallState::CALL_STATUS_DIALING;
536 info.callDirection = Telephony::CallDirection::CALL_DIRECTION_OUT;536 info.callDirection = Telephony::CallDirection::CALL_DIRECTION_OUT;
537 info.callId = pimpl->currentVoipCallId_;537 info.callId = pimpl->currentVoipCallId_;
@@ -14,6 +14,8 @@
14 */14 */
15#include "HidHostService.h"15#include "HidHostService.h"
16#include "ClassCreator.h"16#include "ClassCreator.h"
17+#include <vector>
18+ 
17#include "log_util.h"19#include "log_util.h"
18#include "SleUtils.h"20#include "SleUtils.h"
19#include "nearlink_dft_exception.h"21#include "nearlink_dft_exception.h"
@@ -287,16 +289,17 @@ int HidHostService::HidHostSendReport(std::string device, uint8_t type, uint16_t
287int HidHostService::HidHostSendReport(std::string device, uint8_t type, uint16_t size, std::string &report)289int HidHostService::HidHostSendReport(std::string device, uint8_t type, uint16_t size, std::string &report)
288{290{
289 LOG_INFO("[HIDH Service]:start ");291 LOG_INFO("[HIDH Service]:start ");
292+ static constexpr size_t HID_HOST_REPORT_MAX_LEN = 512; // HID 报文协议上限,防御 IPC 超长输入
290 size_t len = report.size() / 2;293 size_t len = report.size() / 2;
291- if (len <= 0) {294+ if (len == 0 || len > HID_HOST_REPORT_MAX_LEN) {
292 LOG_ERROR("[HIDH Service]: size is invalid!");295 LOG_ERROR("[HIDH Service]: size is invalid!");
293 return HID_HOST_FAILURE;296 return HID_HOST_FAILURE;
294 }297 }
295- uint8_t hexbuf[len]; 298+ std::vector<uint8_t> hexbuf(len);
296- NL_CHECK_RETURN_RET(SleUtils::ConvertHexStringToInt(report, hexbuf, len), HID_HOST_FAILURE,299+ NL_CHECK_RETURN_RET(SleUtils::ConvertHexStringToInt(report, hexbuf.data(),
297- "[HIDH Service]: string is invalid!");300+ static_cast<int>(len)), HID_HOST_FAILURE, "[HIDH Service]: string is invalid!");
298 301 
299- return HidHostSendReport(device, type, len, hexbuf);302+ return HidHostSendReport(device, type, static_cast<uint16_t>(len), hexbuf.data());
300}303}
301 304 
302int HidHostService::HidHostSetReport(std::string device, uint8_t type, uint16_t size, const uint8_t* report)305int HidHostService::HidHostSetReport(std::string device, uint8_t type, uint16_t size, const uint8_t* report)
@@ -127,6 +127,8 @@ void TwsSharedLibApi::PostRecvMsgEventToService(TwsMessage event, uint8_t *data,
127 127 
128 TwsEncodeMsg *decodeMsg = reinterpret_cast<TwsEncodeMsg *>(data);128 TwsEncodeMsg *decodeMsg = reinterpret_cast<TwsEncodeMsg *>(data);
129 NL_CHECK_RETURN(decodeMsg != nullptr, "[Tws LibApi]:decode message invalid");129 NL_CHECK_RETURN(decodeMsg != nullptr, "[Tws LibApi]:decode message invalid");
130+ NL_CHECK_RETURN(decodeMsg->dataLen <= dataLen - sizeof(TwsEncodeMsg),
131+ "[Tws LibApi]:decode message dataLen invalid:%{public}u!", decodeMsg->dataLen);
130 event.msgType_ = decodeMsg->msgType;132 event.msgType_ = decodeMsg->msgType;
131 event.serviceDataLen_ = decodeMsg->dataLen;133 event.serviceDataLen_ = decodeMsg->dataLen;
132 event.serviceData_ = std::make_unique<uint8_t[]>(event.serviceDataLen_);134 event.serviceData_ = std::make_unique<uint8_t[]>(event.serviceDataLen_);
@@ -368,6 +368,8 @@ static void CcpCcsUpdatePropertyCallBack(int32_t appId, NLSTK_SsapServerOnSetPro
368 return;368 return;
369 }369 }
370 size_t index = 0;370 size_t index = 0;
371+ NLSTK_CHECK_RETURN_VOID(property->value.data != NULL && property->value.len >= CCP_CALL_COUNT_LEN,
372+ "[CCP] value data null or len invalid");
371 uint8_t callCount = property->value.data[index++];373 uint8_t callCount = property->value.data[index++];
372 NLSTK_LOG_DEBUG("[CCP] call count is %u", callCount);374 NLSTK_LOG_DEBUG("[CCP] call count is %u", callCount);
373 if (property->value.len == callCount * CCP_CALL_STATUS_LEN + CCP_CALL_COUNT_LEN) {375 if (property->value.len == callCount * CCP_CALL_STATUS_LEN + CCP_CALL_COUNT_LEN) {
@@ -445,6 +445,10 @@ static void HidOnReadReportInfoInReadPropertyState(HidDevice_S *dev, HidReadProp
445 return;445 return;
446 }446 }
447 HidReport_S *report = SDF_VectorElementAt(dev->report, index);447 HidReport_S *report = SDF_VectorElementAt(dev->report, index);
448+ if (report->reportInfoValue.data != NULL) {
449+ SDF_MemFree(report->reportInfoValue.data);
450+ report->reportInfoValue.data = NULL;
451+ }
448 report->reportInfoValue.len = readMsg->property->value.len;452 report->reportInfoValue.len = readMsg->property->value.len;
449 if (report->reportInfoValue.len > HID_MAX_DATA_LEN) {453 if (report->reportInfoValue.len > HID_MAX_DATA_LEN) {
450 NLSTK_LOG_ERROR("[HID] reportInfoValue len is invalid");454 NLSTK_LOG_ERROR("[HID] reportInfoValue len is invalid");
@@ -764,6 +768,10 @@ static void HidOnReadPropertyInConnectedState(HidDevice_S *dev, HidStmParam_S ms
764 HidTypeAndFormatDesc_S value = {0};768 HidTypeAndFormatDesc_S value = {0};
765 value.type = readMsg->property->value.data[0];769 value.type = readMsg->property->value.data[0];
766 value.descLen = readMsg->property->value.len - 1;770 value.descLen = readMsg->property->value.len - 1;
771+ NLSTK_CHECK_RETURN_VOID(value.descLen > 0 && value.descLen <= HID_MAX_DATA_LEN,
772+ "[HID] type and format desc len is invalid");
773+ value.desc = (uint8_t *)SDF_MemZalloc(value.descLen);
774+ NLSTK_CHECK_RETURN_VOID(value.desc != NULL, "[HID] type and format desc malloc fail");
767 (void)memcpy_s(value.desc, value.descLen, readMsg->property->value.data + 1, value.descLen);775 (void)memcpy_s(value.desc, value.descLen, readMsg->property->value.data + 1, value.descLen);
768 HidReadCbk(&dev->addr, type, &value, NLSTK_ERRCODE_SUCCESS);776 HidReadCbk(&dev->addr, type, &value, NLSTK_ERRCODE_SUCCESS);
769 } else if (type == HID_WORK_STATUS_INDICATION) {777 } else if (type == HID_WORK_STATUS_INDICATION) {
@@ -549,7 +549,7 @@ static void CM_EstablishedCbk(uint8_t type, void *context, uint16_t status, DLI_
549 if (status != DLI_SUCCESS) {549 if (status != DLI_SUCCESS) {
550 CM_CHECK_RETURN(context != NULL, "context is null");550 CM_CHECK_RETURN(context != NULL, "context is null");
551 DLI_ICGCbkParam *contexts = (DLI_ICGCbkParam*)context;551 DLI_ICGCbkParam *contexts = (DLI_ICGCbkParam*)context;
552- for (uint8_t i = 0; i < contexts->connHandleNum; i++) {552+ for (uint8_t i = 0; i < contexts->connHandleNum && i < SLE_ICB_MAX_NUM; i++) {
553 NotifySingleChannelCallback(state, CM_ICB_FAILED, contexts->connHandle[i], 0, channelNode);553 NotifySingleChannelCallback(state, CM_ICB_FAILED, contexts->connHandle[i], 0, channelNode);
554 }554 }
555 return;555 return;
@@ -463,7 +463,8 @@ static void SleAccessRemoteRssiRequestsReplyCbk(void *context, uint16_t status,
463 DLI_ExecuteCmdRetParam *cmdRes)463 DLI_ExecuteCmdRetParam *cmdRes)
464{464{
465 CM_CHECK_RETURN(status == DLI_SUCCESS, "req rssi failed");465 CM_CHECK_RETURN(status == DLI_SUCCESS, "req rssi failed");
466- CM_CHECK_RETURN((cmdRes != NULL && cmdRes->eventParameter != NULL), "param is null");466+ CM_CHECK_RETURN((cmdRes != NULL && cmdRes->eventParameter != NULL &&
467+ cmdRes->size >= sizeof(DLI_ReadRemoteRssiEvt)), "param is null or size invalid");
467 468 
468 DLI_ReadRemoteRssiEvt *evt = (DLI_ReadRemoteRssiEvt *)cmdRes->eventParameter;469 DLI_ReadRemoteRssiEvt *evt = (DLI_ReadRemoteRssiEvt *)cmdRes->eventParameter;
469 CM_LOGI("rssi cbk, lcid:0x%04x, rssi:%d", evt->connHandle, evt->rssi);470 CM_LOGI("rssi cbk, lcid:0x%04x, rssi:%d", evt->connHandle, evt->rssi);
@@ -691,7 +692,8 @@ static void SleAccessReadRemoteVersionCbk(void *context, uint16_t statuss, DLI_E
691{692{
692 uint8_t status = (uint8_t)statuss;693 uint8_t status = (uint8_t)statuss;
693 CM_LOGI("status:0x%02x", status);694 CM_LOGI("status:0x%02x", status);
694- CM_CHECK_RETURN((cmdRes != NULL && cmdRes->eventParameter != NULL), "param is null");695+ CM_CHECK_RETURN((cmdRes != NULL && cmdRes->eventParameter != NULL &&
696+ cmdRes->size >= sizeof(DLI_DataLenChangeEvt)), "param is null or size invalid");
695 uint32_t versionAndLocalIndex = (context != NULL) ? ((DLI_ConnCbkContext *)context)->versionAndLocalIndex : 0;697 uint32_t versionAndLocalIndex = (context != NULL) ? ((DLI_ConnCbkContext *)context)->versionAndLocalIndex : 0;
696 DLI_ReadRemoteVersionEvt completeEvt = { 0 };698 DLI_ReadRemoteVersionEvt completeEvt = { 0 };
697 DLI_ReadRemoteVersionEvt *evt = NULL;699 DLI_ReadRemoteVersionEvt *evt = NULL;
@@ -98,6 +98,7 @@ static uint8_t GetAdvDataOperation(uint16_t totalLen, DevdAdvDataOp_S *op)
98 }98 }
99 uint16_t sendLen = totalLen - op->dataOffset;99 uint16_t sendLen = totalLen - op->dataOffset;
100 sendLen = SDF_MIN(sendLen, CfgdbGetMaxAdvDataLen());100 sendLen = SDF_MIN(sendLen, CfgdbGetMaxAdvDataLen());
101+ sendLen = SDF_MIN(sendLen, UINT8_MAX); // DLI_AdvData.advDataLen 为 uint8,防截断
101 op->sendLen = sendLen;102 op->sendLen = sendLen;
102 if (op->dataOffset == 0) {103 if (op->dataOffset == 0) {
103 if (sendLen == totalLen) {104 if (sendLen == totalLen) {
@@ -253,6 +253,8 @@ void DevdSleScanReportCbk(void *context, uint16_t status, struct DLI_ExecuteCmdR
253 253 
254void DevdSleSetScanFilterCbk(void *context, uint16_t status, struct DLI_ExecuteCmdRetParam *cmdRes)254void DevdSleSetScanFilterCbk(void *context, uint16_t status, struct DLI_ExecuteCmdRetParam *cmdRes)
255{255{
256+ NLSTK_CHECK_RETURN_VOID(cmdRes != NULL && cmdRes->size >= sizeof(DLI_SetScanFilterEvt),
257+ "[DEVD]scan filter cbk param null or size invalid");
256 DLI_SetScanFilterEvt *par = (DLI_SetScanFilterEvt *)cmdRes->eventParameter;258 DLI_SetScanFilterEvt *par = (DLI_SetScanFilterEvt *)cmdRes->eventParameter;
257 NLSTK_CHECK_RETURN_VOID(par != NULL, "[DEVD]scan filter eventParameter null");259 NLSTK_CHECK_RETURN_VOID(par != NULL, "[DEVD]scan filter eventParameter null");
258 NLSTK_LOG_INFO("[DEVD]sle set scan filter cbk ret=%hu, subCode=%hhu, numAvailable=%hhu",260 NLSTK_LOG_INFO("[DEVD]sle set scan filter cbk ret=%hu, subCode=%hhu, numAvailable=%hhu",
@@ -194,10 +194,10 @@ static uint32_t QOSM_Base64Decode(const char *data, uint32_t inputLength, uint8_
194 }194 }
195 195 
196 for (size_t index = 0, outputIndex = 0; index < inputLength;) {196 for (size_t index = 0, outputIndex = 0; index < inputLength;) {
197- uint32_t sextetA = data[index] == '=' ? 0 & index++ : g_decodingTable[(int)data[index++]];197+ uint32_t sextetA = data[index] == '=' ? 0 & index++ : g_decodingTable[(uint8_t)data[index++]];
198- uint32_t sextetB = data[index] == '=' ? 0 & index++ : g_decodingTable[(int)data[index++]];198+ uint32_t sextetB = data[index] == '=' ? 0 & index++ : g_decodingTable[(uint8_t)data[index++]];
199- uint32_t sextetC = data[index] == '=' ? 0 & index++ : g_decodingTable[(int)data[index++]];199+ uint32_t sextetC = data[index] == '=' ? 0 & index++ : g_decodingTable[(uint8_t)data[index++]];
200- uint32_t sextetD = data[index] == '=' ? 0 & index++ : g_decodingTable[(int)data[index++]];200+ uint32_t sextetD = data[index] == '=' ? 0 & index++ : g_decodingTable[(uint8_t)data[index++]];
201 201 
202 uint32_t triple = (sextetA << 3 * 6)202 uint32_t triple = (sextetA << 3 * 6)
203 + (sextetB << 2 * 6)203 + (sextetB << 2 * 6)
@@ -111,6 +111,10 @@ bool SSAP_CheckUuidStd(NLSTK_SsapUuid_S *uuid)
111 111 
112void SSAP_GetUuidFromPktBuf(NLSTK_SsapUuid_S *uuid, uint8_t *srcBuf, uint32_t srcBufLen)112void SSAP_GetUuidFromPktBuf(NLSTK_SsapUuid_S *uuid, uint8_t *srcBuf, uint32_t srcBufLen)
113{113{
114+ if (srcBuf == NULL || srcBufLen > SSAP_UUID128_LEN) {
115+ CP_LOG_ERROR("[SSAP] get uuid from pkt wrong len: %u", srcBufLen);
116+ return;
117+ }
114 if (srcBufLen < SSAP_UUID128_LEN) {118 if (srcBufLen < SSAP_UUID128_LEN) {
115 (void)memcpy_s(uuid->uuid, SSAP_UUID128_LEN, g_ssapStdBaseUuid, SSAP_UUID128_LEN);119 (void)memcpy_s(uuid->uuid, SSAP_UUID128_LEN, g_ssapStdBaseUuid, SSAP_UUID128_LEN);
116 }120 }
@@ -705,6 +705,11 @@ static void SsapcAppReadByUuidCompCb(int32_t appId, void *arg)
705 hook(appId, NULL, 0, NLSTK_ERRCODE_FAIL);705 hook(appId, NULL, 0, NLSTK_ERRCODE_FAIL);
706 return;706 return;
707 }707 }
708+ if (complete->readVals->size > UINT8_MAX) {
709+ CP_LOG_ERROR("[SSAPC_APP] read by uuid rsp item over limit, size: %u", complete->readVals->size);
710+ hook(appId, NULL, 0, NLSTK_ERRCODE_FAIL);
711+ return;
712+ }
708 uint8_t num = (uint8_t)complete->readVals->size;713 uint8_t num = (uint8_t)complete->readVals->size;
709 NLSTK_SsapClientReadPropertyInfo_S *props =714 NLSTK_SsapClientReadPropertyInfo_S *props =
710 (NLSTK_SsapClientReadPropertyInfo_S *)SDF_MemZalloc(sizeof(NLSTK_SsapClientReadPropertyInfo_S) * num);715 (NLSTK_SsapClientReadPropertyInfo_S *)SDF_MemZalloc(sizeof(NLSTK_SsapClientReadPropertyInfo_S) * num);
@@ -1006,7 +1006,8 @@ void SSAPC_ReadRspHandle(SSAP_Link_S *link, SDF_Buff_S *sdfBuff)
1006 if (handleNum == 1) {1006 if (handleNum == 1) {
1007 SingleReadRspDecode(link, readReq, readRsp, len);1007 SingleReadRspDecode(link, readReq, readRsp, len);
1008 } else {1008 } else {
1009- MultiReadRspDecode(link, (Ssap_PduReadReqItem_S *)(readReq->items), handleNum, readRsp->items, len);1009+ MultiReadRspDecode(link, (Ssap_PduReadReqItem_S *)(readReq->items), handleNum, readRsp->items,
1010+ len - SSAP_READ_RSP_DATA_OFFSET);
1010 }1011 }
1011}1012}
1012 1013 
@@ -187,6 +187,8 @@ void SmPkgDispatcher(uint16_t opcode, SLE_Addr_S *addr, const uint8_t *pkg, size
187 NLSTK_LOG_ERROR("[SM] Find remote device key missing.");187 NLSTK_LOG_ERROR("[SM] Find remote device key missing.");
188 STM_MFUNC(slink->stm, Transition, g_smStateName[SM_STATE_MISS]);188 STM_MFUNC(slink->stm, Transition, g_smStateName[SM_STATE_MISS]);
189 STM_MFUNC(slink->stm, ProcessMessage, (Message) { .what = SM_MISS_HANDLE });189 STM_MFUNC(slink->stm, ProcessMessage, (Message) { .what = SM_MISS_HANDLE });
190+ slink = SmFindSLink(addr); // 状态机处理 MISS 可能同步释放 slink,需重新查询
191+ NLSTK_CHECK_RETURN_VOID(slink != NULL, "[SM] slink released on miss handling.");
190 NLSTK_CHECK_RETURN_VOID(slink->dispatcher != NULL, "[SM] slink dispatcher is null.");192 NLSTK_CHECK_RETURN_VOID(slink->dispatcher != NULL, "[SM] slink dispatcher is null.");
191 slink->dispatcher(opcode, slink, pkg, size);193 slink->dispatcher(opcode, slink, pkg, size);
192 } else {194 } else {
@@ -64,7 +64,8 @@ void SmSendGNodeDhKey(SmSLink_S *slink)
64 SmAuthDhkeyMsg_S msg = {0};64 SmAuthDhkeyMsg_S msg = {0};
65 (void)memcpy_s(msg.authData, SM_DHKEY_AUTHCODE_LEN, dhkeyCode.authCode, SM_DHKEY_AUTHCODE_LEN);65 (void)memcpy_s(msg.authData, SM_DHKEY_AUTHCODE_LEN, dhkeyCode.authCode, SM_DHKEY_AUTHCODE_LEN);
66 SmDftCacheTimestamp(&slink->rmtAddr, NLSTK_DFT_EVENT_SM_G_AUTH_EXCEP, SM_DFT_G_AUTH_SEND_CFMKEY_TIME);66 SmDftCacheTimestamp(&slink->rmtAddr, NLSTK_DFT_EVENT_SM_G_AUTH_EXCEP, SM_DFT_G_AUTH_SEND_CFMKEY_TIME);
67- SmSendMessage(slink, SM_AUTH_G_NODE_DHKEY, (const uint8_t *)&msg, sizeof(SmAuthDhkeyMsg_S));67+ bool ret = SmSendMessage(slink, SM_AUTH_G_NODE_DHKEY, (const uint8_t *)&msg, sizeof(SmAuthDhkeyMsg_S));
68+ NLSTK_CHECK_RETURN_VOID(ret == true, "[SM] Send Message failed.");
68}69}
69 70 
70void SmRecvGNodeDhKey(SmSLink_S *slink, const uint8_t *pkg, size_t size)71void SmRecvGNodeDhKey(SmSLink_S *slink, const uint8_t *pkg, size_t size)
@@ -253,7 +253,11 @@ static void RecvPairingCfm(SmSLink_S *slink, const uint8_t *pkg, size_t size)
253 slink->negoParams.codeAlgoCap[i] = msg->codeAlgoCap[i];253 slink->negoParams.codeAlgoCap[i] = msg->codeAlgoCap[i];
254 }254 }
255 (void)memcpy_s(slink->gNode.pubKey, SM_PUBLIC_KEY_LEN, msg->gNodePubKey, SM_PUBLIC_KEY_LEN);255 (void)memcpy_s(slink->gNode.pubKey, SM_PUBLIC_KEY_LEN, msg->gNodePubKey, SM_PUBLIC_KEY_LEN);
256+ SLE_Addr_S rmtAddr = slink->rmtAddr;
256 SendPairingInitInfo(slink);257 SendPairingInitInfo(slink);
258+ // 发送失败会同步释放 slink(状态机 REMV),继续使用前需重新查询(对齐 SmPkgDispatcher 的重查模式)
259+ slink = SmFindSLink(&rmtAddr);
260+ NLSTK_CHECK_RETURN_VOID(slink != NULL, "[SM] slink released on send pairing init info failed.");
257 SmDftCacheTimestamp(&slink->rmtAddr, NLSTK_DFT_EVENT_SM_T_NEGO_EXCEP, SM_DFT_T_NEGO_SEND_PAIR_INIT_TIME);261 SmDftCacheTimestamp(&slink->rmtAddr, NLSTK_DFT_EVENT_SM_T_NEGO_EXCEP, SM_DFT_T_NEGO_SEND_PAIR_INIT_TIME);
258 STM_MFUNC(slink->stm, ProcessMessage, (Message) { .what = SM_NEGO_SUCCESS });262 STM_MFUNC(slink->stm, ProcessMessage, (Message) { .what = SM_NEGO_SUCCESS });
259}263}
@@ -277,8 +281,9 @@ static void SendPairingInitInfo(SmSLink_S *slink)
277 (void)memcpy_s(slink->tNode.pubKey, SM_PUBLIC_KEY_LEN, keyPair.localPubKey, SM_PUBLIC_KEY_LEN);281 (void)memcpy_s(slink->tNode.pubKey, SM_PUBLIC_KEY_LEN, keyPair.localPubKey, SM_PUBLIC_KEY_LEN);
278 /* 发送公钥 */282 /* 发送公钥 */
279 (void)memcpy_s(msg.tNodePubKey, SM_PUBLIC_KEY_LEN, slink->tNode.pubKey, SM_PUBLIC_KEY_LEN);283 (void)memcpy_s(msg.tNodePubKey, SM_PUBLIC_KEY_LEN, slink->tNode.pubKey, SM_PUBLIC_KEY_LEN);
280- SmSendMessage(slink, SM_NEGO_PAIRING_INIT_INFO, (const uint8_t *)&msg, sizeof(SmPairInitInfoMsg_S));284+ bool ret = SmSendMessage(slink, SM_NEGO_PAIRING_INIT_INFO, (const uint8_t *)&msg, sizeof(SmPairInitInfoMsg_S));
281 (void)memset_s(&keyPair, sizeof(keyPair), 0, sizeof(keyPair));285 (void)memset_s(&keyPair, sizeof(keyPair), 0, sizeof(keyPair));
286+ NLSTK_CHECK_RETURN_VOID(ret == true, "[SM] Send Message failed.");
282}287}
283 288 
284static void RecvPairingInitInfo(SmSLink_S *slink, const uint8_t *pkg, size_t size)289static void RecvPairingInitInfo(SmSLink_S *slink, const uint8_t *pkg, size_t size)
@@ -158,7 +158,10 @@ static void PassCodeStartPatternInputT(SmSLink_S *slink)
158 return;158 return;
159 }159 }
160 (void)memcpy_s(slink->gNode.confirm, SM_CONFIRM_NUMBER_LEN, confirm.confirm, SM_CONFIRM_NUMBER_LEN);160 (void)memcpy_s(slink->gNode.confirm, SM_CONFIRM_NUMBER_LEN, confirm.confirm, SM_CONFIRM_NUMBER_LEN);
161+ SLE_Addr_S rmtAddr = slink->rmtAddr;
161 PassCodeSendGNodeCfmWithRa(slink);162 PassCodeSendGNodeCfmWithRa(slink);
163+ slink = SmFindSLink(&rmtAddr); // 发送失败会同步释放 slink,需重新查询
164+ NLSTK_CHECK_RETURN_VOID(slink != NULL, "[SM][PASSCODE] slink released on send cfm failed.");
162 SmSLinkWaitExpectOpCode(slink, SM_AUTH_T_NODE_CFM_WITH_RB, SM_RECV_USER_CONFIRM_TIMEOUT_TIME);165 SmSLinkWaitExpectOpCode(slink, SM_AUTH_T_NODE_CFM_WITH_RB, SM_RECV_USER_CONFIRM_TIMEOUT_TIME);
163 } else {166 } else {
164 /* 通知T端用户可以输入,T端上层不会使用code值,因此无需赋值 */167 /* 通知T端用户可以输入,T端上层不会使用code值,因此无需赋值 */
@@ -194,7 +197,10 @@ void SmPassCodeSetGPassCode(SmSLink_S *slink)
194 return;197 return;
195 }198 }
196 (void)memcpy_s(slink->gNode.confirm, SM_CONFIRM_NUMBER_LEN, confirm.confirm, SM_CONFIRM_NUMBER_LEN);199 (void)memcpy_s(slink->gNode.confirm, SM_CONFIRM_NUMBER_LEN, confirm.confirm, SM_CONFIRM_NUMBER_LEN);
200+ SLE_Addr_S rmtAddr = slink->rmtAddr;
197 PassCodeSendGNodeCfmWithRa(slink);201 PassCodeSendGNodeCfmWithRa(slink);
202+ slink = SmFindSLink(&rmtAddr); // 发送失败会同步释放 slink,需重新查询
203+ NLSTK_CHECK_RETURN_VOID(slink != NULL, "[SM][PASSCODE] slink released on send cfm failed.");
198 SmSLinkWaitExpectOpCode(slink, SM_AUTH_T_NODE_CFM_WITH_RB, SM_RECV_TIMEOUT_TIME);204 SmSLinkWaitExpectOpCode(slink, SM_AUTH_T_NODE_CFM_WITH_RB, SM_RECV_TIMEOUT_TIME);
199}205}
200 206 
@@ -240,7 +246,8 @@ static void PassCodeSendGNodeCfmWithRa(SmSLink_S *slink)
240 SmAuthGCfmWithRaMsg_S msg = {0};246 SmAuthGCfmWithRaMsg_S msg = {0};
241 (void)memcpy_s(msg.gNodeCfm, SM_CONFIRM_NUMBER_LEN, slink->gNode.confirm, SM_CONFIRM_NUMBER_LEN);247 (void)memcpy_s(msg.gNodeCfm, SM_CONFIRM_NUMBER_LEN, slink->gNode.confirm, SM_CONFIRM_NUMBER_LEN);
242 (void)memcpy_s(msg.randomA, SM_RANDOM_NUMBER_R_LEN, slink->gNode.randomR, SM_RANDOM_NUMBER_R_LEN);248 (void)memcpy_s(msg.randomA, SM_RANDOM_NUMBER_R_LEN, slink->gNode.randomR, SM_RANDOM_NUMBER_R_LEN);
243- SmSendMessage(slink, SM_AUTH_G_NODE_CFM_WITH_RA, (const uint8_t *)&msg, sizeof(SmAuthGCfmWithRaMsg_S));249+ bool ret = SmSendMessage(slink, SM_AUTH_G_NODE_CFM_WITH_RA, (const uint8_t *)&msg, sizeof(SmAuthGCfmWithRaMsg_S));
250+ NLSTK_CHECK_RETURN_VOID(ret == true, "[SM][PASSCODE] Send Message failed.");
244}251}
245 252 
246static void PassCodeRecvGNodeCfmWithRa(SmSLink_S *slink, const uint8_t *pkg, size_t size)253static void PassCodeRecvGNodeCfmWithRa(SmSLink_S *slink, const uint8_t *pkg, size_t size)
@@ -350,7 +357,10 @@ static void PassCodeRecvTNodeCfmWithRb(SmSLink_S *slink, const uint8_t *pkg, siz
350 (void)memset_s(&keyPair, sizeof(keyPair), 0, sizeof(keyPair));357 (void)memset_s(&keyPair, sizeof(keyPair), 0, sizeof(keyPair));
351 return;358 return;
352 }359 }
360+ SLE_Addr_S rmtAddr = slink->rmtAddr;
353 SmSendGNodeDhKey(slink);361 SmSendGNodeDhKey(slink);
362+ slink = SmFindSLink(&rmtAddr); // 发送失败会同步释放 slink,需重新查询
363+ NLSTK_CHECK_RETURN_VOID(slink != NULL, "[SM][PASSCODE] slink released on send dhkey failed.");
354 SmSLinkWaitExpectOpCode(slink, SM_AUTH_T_NODE_DHKEY, SM_RECV_TIMEOUT_TIME);364 SmSLinkWaitExpectOpCode(slink, SM_AUTH_T_NODE_DHKEY, SM_RECV_TIMEOUT_TIME);
355 (void)memset_s(&keyPair, sizeof(keyPair), 0, sizeof(keyPair));365 (void)memset_s(&keyPair, sizeof(keyPair), 0, sizeof(keyPair));
356}366}
@@ -394,7 +404,7 @@ static void GenMixPassCode(SmSLink_S *slink, uint32_t passCodeNum, uint8_t *mixC
394 };404 };
395 /* G节点公钥低128比特 */405 /* G节点公钥低128比特 */
396 (void)memcpy_s(input.key, SM_OCTETS_16, slink->gNode.pubKey, SM_OCTETS_16);406 (void)memcpy_s(input.key, SM_OCTETS_16, slink->gNode.pubKey, SM_OCTETS_16);
397- uint8_t buffM[SM_MIX_PASSCODE_LEN];407+ uint8_t buffM[SM_MIX_PASSCODE_LEN] = {0};
398 for (uint8_t idx = 0; idx < sizeof(passCodeNum); idx++) {408 for (uint8_t idx = 0; idx < sizeof(passCodeNum); idx++) {
399 uint8_t byte = (passCodeNum >> (idx * SM_OCTETS_8)) & SM_BYTE_MAX_VAL;409 uint8_t byte = (passCodeNum >> (idx * SM_OCTETS_8)) & SM_BYTE_MAX_VAL;
400 buffM[idx] = byte;410 buffM[idx] = byte;
@@ -249,7 +249,10 @@ static void PassWordRecvTNodeCfmWithRb(SmSLink_S *slink, const uint8_t *pkg, siz
249 (void)memset_s(&keyPair, sizeof(keyPair), 0, sizeof(keyPair));249 (void)memset_s(&keyPair, sizeof(keyPair), 0, sizeof(keyPair));
250 return;250 return;
251 }251 }
252+ SLE_Addr_S rmtAddr = slink->rmtAddr;
252 SmSendGNodeDhKey(slink);253 SmSendGNodeDhKey(slink);
254+ slink = SmFindSLink(&rmtAddr); // 发送失败会同步释放 slink,需重新查询
255+ NLSTK_CHECK_RETURN_VOID(slink != NULL, "[SM][PASSWORD] slink released on send dhkey failed.");
253 SmSLinkWaitExpectOpCode(slink, SM_AUTH_T_NODE_DHKEY, SM_RECV_TIMEOUT_TIME);256 SmSLinkWaitExpectOpCode(slink, SM_AUTH_T_NODE_DHKEY, SM_RECV_TIMEOUT_TIME);
254 // 清理 keyPair 中的敏感数据257 // 清理 keyPair 中的敏感数据
255 (void)memset_s(&keyPair, sizeof(keyPair), 0, sizeof(keyPair));258 (void)memset_s(&keyPair, sizeof(keyPair), 0, sizeof(keyPair));
@@ -233,7 +233,8 @@ static void ReadLocalCsCapsCbk(void *context, uint16_t status, DLI_ExecuteCmdRet
233 SDF_SemPost(g_readCmdSem);233 SDF_SemPost(g_readCmdSem);
234 return;234 return;
235 }235 }
236- NLSTK_CHECK_RETURN_VOID(cmdRes != NULL && cmdRes->eventParameter != NULL, "Read local cs caps callback error.");236+ NLSTK_CHECK_RETURN_VOID(cmdRes != NULL && cmdRes->eventParameter != NULL && cmdRes->size >= SLE_MEASURE_LEN,
237+ "Read local cs caps callback error.");
237 DLI_ReadLocalCsCapsEvt *param = (DLI_ReadLocalCsCapsEvt *)cmdRes->eventParameter;238 DLI_ReadLocalCsCapsEvt *param = (DLI_ReadLocalCsCapsEvt *)cmdRes->eventParameter;
238 g_localCsCaps.status = (uint8_t)status;239 g_localCsCaps.status = (uint8_t)status;
239 (void)memcpy_s(&g_localCsCaps.caps, SLE_MEASURE_LEN, &param->caps, SLE_MEASURE_LEN);240 (void)memcpy_s(&g_localCsCaps.caps, SLE_MEASURE_LEN, &param->caps, SLE_MEASURE_LEN);
@@ -1267,13 +1267,17 @@ uint32_t DLI_AcceptICBReq(DLI_AcceptICBReqParam *param)
1267 uint16_t connHandle;1267 uint16_t connHandle;
1268 DLI_ENCODE2BYTE_LITTLE(&connHandle, param->connHandle);1268 DLI_ENCODE2BYTE_LITTLE(&connHandle, param->connHandle);
1269 // Tips: 被动连接没有处理V1兼容问题1269 // Tips: 被动连接没有处理V1兼容问题
1270+ // 回调上下文必须是完整 DLI_ICGCbkParam:失败事件会按 connHandleNum/connHandle[] 读取
1271+ DLI_ICGCbkParam cbkParam = {0};
1272+ cbkParam.connHandle[0] = param->connHandle; // 主机序:失败通知按该值精确匹配连接
1273+ cbkParam.connHandleNum = 1;
1270 uint32_t ret = DLI_ExecuteCommand(param->opCode,1274 uint32_t ret = DLI_ExecuteCommand(param->opCode,
1271 param->opCode == DLI_ACCEPT_IMB_REQ ? DLI_IMB_ESTABLISHED_EVT : DLI_IOB_ESTABLISHED_EVT,1275 param->opCode == DLI_ACCEPT_IMB_REQ ? DLI_IMB_ESTABLISHED_EVT : DLI_IOB_ESTABLISHED_EVT,
1272 &connHandle,1276 &connHandle,
1273 sizeof(connHandle),1277 sizeof(connHandle),
1274 NULL,1278 NULL,
1275- &param->type,1279+ &cbkParam,
1276- sizeof(param->type));1280+ sizeof(cbkParam));
1277 DLI_LOGD("accept param req ret = %u", ret);1281 DLI_LOGD("accept param req ret = %u", ret);
1278 return ret;1282 return ret;
1279}1283}
@@ -451,7 +451,8 @@ static void DTAP_TransSendCacheBuff(DTAP_Channel_S *channel, DTAP_ReliableChanne
451 }451 }
452 // 缓存之前已对长度进行校验,无需在做额外判断452 // 缓存之前已对长度进行校验,无需在做额外判断
453 uint8_t headerLen = reliable->isRecvFrame ? DTAP_DUPLEX_FRAG_FRAME_HEADER_LEN : DTAP_SIMPLEX_FRAG_FRAME_HEADER_LEN;453 uint8_t headerLen = reliable->isRecvFrame ? DTAP_DUPLEX_FRAG_FRAME_HEADER_LEN : DTAP_SIMPLEX_FRAG_FRAME_HEADER_LEN;
454- uint16_t mps = channel->mps - headerLen - DTAP_CRC_LEN;454+ uint16_t mps = (channel->mps > headerLen + DTAP_CRC_LEN) ?
455+ (channel->mps - headerLen - DTAP_CRC_LEN) : 1;
455 uint16_t frameCnt = DTAP_GetFragmentFramesNum(SDF_DataLenGet(reliable->cacheBuff), mps);456 uint16_t frameCnt = DTAP_GetFragmentFramesNum(SDF_DataLenGet(reliable->cacheBuff), mps);
456 // 如果当前这个包会塞满发送队列或超过发送队列,则等待下次触发发送457 // 如果当前这个包会塞满发送队列或超过发送队列,则等待下次触发发送
457 if (SDF_DListCount(&(reliable->txWindow.txList)) + frameCnt >= reliable->txWindow.size) {458 if (SDF_DListCount(&(reliable->txWindow.txList)) + frameCnt >= reliable->txWindow.size) {
@@ -394,6 +394,10 @@ static DTAP_Channel_S *DTAP_GetOrCreateFragmentChannel(uint16_t lcid, bool *hasC
394 394 
395static void DTAP_SetApBufferNum(uint8_t bufferNum)395static void DTAP_SetApBufferNum(uint8_t bufferNum)
396{396{
397+ if (bufferNum == 0) {
398+ DTAP_LOGE("ap buffer num is invalid:%hhu", bufferNum);
399+ return;
400+ }
397 DTAP_LOGI("ap buffer num is set:%hhu", bufferNum);401 DTAP_LOGI("ap buffer num is set:%hhu", bufferNum);
398 g_apBufferNum = bufferNum;402 g_apBufferNum = bufferNum;
399 DTAP_RecalcLcidQuota();403 DTAP_RecalcLcidQuota();
@@ -401,13 +405,14 @@ static void DTAP_SetApBufferNum(uint8_t bufferNum)
401 405 
402static uint8_t DTAP_DLIAcbNumGet(void)406static uint8_t DTAP_DLIAcbNumGet(void)
403{407{
404- return (uint8_t)DLI_DataNumGet(ACB_DATA_TYPE);408+ uint16_t acbNum = DLI_DataNumGet(ACB_DATA_TYPE);
409+ return (uint8_t)((acbNum < UINT8_MAX) ? acbNum : UINT8_MAX);
405}410}
406 411 
407static void DTAP_DLIDataNumChangecbk(DLI_DataType type, uint16_t dataNum)412static void DTAP_DLIDataNumChangecbk(DLI_DataType type, uint16_t dataNum)
408{413{
409 if (type == ACB_DATA_TYPE) {414 if (type == ACB_DATA_TYPE) {
410- DTAP_SetApBufferNum(dataNum);415+ DTAP_SetApBufferNum((uint8_t)((dataNum < UINT8_MAX) ? dataNum : UINT8_MAX));
411 if (g_acbNumChangeCbk != NULL) {416 if (g_acbNumChangeCbk != NULL) {
412 g_acbNumChangeCbk(dataNum);417 g_acbNumChangeCbk(dataNum);
413 }418 }
@@ -130,7 +130,7 @@ static uint32_t DTAP_RecvBasicFrame(DTAP_Channel_S *transChan, DTAP_Frame_S *dta
130 info.pi = dtapFrame->pi;130 info.pi = dtapFrame->pi;
131 info.tcid = transChan->srcTcid;131 info.tcid = transChan->srcTcid;
132 if (!basic->isReady) {132 if (!basic->isReady) {
133- CHECK_AND_RETURN_RET_LOG(DTAP_TAG, SDF_DListCount(&(basic->cacheRxBuffs)) <= DTAP_BASIC_MODE_MAX_CACHE_NUM,133+ CHECK_AND_RETURN_RET_LOG(DTAP_TAG, SDF_DListCount(&(basic->cacheRxBuffs)) < DTAP_BASIC_MODE_MAX_CACHE_NUM,
134 DTAP_TRANS_BASIC_CACHE_OVERFLOW_ERR, "the number of cached buffs has reached its maximum value");134 DTAP_TRANS_BASIC_CACHE_OVERFLOW_ERR, "the number of cached buffs has reached its maximum value");
135 DTAP_LOGW("channel is not ready, lcid: %hu, srcTcid: %hhu", transChan->lcid, transChan->srcTcid);135 DTAP_LOGW("channel is not ready, lcid: %hu, srcTcid: %hhu", transChan->lcid, transChan->srcTcid);
136 DTAP_BasicCacheFrame_S *basicFrame = DTAP_CreateBasicCacheFrame(buff, info, recvCb);136 DTAP_BasicCacheFrame_S *basicFrame = DTAP_CreateBasicCacheFrame(buff, info, recvCb);
@@ -256,7 +256,7 @@ static uint32_t DTAP_RecvStreamFrame(DTAP_Channel_S *transChan, DTAP_Frame_S *dt
256 }256 }
257 DTAP_Stream_Channel_S *stream = (DTAP_Stream_Channel_S *)transChan->attr;257 DTAP_Stream_Channel_S *stream = (DTAP_Stream_Channel_S *)transChan->attr;
258 stream->recvCb = recvCb;258 stream->recvCb = recvCb;
259- bool isNotFull = SDF_DListCount(&stream->rxList) <= DTAP_STREAM_CACHE_MAX;259+ bool isNotFull = SDF_DListCount(&stream->rxList) < DTAP_STREAM_CACHE_MAX;
260 CHECK_AND_RETURN_RET_LOG(DTAP_TAG, isNotFull, DTAP_TRANS_STREAM_RX_FULL, "rxList is full");260 CHECK_AND_RETURN_RET_LOG(DTAP_TAG, isNotFull, DTAP_TRANS_STREAM_RX_FULL, "rxList is full");
261 SDF_Buff_S *buff = dtapFrame->buff;261 SDF_Buff_S *buff = dtapFrame->buff;
262 uint32_t ret = BuffCheck(dtapFrame, stream, buff);262 uint32_t ret = BuffCheck(dtapFrame, stream, buff);
@@ -30,7 +30,7 @@ extern "C" {
30 30 
31#define DECODE4BYTE_LITTLE(_ptr) \31#define DECODE4BYTE_LITTLE(_ptr) \
32 (uint32_t)(*(uint8_t *)(_ptr) | (*((uint8_t *)(_ptr) + 1) << 8) | \32 (uint32_t)(*(uint8_t *)(_ptr) | (*((uint8_t *)(_ptr) + 1) << 8) | \
33- (*((uint8_t *)(_ptr) + 2) << 16) | (*((uint8_t *)(_ptr) + 3) << 24))33+ (*((uint8_t *)(_ptr) + 2) << 16) | (((uint32_t)(*((uint8_t *)(_ptr) + 3))) << 24))
34 34 
35#define ENCODE2BYTE_LITTLE(_ptr, data) \35#define ENCODE2BYTE_LITTLE(_ptr, data) \
36do { \36do { \