已合并
fix:update br proxy #12523
fix:update br proxy #12523
已合并
crazy_hu创建于 9月11日
共 7 个文件变更+92-19
@@ -872,7 +872,7 @@ static bool IsPidExist(ProxyBaseInfo *baseInfo, uint32_t requestId, pid_t pid)
872 Anonymize(baseInfo->uuid, &uuidTmp);872 Anonymize(baseInfo->uuid, &uuidTmp);
873 TRANS_LOGI(TRANS_SVC,873 TRANS_LOGI(TRANS_SVC,
874 "[br_proxy] brproxy open! brMac=%{public}s, uuid=%{public}s, requestId=%{public}u, pid=%{public}d",874 "[br_proxy] brproxy open! brMac=%{public}s, uuid=%{public}s, requestId=%{public}u, pid=%{public}d",
875- BrMacTmp, uuidTmp, requestId, pid);875+ AnonymizeWrapper(BrMacTmp), AnonymizeWrapper(uuidTmp), requestId, pid);
xuhengxiangxuhengxiang
xuhengxiangxuhengxiang24 天前

AnonymizeWrapper() 被调用在已经通过 Anonymize() 匿名化处理过的 BrMacTmp 和 uuidTmp 上。如果 AnonymizeWrapper 内部分配内存,则该内存永远不会被释放(仅 AnonymizeFree 了原始的 BrMacTmp/uuidTmp),导致内存泄漏。如果 AnonymizeWrapper 使用静态缓冲区,则两次调用会互相覆盖,导致日志中 brMac 和 uuid 显示相同的值。

移除冗余的 Anonymize/AnonymizeFree 调用,直接对原始 brMac 和 uuid 使用 AnonymizeWrapper;或者移除 AnonymizeWrapper 包装,直接使用已匿名化的 BrMacTmp/uuidTmp。

likedislike
xuhengxiangxuhengxiang24 天前

AnonymizeWrapper(BrMacTmp) 和 AnonymizeWrapper(uuidTmp) 的返回值未释放。BrMacTmp 和 uuidTmp 已通过 Anonymize 分配内存,如果 AnonymizeWrapper 内部也分配内存(如内部调用 Anonymize 并返回结果),则每次执行此代码路径都会泄漏两块内存。此外,对已匿名化的字符串再次调用匿名化包装器属于逻辑错误(双重匿名化),可能产生异常输出。

确认 AnonymizeWrapper 的实现。如果它分配内存,需在日志输出后释放其返回值;如果其设计用途是处理原始字符串,应直接传入 baseInfo->brMac 和 baseInfo->uuid,而非已匿名化的 BrMacTmp/uuidTmp。

likedislike
xuhengxiangxuhengxiang24 天前

AnonymizeWrapper(BrMacTmp) 和 AnonymizeWrapper(uuidTmp) 的返回值未被释放。原代码直接使用已 Anonymize 的字符串并通过 AnonymizeFree 释放,新代码用 AnonymizeWrapper 包装后,若该函数内部分配了新内存,则返回值会泄漏。

确认 AnonymizeWrapper 的实现。若其分配内存,需在日志输出后释放返回值;若返回内部静态/栈缓冲区则无需处理。

likedislike
xuhengxiangxuhengxiang24 天前

AnonymizeWrapper(BrMacTmp) 和 AnonymizeWrapper(uuidTmp) 可能分配新内存,但后续仅 AnonymizeFree(BrMacTmp) 和 AnonymizeFree(uuidTmp) 释放了原始内存。如果 AnonymizeWrapper 内部分配了新字符串,则该内存永远不会被释放,导致内存泄漏。

确认 AnonymizeWrapper 的实现。如果它分配新内存,需要保存其返回值并在日志输出后释放;如果它只是返回输入指针的包装,则无需额外释放。或者直接使用 AnonymizeWrapper 替代 Anonymize+AnonymizeFree 模式,移除冗余调用。

likedislike
876 AnonymizeFree(BrMacTmp);876 AnonymizeFree(BrMacTmp);
877 AnonymizeFree(uuidTmp);877 AnonymizeFree(uuidTmp);
878 (void)SoftBusMutexUnlock(&(g_serverList->lock));878 (void)SoftBusMutexUnlock(&(g_serverList->lock));
@@ -1305,7 +1305,8 @@ static int32_t RefreshChannel(ProxyChannelParam *param, bool *isRefresh, uint32_
1305 BrProxyInfo *nodeNext = NULL;1305 BrProxyInfo *nodeNext = NULL;
1306 LIST_FOR_EACH_ENTRY_SAFE(nodeInfo, nodeNext, &(g_proxyList->list), BrProxyInfo, node) {1306 LIST_FOR_EACH_ENTRY_SAFE(nodeInfo, nodeNext, &(g_proxyList->list), BrProxyInfo, node) {
1307 if (strcmp(nodeInfo->proxyInfo.brMac, param->brMac) != 0 ||1307 if (strcmp(nodeInfo->proxyInfo.brMac, param->brMac) != 0 ||
1308- strcmp(nodeInfo->proxyInfo.uuid, param->uuid) != 0) {1308+ strcmp(nodeInfo->proxyInfo.uuid, param->uuid) != 0 ||
xuhengxiangxuhengxiang
xuhengxiangxuhengxiang24 天前

RefreshChannel 中新增了 nodeInfo->requestId != requestId 的匹配条件。这会阻止对同一设备(相同 brMac+uuid)但不同 requestId 的已有通道进行刷新,可能导致无法复用已有连接、创建重复通道或连接失败。

确认此变更是否符合预期。如果 RefreshChannel 的目的是刷新同一设备的已有通道,则不应添加 requestId 匹配条件;如果需要精确匹配特定请求的通道,需确保调用方传入正确的 requestId。

likedislike
xuhengxiangxuhengxiang24 天前

RefreshChannel 中新增了 nodeInfo->requestId != requestId 的条件判断。如果 requestId 是 param->requestId(新请求ID),则此条件会导致所有已有通道(具有不同的旧 requestId)都被跳过,使 RefreshChannel 永远无法匹配到已有通道,导致每次都创建新通道而非复用已有通道,可能造成资源泄漏或连接管理混乱。

确认 requestId 变量的来源。如果意图是匹配旧通道进行刷新,应使用 oldRequestId 而非新的 requestId 进行比较;如果是有意限制只刷新相同 requestId 的通道,需确认此行为变更不会导致已有通道无法被刷新。

likedislike
1309+ nodeInfo->requestId != requestId) {
1309 continue;1310 continue;
1310 }1311 }
1311 if (nodeInfo->isConnected && nodeInfo->channel.refresh != NULL) {1312 if (nodeInfo->isConnected && nodeInfo->channel.refresh != NULL) {
@@ -1322,7 +1323,6 @@ static int32_t RefreshChannel(ProxyChannelParam *param, bool *isRefresh, uint32_
1322static int32_t InitProxyChannelParams(const char *brMac, const char *uuid,1323static int32_t InitProxyChannelParams(const char *brMac, const char *uuid,
1323 uint32_t requestId, int32_t appIndex, ProxyChannelParam *param)1324 uint32_t requestId, int32_t appIndex, ProxyChannelParam *param)
1324{1325{
xuhengxiangxuhengxiang
xuhengxiangxuhengxiang9月15日

潜在的未初始化内存问题:memset_s 从 InitProxyChannelParams 中移除,改由调用方 ConnectPeerDevice 负责。如果存在其他调用 InitProxyChannelParams 的地方且未事先清零结构体,ProxyChannelParam 中未被显式赋值的字段将包含未初始化的栈内存,可能导致不可预期的行为。

确认 InitProxyChannelParams 的所有调用方都在调用前对 ProxyChannelParam 进行了清零操作;或者保留 InitProxyChannelParams 内部的 memset_s,确保函数自身的健壮性。

likedislike
xuhengxiangxuhengxiang24 天前

从 InitProxyChannelParams 中移除了 memset_s 初始化。虽然 ConnectPeerDevice 调用前新增了 memset_s,但如果 InitProxyChannelParams 被其他函数调用且未事先清零 param 结构体,则 ProxyChannelParam 中未被显式赋值的字段将包含未初始化的栈数据,可能导致数据损坏或不可预期行为。

在 InitProxyChannelParams 内部保留 memset_s 初始化,确保无论调用方是否预清零,结构体所有字段都处于已知状态。

likedislike
xuhengxiangxuhengxiang24 天前

从 InitProxyChannelParams 中移除了 memset_s 初始化。该函数是 static 函数,如果文件中存在其他调用者(未在 diff 中显示),它们将传入未清零的 ProxyChannelParam 结构体,导致未初始化字段被后续逻辑读取,可能引发数据损坏或未定义行为。即使当前唯一调用者 ConnectPeerDevice 已补充了 memset_s,这种将初始化责任转移到调用者的模式也是脆弱的。

在 InitProxyChannelParams 函数内部保留 memset_s 初始化,确保函数自身契约完整,不依赖调用者预先清零。

likedislike
xuhengxiangxuhengxiang24 天前

从 InitProxyChannelParams 中移除了 memset_s 对 param 结构体的整体清零。该函数为 static,若存在除 ConnectPeerDevice 之外的其他调用者未在调用前执行 memset_s,ProxyChannelParam 中未显式赋值的字段将为未初始化状态,可能导致未定义行为或数据损坏。

确认 InitProxyChannelParams 的所有调用点均在调用前对 ProxyChannelParam 进行了 memset_s 清零。若有遗漏调用者,需补充清零操作或将 memset_s 保留在函数内部。

likedislike
xuhengxiangxuhengxiang24 天前

从 InitProxyChannelParams 中移除了 memset_s 对 param 的清零操作。虽然当前唯一可见的调用方 ConnectPeerDevice 在调用前添加了 memset_s,但如果存在其他调用方未初始化该结构体,ProxyChannelParam 中未被显式赋值的字段将包含未初始化的栈数据,可能导致未定义行为或数据泄露。

在 InitProxyChannelParams 函数内部保留 memset_s 清零操作以确保防御性安全,或者确保所有调用方在调用前都正确初始化 ProxyChannelParam 结构体。

likedislike
1325- (void)memset_s(param, sizeof(ProxyChannelParam), 0, sizeof(ProxyChannelParam));
1326 param->requestId = requestId;1326 param->requestId = requestId;
1327 param->appIndex = appIndex;1327 param->appIndex = appIndex;
1328 TransBrProxyStorageInfo info;1328 TransBrProxyStorageInfo info;
@@ -1335,7 +1335,7 @@ static int32_t InitProxyChannelParams(const char *brMac, const char *uuid,
1335 if (strcpy_s(param->brMac, sizeof(param->brMac), brMac) != EOK ||1335 if (strcpy_s(param->brMac, sizeof(param->brMac), brMac) != EOK ||
1336 strcpy_s(param->uuid, sizeof(param->uuid), uuid) != EOK) {1336 strcpy_s(param->uuid, sizeof(param->uuid), uuid) != EOK) {
1337 TRANS_LOGE(TRANS_SVC, "[br_proxy] copy brMac or uuid failed");1337 TRANS_LOGE(TRANS_SVC, "[br_proxy] copy brMac or uuid failed");
1338- return SOFTBUS_MEM_ERR;1338+ return SOFTBUS_STRCPY_ERR;
1339 }1339 }
1340 param->timeoutMs = BR_PROXY_MAX_WAIT_TIME_MS;1340 param->timeoutMs = BR_PROXY_MAX_WAIT_TIME_MS;
1341 return SOFTBUS_OK;1341 return SOFTBUS_OK;
@@ -1359,15 +1359,21 @@ static int32_t AddChannelAndRefresh(ProxyChannelParam *param, uint32_t oldReques
1359 }1359 }
1360 if (!isRefresh) {1360 if (!isRefresh) {
1361 ProxyChannelManager *proxyMgr = GetProxyChannelManager();1361 ProxyChannelManager *proxyMgr = GetProxyChannelManager();
1362+ if (proxyMgr == NULL) {
1363+ ret = SOFTBUS_INVALID_PARAM;
1364+ goto FAIL;
xuhengxiangxuhengxiang
xuhengxiangxuhengxiang9月15日

在 AddChannelAndRefresh 函数中,当 proxyMgr == NULL 时跳转到 FAIL 标签,但此时 ret 仍为之前 RefreshChannel 调用成功后的值(SOFTBUS_OK),导致函数在失败路径上返回成功码。调用方会误认为操作成功,后续可能访问未初始化的 channel 资源。

在 goto FAIL 之前设置 ret 为适当的错误码,例如:ret = SOFTBUS_ERR; goto FAIL;

likedislike
xuhengxiangxuhengxiang9月15日

在 AddChannelAndRefresh 函数中,当 proxyMgr == NULL 时跳转到 FAIL 标签,但未将 ret 设置为错误码。如果此时 ret 保留了之前 RefreshChannel 成功的返回值(SOFTBUS_OK),函数将返回成功,导致上层认为通道已打开,但实际上并未执行 openProxyChannel,引发状态不一致和逻辑错误。

在 goto FAIL; 之前添加 ret = SOFTBUS_ERR; 或其他适当的错误码,确保函数在失败时返回错误。

likedislike
1365+ }
xuhengxiang
xuhengxiangxuhengxiang9月15日

逻辑错误:当 GetProxyChannelManager() 返回 NULL 时,直接 goto FAIL,但此时 ret 变量未被设置为错误码(可能仍为之前 RefreshChannel 返回的 SOFTBUS_OK)。这导致函数在失败路径上返回 SOFTBUS_OK,调用方会误认为操作成功。同时 FAIL 标签处会执行 UpdateBrProxyRequestId 和 ServerDeleteChannelFromList 清理操作,但此时 proxyMgr 为 NULL,channel 可能尚未被正确创建,这些清理操作可能不安全。

在 goto FAIL 之前设置 ret 为适当的错误码,例如:if (proxyMgr == NULL) { ret = SOFTBUS_ERR; goto FAIL; }

likedislike
1362 ret = proxyMgr->openProxyChannel(param, &g_channelOpen);1366 ret = proxyMgr->openProxyChannel(param, &g_channelOpen);
1363 if (ret != SOFTBUS_OK) {1367 if (ret != SOFTBUS_OK) {
1364- TRANS_LOGE(TRANS_SVC, "[br_proxy] openProxyChannel failed, ret=%{public}d", ret);1368+ goto FAIL;
1365- (void)UpdateBrProxyRequestId(param->brMac, param->uuid, param->appIndex, oldRequestId, &oldRequestId);
1366- (void)ServerDeleteChannelFromList(channelId);
1367- return ret;
1368 }1369 }
1369 }1370 }
1370 return ret;1371 return ret;
1372+FAIL:
1373+ TRANS_LOGE(TRANS_SVC, "[br_proxy] openProxyChannel failed, ret=%{public}d", ret);
1374+ (void)UpdateBrProxyRequestId(param->brMac, param->uuid, param->appIndex, oldRequestId, &oldRequestId);
1375+ (void)ServerDeleteChannelFromList(channelId);
1376+ return ret;
1371}1377}
1372 1378 
1373static int32_t ConnectPeerDevice(const char *brMac, const char *uuid, uint32_t *requestId, int32_t appIndex)1379static int32_t ConnectPeerDevice(const char *brMac, const char *uuid, uint32_t *requestId, int32_t appIndex)
@@ -1378,6 +1384,7 @@ static int32_t ConnectPeerDevice(const char *brMac, const char *uuid, uint32_t *
1378 }1384 }
1379 *requestId = proxyMgr->generateRequestId();1385 *requestId = proxyMgr->generateRequestId();
1380 ProxyChannelParam param;1386 ProxyChannelParam param;
1387+ (void)memset_s(&param, sizeof(ProxyChannelParam), 0, sizeof(ProxyChannelParam));
byx0010
byx0010byx00109月15日

lgtm

likedislike
1381 int32_t ret = InitProxyChannelParams(brMac, uuid, *requestId, appIndex, &param);1388 int32_t ret = InitProxyChannelParams(brMac, uuid, *requestId, appIndex, &param);
1382 if (ret != SOFTBUS_OK) {1389 if (ret != SOFTBUS_OK) {
1383 return ret;1390 return ret;
@@ -14,6 +14,8 @@
14 */14 */
15 15 
16#include "far_field_proxy_adapter.h"16#include "far_field_proxy_adapter.h"
17+ 
18+#include "conn_event.h"
17#include "conn_log.h"19#include "conn_log.h"
18#include "softbus_error_code.h"20#include "softbus_error_code.h"
19#include "softbus_init_common.h"21#include "softbus_init_common.h"
@@ -61,6 +63,36 @@ static FarFieldCallbackSt *g_farFieldCallback = NULL;
61 63 
62static SoftBusMutex g_adapterMutex;64static SoftBusMutex g_adapterMutex;
63 65 
66+typedef int32_t (*DfxEventCallbackFunc)(const DfxEventExtra *event);
67+typedef void (*RegisterDfxEventCallbackFunc)(DfxEventCallbackFunc callback);
68+ 
69+static int32_t DfxEventCallback(const DfxEventExtra *event)
70+{
71+ CONN_CHECK_AND_RETURN_RET_LOGE(event != NULL, SOFTBUS_INVALID_PARAM, CONN_PROXY, "event is null");
xuhengxiang
xuhengxiangxuhengxiang9月15日

DfxEventCallback 中未对 event->func 和 event->hostPkg 指针进行 NULL 检查。如果这些指针为 NULL 且 ConnEventInner 内部未做防御性处理,可能导致空指针解引用崩溃。

在调用 ConnEventInner 前,对 event->func 和 event->hostPkg 进行 NULL 检查,或确保 ConnEventInner 能够安全处理 NULL 指针参数。

likedislike
72+ ConnEventExtra extra = {
73+ .callerPkg = event->hostPkg,
xuhengxiang
xuhengxiangxuhengxiang9月15日

在 DfxEventCallback 中,未对 event->hostPkg 和 event->func 进行非空校验。如果外部库传入的这两个字段为 NULL,且 ConnEventInner 或其下游函数直接使用这些字符串指针(如 strlen、printf 等),可能导致空指针解引用崩溃。

在使用 event->hostPkg 和 event->func 之前增加非空校验,或确保 ConnEventInner 内部能安全处理 NULL 字符串。

likedislike
74+ .result = event->stageRes,
75+ .errcode = event->errorCode,
76+ .connectReason = event->connectReason,
77+ .costTime = event->costTime,
78+ .sendCnt = event->sendMsgCnt,
xuhengxiang
xuhengxiangxuhengxiang9月15日

DfxEventCallback 函数中直接使用 event->hostPkg 和 event->func,未检查它们是否为 NULL。如果这些指针为 NULL,且下游函数 ConnEventInner 未做空指针检查,可能导致空指针解引用崩溃。

在使用 event->hostPkg 和 event->func 前增加非空检查,或确保下游函数能安全处理 NULL 指针。

likedislike
79+ .receiveCnt = event->receiveMsgCnt,
80+ };
81+ ConnEventInner(event->bizScene, event->bizStage, event->func, event->line, &extra);
82+ return SOFTBUS_OK;
83+}
xuhengxiang
xuhengxiangxuhengxiang9月15日

RegisterDfxEventCallback 函数直接访问全局变量 g_adapterContext.soHandle 但未获取 g_adapterMutex 互斥锁。若 LoadFarFieldSymbols 的调用上下文未持有该锁,存在与 soHandle 相关的数据竞争风险。

在 RegisterDfxEventCallback 中访问 g_adapterContext.soHandle 前确保已持有 g_adapterMutex,或在 LoadFarFieldSymbols 调用链中确认锁已被持有。

likedislike
84+ 
xuhengxiangxuhengxiang
xuhengxiangxuhengxiang9月15日

dlsym 调用后仅通过判断返回值是否为 NULL 来检测错误。dlsym 返回 NULL 既可能表示符号未找到,也可能是符号的合法值。未使用 dlerror() 进行区分,在边缘场景下可能误判。

在调用 dlsym 前先调用 dlerror() 清除之前的错误状态,调用后再检查 dlerror() 返回值以准确判断是否发生错误。

likedislike
xuhengxiangxuhengxiang9月15日

RegisterDfxEventCallback 函数中调用 dlsym 时未检查 g_adapterContext.soHandle 是否为 NULL。如果 soHandle 为 NULL,dlsym 可能会在主程序中搜索符号,导致调用错误的函数或引发未定义行为。

在调用 dlsym 前增加对 g_adapterContext.soHandle != NULL 的检查。

likedislike
xuhengxiangxuhengxiang9月15日

RegisterDfxEventCallback 访问全局变量 g_adapterContext.soHandle 时未持有 g_adapterMutex。如果 LoadFarFieldSymbols 在多线程环境下被调用,或与 so 卸载操作并发,可能导致竞态条件。

确保在持有 g_adapterMutex 的情况下调用 RegisterDfxEventCallback 或访问 g_adapterContext。

likedislike
85+static void RegisterDfxEventCallback(void)
86+{
87+ RegisterDfxEventCallbackFunc registerDfxEventCallback = (RegisterDfxEventCallbackFunc)dlsym(
88+ g_adapterContext.soHandle, "RegisterDfxEventCallback");
89+ if (registerDfxEventCallback == NULL) {
90+ CONN_LOGE(CONN_PROXY, "Failed to load RegisterDfxEventCallback symbol");
91+ return;
92+ }
93+ registerDfxEventCallback(DfxEventCallback);
94+}
95+ 
64static int32_t LoadFarFieldSymbols(void)96static int32_t LoadFarFieldSymbols(void)
65{97{
66 g_adapterContext.initProxy = (FarFieldInitProxyFunc)dlsym(g_adapterContext.soHandle, "FarFieldInitProxy");98 g_adapterContext.initProxy = (FarFieldInitProxyFunc)dlsym(g_adapterContext.soHandle, "FarFieldInitProxy");
@@ -101,6 +133,7 @@ static int32_t LoadFarFieldSymbols(void)
101 CONN_CHECK_AND_RETURN_RET_LOGE(g_adapterContext.refresh != NULL, FAR_FIELD_ADAPTER_SYMBOL_NOT_FOUND, CONN_PROXY,133 CONN_CHECK_AND_RETURN_RET_LOGE(g_adapterContext.refresh != NULL, FAR_FIELD_ADAPTER_SYMBOL_NOT_FOUND, CONN_PROXY,
102 "Failed to load FarFieldRefresh symbol");134 "Failed to load FarFieldRefresh symbol");
103 135 
136+ RegisterDfxEventCallback();
104 CONN_LOGI(CONN_PROXY, "All symbols loaded successfully");137 CONN_LOGI(CONN_PROXY, "All symbols loaded successfully");
105 return SOFTBUS_OK;138 return SOFTBUS_OK;
106}139}
@@ -106,8 +106,11 @@ CONN_ASSIGNER(Errcode, BrProxyState, brProxyState)
106CONN_ASSIGNER(Errcode, BrProxyIsClear, brProxyIsClear)106CONN_ASSIGNER(Errcode, BrProxyIsClear, brProxyIsClear)
107CONN_ASSIGNER(Errcode, BrProxyIsRetry, brProxyIsRetry)107CONN_ASSIGNER(Errcode, BrProxyIsRetry, brProxyIsRetry)
108CONN_ASSIGNER(Errcode, BrProxyIsAcl, brProxyIsAcl)108CONN_ASSIGNER(Errcode, BrProxyIsAcl, brProxyIsAcl)
109+CONN_ASSIGNER(Errcode, ConnectReason, connectReason)
110+CONN_ASSIGNER(Errcode, SendCnt, sendCnt)
111+CONN_ASSIGNER(Errcode, ReceiveCnt, receiveCnt)
109 112 
110-#define CONN_ASSIGNER_SIZE 72 // Size of g_connAssigners113+#define CONN_ASSIGNER_SIZE 75 // Size of g_connAssigners
111static HiSysEventParamAssigner g_connAssigners[] = {114static HiSysEventParamAssigner g_connAssigners[] = {
112 { "STAGE_RES", HISYSEVENT_INT32, ConnAssignerResult },115 { "STAGE_RES", HISYSEVENT_INT32, ConnAssignerResult },
113 { "ERROR_CODE", HISYSEVENT_INT32, ConnAssignerErrcode },116 { "ERROR_CODE", HISYSEVENT_INT32, ConnAssignerErrcode },
@@ -172,15 +175,18 @@ static HiSysEventParamAssigner g_connAssigners[] = {
172 { "BUSINESS_TAG", HISYSEVENT_STRING, ConnAssignerBusinessTag },175 { "BUSINESS_TAG", HISYSEVENT_STRING, ConnAssignerBusinessTag },
173 { "STA_CHLOAD", HISYSEVENT_INT32, ConnAssignerStaChload },176 { "STA_CHLOAD", HISYSEVENT_INT32, ConnAssignerStaChload },
174 { "SAME_ACCOUNT", HISYSEVENT_INT32, ConnAssignerSameAccount },177 { "SAME_ACCOUNT", HISYSEVENT_INT32, ConnAssignerSameAccount },
175- { "DISCOVERY_CNT", HISYSEVENT_INT32, ConnAssignerDiscoveryCnt },178+ { "DISCOVERY_CNT", HISYSEVENT_INT32, ConnAssignerDiscoveryCnt },
176- { "CONNECTING_CNT", HISYSEVENT_INT32, ConnAssignerConnectingCnt },179+ { "CONNECTING_CNT", HISYSEVENT_INT32, ConnAssignerConnectingCnt },
177- { "CONNECT_SUCCESS_CNT", HISYSEVENT_INT32, ConnAssignerConnectSuccessCnt },180+ { "CONNECT_SUCCESS_CNT", HISYSEVENT_INT32, ConnAssignerConnectSuccessCnt },
178- { "CONNECT_FAIL_CNT", HISYSEVENT_INT32, ConnAssignerConnectFailCnt },181+ { "CONNECT_FAIL_CNT", HISYSEVENT_INT32, ConnAssignerConnectFailCnt },
179- { "VIRTUAL_LINK_TYPE", HISYSEVENT_INT32, ConnAssignerVirtualLinkType },182+ { "VIRTUAL_LINK_TYPE", HISYSEVENT_INT32, ConnAssignerVirtualLinkType },
180- { "BR_PROXY_STATE", HISYSEVENT_INT32, ConnAssignerBrProxyState },183+ { "BR_PROXY_STATE", HISYSEVENT_INT32, ConnAssignerBrProxyState },
181 { "BR_PROXY_IS_CLEAR", HISYSEVENT_INT32, ConnAssignerBrProxyIsClear },184 { "BR_PROXY_IS_CLEAR", HISYSEVENT_INT32, ConnAssignerBrProxyIsClear },
182 { "BR_PROXY_IS_RETRY", HISYSEVENT_INT32, ConnAssignerBrProxyIsRetry },185 { "BR_PROXY_IS_RETRY", HISYSEVENT_INT32, ConnAssignerBrProxyIsRetry },
183- { "BR_PROXY_IS_ACL", HISYSEVENT_INT32, ConnAssignerBrProxyIsAcl },186+ { "BR_PROXY_IS_ACL", HISYSEVENT_INT32, ConnAssignerBrProxyIsAcl },
187+ { "CONNECT_REASON", HISYSEVENT_INT32, ConnAssignerConnectReason },
188+ { "SEND_CNT", HISYSEVENT_INT32, ConnAssignerSendCnt },
189+ { "RECEIVE_CNT", HISYSEVENT_INT32, ConnAssignerReceiveCnt },
184 // Modification Note: remember updating CONN_ASSIGNER_SIZE190 // Modification Note: remember updating CONN_ASSIGNER_SIZE
185};191};
186 192 
@@ -40,6 +40,7 @@ typedef enum {
40 EVENT_SCENE_PAGING_PASSIVE_BROADCAST_RESPONSE = 13,40 EVENT_SCENE_PAGING_PASSIVE_BROADCAST_RESPONSE = 13,
41 EVENT_SCENE_BR_PROXY = 14,41 EVENT_SCENE_BR_PROXY = 14,
42 EVENT_SCENE_GENERAL_CONNECT = 15,42 EVENT_SCENE_GENERAL_CONNECT = 15,
43+ EVENT_SCENE_FAR_FIELD = 16,
43} ConnEventScene;44} ConnEventScene;
44 45 
45typedef enum {46typedef enum {
@@ -78,12 +79,29 @@ typedef enum {
78 EVENT_STAGE_BR_PROXY_STATE = 2110,79 EVENT_STAGE_BR_PROXY_STATE = 2110,
79 EVENT_STAGE_BR_PROXY_RECONNECT = 2111,80 EVENT_STAGE_BR_PROXY_RECONNECT = 2111,
80 EVENT_STAGE_BR_PROXY_SEND = 2112,81 EVENT_STAGE_BR_PROXY_SEND = 2112,
82+ 
83+ EVENT_STAGE_FAR_FIELD_START = 2200, // far field stage start[2201,2298]
84+ EVENT_STAGE_FAR_FIELD_END = 2299, // far field stage end[2201,2298]
xuhengxiang
xuhengxiangxuhengxiang24 天前

DfxEventExtra 结构体包含 char *func 和 char *hostPkg 裸指针,未定义所有权语义。若该结构体按值传递或浅拷贝,将导致双重释放、释放后使用或内存泄漏。

明确指针所有权:若为字符串字面量/静态字符串,使用 const char*;若需动态分配,提供深拷贝和释放函数,或使用固定长度字符数组替代。

likedislike
81} ConnEventConnectStage;85} ConnEventConnectStage;
82 86 
83typedef enum {87typedef enum {
xuhengxiang
xuhengxiangxuhengxiang24 天前

新增结构体 DfxEventExtra 包含裸指针 char *func 和 char *hostPkg。如果该结构体实例被异步处理(如DFX事件上报)或按值复制,极易导致悬垂指针、Use-After-Free 或双重释放,引发严重崩溃。

避免在跨模块传递的结构体中使用裸指针。建议使用固定长度的字符数组(如 char func[MAX_LEN]),或明确要求调用方保证指针生命周期,并在结构体中增加深拷贝/释放机制。

likedislike
84 EVENT_STAGE_TCP_COMMON_ONE = 1,88 EVENT_STAGE_TCP_COMMON_ONE = 1,
85} ConnEventTcpCommonStage;89} ConnEventTcpCommonStage;
86 90 
91+typedef struct {
92+ char *func;
93+ int32_t line;
94+ int32_t bizScene;
95+ int32_t bizStage;
96+ int32_t stageRes;
97+ int32_t errorCode;
98+ char *hostPkg;
99+ int32_t connectReason;
100+ int32_t costTime;
101+ int32_t sendMsgCnt;
102+ int32_t receiveMsgCnt;
103+} DfxEventExtra;
104+ 
87typedef struct {105typedef struct {
88 int32_t result; // STAGE_RES106 int32_t result; // STAGE_RES
89 int32_t errcode; // ERROR_CODE107 int32_t errcode; // ERROR_CODE
@@ -157,6 +175,9 @@ typedef struct {
157 int32_t brProxyIsClear; // BR_PROXY_IS_CLEAR175 int32_t brProxyIsClear; // BR_PROXY_IS_CLEAR
158 int32_t brProxyIsRetry; // BR_PROXY_IS_RETRY176 int32_t brProxyIsRetry; // BR_PROXY_IS_RETRY
159 int32_t brProxyIsAcl; // BR_PROXY_IS_ACL177 int32_t brProxyIsAcl; // BR_PROXY_IS_ACL
178+ int32_t connectReason; // CONNECT_REASON
179+ int32_t sendCnt; // SEND_CNT
xuhengxiang
xuhengxiangxuhengxiang24 天前

在公共接口结构体 ConnEventExtra 末尾添加新字段会破坏ABI兼容性。如果存在新旧版本编译的模块(如动态库与主程序)相互调用,由于结构体大小不一致,会导致内存越界读写,引发崩溃或数据损坏。

如果此头文件用于跨模块/进程通信,不应直接修改现有结构体大小。应通过版本号机制、预留字段或新增的扩展结构体指针来传递额外数据,以确保向后兼容。

likedislike
180+ int32_t receiveCnt; // RECEIVE_CNT
160} ConnEventExtra;181} ConnEventExtra;
161 182 
162typedef enum {183typedef enum {
@@ -556,7 +556,7 @@ enum SoftBusErrNo {
556 SOFTBUS_TRANS_DLOPEN_FAILED,556 SOFTBUS_TRANS_DLOPEN_FAILED,
557 SOFTBUS_TRANS_DLSYM_FAILED,557 SOFTBUS_TRANS_DLSYM_FAILED,
558 SOFTBUS_TRANS_DLCLOSE_FAILED,558 SOFTBUS_TRANS_DLCLOSE_FAILED,
559- SOFTBUS_TRANS_MATA_PLUGIN_IS_ENABLED,559+ SOFTBUS_TRANS_META_PLUGIN_IS_ENABLE,
560 560 
561 /* errno begin: -((203 << 21) | (3 << 16) | 0xFFFF) */561 /* errno begin: -((203 << 21) | (3 << 16) | 0xFFFF) */
562 SOFTBUS_AUTH_ERR_BASE = SOFTBUS_ERRNO(AUTH_SUB_MODULE_CODE),562 SOFTBUS_AUTH_ERR_BASE = SOFTBUS_ERRNO(AUTH_SUB_MODULE_CODE),
@@ -105,6 +105,9 @@ static int32_t MatchConnEventNameTypeExtraForAddMsg(const HiSysEventParam *param
105 MatchConnEventNameTypeExtraInt32Param(params, ++index, extra.brProxyIsClear);105 MatchConnEventNameTypeExtraInt32Param(params, ++index, extra.brProxyIsClear);
106 MatchConnEventNameTypeExtraInt32Param(params, ++index, extra.brProxyIsRetry);106 MatchConnEventNameTypeExtraInt32Param(params, ++index, extra.brProxyIsRetry);
107 MatchConnEventNameTypeExtraInt32Param(params, ++index, extra.brProxyIsAcl);107 MatchConnEventNameTypeExtraInt32Param(params, ++index, extra.brProxyIsAcl);
108+ MatchConnEventNameTypeExtraInt32Param(params, ++index, extra.connectReason);
xuhengxiang
xuhengxiangxuhengxiang24 天前

新增3次对 params 数组的访问(connectReason、sendCnt、receiveCnt),但未见对 params 数组大小的边界检查。若调用方传入的 params 数组仍按旧的参数数量分配,将导致数组越界读取(buffer over-read),属于内存安全问题。

确认所有调用方传入的 params 数组容量已同步更新以容纳新增的3个参数;或在 MatchConnEventNameTypeExtraInt32Param 中增加对 index 相对于 paramCount 的边界校验。

likedislike
109+ MatchConnEventNameTypeExtraInt32Param(params, ++index, extra.sendCnt);
110+ MatchConnEventNameTypeExtraInt32Param(params, ++index, extra.receiveCnt);
108 return ++index;111 return ++index;
109}112}
110 113 
@@ -98,6 +98,9 @@ static ConnEventExtra g_validExtra = {
98 .brProxyIsClear = 1,98 .brProxyIsClear = 1,
99 .brProxyIsRetry = 1,99 .brProxyIsRetry = 1,
100 .brProxyIsAcl = 1,100 .brProxyIsAcl = 1,
101+ .connectReason = 1,
102+ .sendCnt = 1,
103+ .receiveCnt = 1,
101};104};
102 105 
103/*106/*
@@ -219,7 +222,7 @@ static ConnEventExtra g_invalidExtra = {
219HWTEST_F(ConnEventTest, ConnEventTest003, TestSize.Level0)222HWTEST_F(ConnEventTest, ConnEventTest003, TestSize.Level0)
220{223{
221 constexpr int32_t TWO_VALID_EXTRA_SIZE = 2; // result, errcode is valid224 constexpr int32_t TWO_VALID_EXTRA_SIZE = 2; // result, errcode is valid
222- constexpr int32_t VALID_EXTRA_SIZE = 34;225+ constexpr int32_t VALID_EXTRA_SIZE = 37;
223 226 
224 HiSysEventMock mock;227 HiSysEventMock mock;
225 EXPECT_CALL(mock,228 EXPECT_CALL(mock,
@@ -240,7 +243,7 @@ HWTEST_F(ConnEventTest, ConnEventTest004, TestSize.Level0)
240{243{
241 ConnEventExtra emptyExtra = { 0 };244 ConnEventExtra emptyExtra = { 0 };
242 constexpr int32_t TWO_VALID_EXTRA_SIZE = 2; // result, errcode is valid245 constexpr int32_t TWO_VALID_EXTRA_SIZE = 2; // result, errcode is valid
243- constexpr int32_t VALID_EXTRA_SIZE = 34;246+ constexpr int32_t VALID_EXTRA_SIZE = 37;
244 247 
245 HiSysEventMock mock;248 HiSysEventMock mock;
246 EXPECT_CALL(mock,249 EXPECT_CALL(mock,