Skip to content

Commit 622784b

Browse files
authored
fix: [3.3.6] memory leak and use-after-free crash (#35142)
1 parent 8ddcf07 commit 622784b

File tree

3 files changed

+15
-7
lines changed

3 files changed

+15
-7
lines changed

source/client/src/clientImpl.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,9 @@ int32_t asyncExecDdlQuery(SRequestObj* pRequest, SQuery* pQuery) {
482482
}
483483

484484
SCmdMsgInfo* pMsgInfo = pQuery->pCmdMsg;
485+
// Clear pQuery->pCmdMsg before the async call so that nodesDestroyNode (which may be
486+
// triggered by the async response callback on another thread) will not double-free pCmdMsg.
487+
pQuery->pCmdMsg = NULL;
485488
pRequest->type = pMsgInfo->msgType;
486489
pRequest->body.requestMsg = (SDataBuf){.pData = pMsgInfo->pMsg, .len = pMsgInfo->msgLen, .handle = NULL};
487490
pMsgInfo->pMsg = NULL; // pMsg transferred to SMsgSendInfo management
@@ -490,6 +493,11 @@ int32_t asyncExecDdlQuery(SRequestObj* pRequest, SQuery* pQuery) {
490493
SMsgSendInfo* pSendMsg = buildMsgInfoImpl(pRequest);
491494

492495
int32_t code = asyncSendMsgToServer(pAppInfo->pTransporter, &pMsgInfo->epSet, NULL, pSendMsg);
496+
// pMsgInfo->pMsg has been transferred to pRequest->body.requestMsg and pMsgInfo->epSet has
497+
// been consumed by asyncSendMsgToServer; the SCmdMsgInfo struct itself is no longer needed.
498+
// Use the local pMsgInfo variable (not pQuery->pCmdMsg) to avoid a use-after-free: the async
499+
// response callback may have run on another thread and destroyed pQuery by this point.
500+
taosMemoryFree(pMsgInfo);
493501
if (code) {
494502
doRequestCallback(pRequest, code);
495503
}

source/libs/executor/src/sysscanoperator.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3128,7 +3128,7 @@ static SSDataBlock* sysTableScanFromMNode(SOperatorInfo* pOperator, SSysTableSca
31283128
pRsp->numOfRows, pInfo->loadInfo.totalRows);
31293129

31303130
if (pRsp->numOfRows == 0) {
3131-
taosMemoryFree(pRsp);
3131+
taosMemoryFreeClear(pInfo->pRsp);
31323132
return NULL;
31333133
}
31343134
}
@@ -3138,7 +3138,7 @@ static SSDataBlock* sysTableScanFromMNode(SOperatorInfo* pOperator, SSysTableSca
31383138
if (code != TSDB_CODE_SUCCESS) {
31393139
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
31403140
pTaskInfo->code = code;
3141-
taosMemoryFreeClear(pRsp);
3141+
taosMemoryFreeClear(pInfo->pRsp);
31423142
T_LONG_JMP(pTaskInfo->env, code);
31433143
}
31443144
updateLoadRemoteInfo(&pInfo->loadInfo, pRsp->numOfRows, pRsp->compLen, startTs, pOperator);
@@ -3148,10 +3148,10 @@ static SSDataBlock* sysTableScanFromMNode(SOperatorInfo* pOperator, SSysTableSca
31483148
if (code != TSDB_CODE_SUCCESS) {
31493149
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
31503150
pTaskInfo->code = code;
3151-
taosMemoryFreeClear(pRsp);
3151+
taosMemoryFreeClear(pInfo->pRsp);
31523152
T_LONG_JMP(pTaskInfo->env, code);
31533153
}
3154-
taosMemoryFree(pRsp);
3154+
taosMemoryFreeClear(pInfo->pRsp);
31553155
if (pInfo->pRes->info.rows > 0) {
31563156
return pInfo->pRes;
31573157
} else if (pOperator->status == OP_EXEC_DONE) {

test/ci/run_upgrade_compat.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@ function download_version() {
9696
local start_time
9797
start_time=$(date +%s)
9898

99-
# Quick check: skip if cache exists and all files are >= 30M
99+
# Quick check: skip if cache exists and all files are >= 10M
100100
local file_count valid_count
101101
file_count=$(find "$target_dir" -maxdepth 1 -type f 2>/dev/null | wc -l)
102-
valid_count=$(find "$target_dir" -maxdepth 1 -type f -size +30M 2>/dev/null | wc -l)
102+
valid_count=$(find "$target_dir" -maxdepth 1 -type f -size +10M 2>/dev/null | wc -l)
103103
if [ "$file_count" -ge 2 ] && [ "$valid_count" -eq "$file_count" ]; then
104104
return 0
105105
fi
@@ -110,7 +110,7 @@ function download_version() {
110110

111111
# Re-check inside lock in case another process already finished
112112
file_count=$(find "$target_dir" -maxdepth 1 -type f 2>/dev/null | wc -l)
113-
valid_count=$(find "$target_dir" -maxdepth 1 -type f -size +30M 2>/dev/null | wc -l)
113+
valid_count=$(find "$target_dir" -maxdepth 1 -type f -size +10M 2>/dev/null | wc -l)
114114
if [ "$file_count" -ge 2 ] && [ "$valid_count" -eq "$file_count" ]; then
115115
return 0
116116
fi

0 commit comments

Comments
 (0)