Merge pull request #24952 from taosdata/fix/TD-28904_and_TD-28894

fix: memory free sequence of sub request caused memory use after free
This commit is contained in:
dapan1121 2024-03-04 08:48:25 +08:00 committed by GitHub
commit d565ac5374
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 40 deletions

View File

@ -354,6 +354,7 @@ SRequestObj* acquireRequest(int64_t rid);
int32_t releaseRequest(int64_t rid); int32_t releaseRequest(int64_t rid);
int32_t removeRequest(int64_t rid); int32_t removeRequest(int64_t rid);
void doDestroyRequest(void* p); void doDestroyRequest(void* p);
int64_t removeFromMostPrevReq(SRequestObj* pRequest);
char* getDbOfConnection(STscObj* pObj); char* getDbOfConnection(STscObj* pObj);
void setConnectionDB(STscObj* pTscObj, const char* db); void setConnectionDB(STscObj* pTscObj, const char* db);

View File

@ -385,6 +385,33 @@ int32_t releaseRequest(int64_t rid) { return taosReleaseRef(clientReqRefPool, ri
int32_t removeRequest(int64_t rid) { return taosRemoveRef(clientReqRefPool, rid); } int32_t removeRequest(int64_t rid) { return taosRemoveRef(clientReqRefPool, rid); }
/// return the most previous req ref id
int64_t removeFromMostPrevReq(SRequestObj* pRequest) {
int64_t mostPrevReqRefId = pRequest->self;
SRequestObj* pTmp = pRequest;
while (pTmp->relation.prevRefId) {
pTmp = acquireRequest(pTmp->relation.prevRefId);
if (pTmp) {
mostPrevReqRefId = pTmp->self;
releaseRequest(mostPrevReqRefId);
} else {
break;
}
}
removeRequest(mostPrevReqRefId);
return mostPrevReqRefId;
}
void destroyNextReq(int64_t nextRefId) {
if (nextRefId) {
SRequestObj* pObj = acquireRequest(nextRefId);
if (pObj) {
releaseRequest(nextRefId);
releaseRequest(nextRefId);
}
}
}
void destroySubRequests(SRequestObj *pRequest) { void destroySubRequests(SRequestObj *pRequest) {
int32_t reqIdx = -1; int32_t reqIdx = -1;
SRequestObj *pReqList[16] = {NULL}; SRequestObj *pReqList[16] = {NULL};
@ -435,7 +462,7 @@ void doDestroyRequest(void *p) {
uint64_t reqId = pRequest->requestId; uint64_t reqId = pRequest->requestId;
tscTrace("begin to destroy request %" PRIx64 " p:%p", reqId, pRequest); tscTrace("begin to destroy request %" PRIx64 " p:%p", reqId, pRequest);
destroySubRequests(pRequest); int64_t nextReqRefId = pRequest->relation.nextRefId;
taosHashRemove(pRequest->pTscObj->pRequests, &pRequest->self, sizeof(pRequest->self)); taosHashRemove(pRequest->pTscObj->pRequests, &pRequest->self, sizeof(pRequest->self));
@ -471,6 +498,7 @@ void doDestroyRequest(void *p) {
taosMemoryFreeClear(pRequest->sqlstr); taosMemoryFreeClear(pRequest->sqlstr);
taosMemoryFree(pRequest); taosMemoryFree(pRequest);
tscTrace("end to destroy request %" PRIx64 " p:%p", reqId, pRequest); tscTrace("end to destroy request %" PRIx64 " p:%p", reqId, pRequest);
destroyNextReq(nextReqRefId);
} }
void destroyRequest(SRequestObj *pRequest) { void destroyRequest(SRequestObj *pRequest) {
@ -479,7 +507,7 @@ void destroyRequest(SRequestObj *pRequest) {
} }
taos_stop_query(pRequest); taos_stop_query(pRequest);
removeRequest(pRequest->self); removeFromMostPrevReq(pRequest);
} }
void taosStopQueryImpl(SRequestObj *pRequest) { void taosStopQueryImpl(SRequestObj *pRequest) {

View File

@ -1254,54 +1254,34 @@ void doAsyncQuery(SRequestObj *pRequest, bool updateMetaForce) {
} }
void restartAsyncQuery(SRequestObj *pRequest, int32_t code) { void restartAsyncQuery(SRequestObj *pRequest, int32_t code) {
int32_t reqIdx = 0; tscInfo("restart request: %s p: %p", pRequest->sqlstr, pRequest);
SRequestObj *pReqList[16] = {NULL}; SRequestObj* pUserReq = pRequest;
SRequestObj *pUserReq = NULL; acquireRequest(pRequest->self);
pReqList[0] = pRequest; while (pUserReq) {
uint64_t tmpRefId = 0; if (pUserReq->self == pUserReq->relation.userRefId || pUserReq->relation.userRefId == 0) {
SRequestObj *pTmp = pRequest;
while (pTmp->relation.prevRefId) {
tmpRefId = pTmp->relation.prevRefId;
pTmp = acquireRequest(tmpRefId);
if (pTmp) {
pReqList[++reqIdx] = pTmp;
releaseRequest(tmpRefId);
} else {
tscError("prev req ref 0x%" PRIx64 " is not there", tmpRefId);
break; break;
}
}
tmpRefId = pRequest->relation.nextRefId;
while (tmpRefId) {
pTmp = acquireRequest(tmpRefId);
if (pTmp) {
tmpRefId = pTmp->relation.nextRefId;
removeRequest(pTmp->self);
releaseRequest(pTmp->self);
} else { } else {
tscError("next req ref 0x%" PRIx64 " is not there", tmpRefId); int64_t nextRefId = pUserReq->relation.nextRefId;
break; releaseRequest(pUserReq->self);
if (nextRefId) {
pUserReq = acquireRequest(nextRefId);
} }
} }
for (int32_t i = reqIdx; i >= 0; i--) {
destroyCtxInRequest(pReqList[i]);
if (pReqList[i]->relation.userRefId == pReqList[i]->self || 0 == pReqList[i]->relation.userRefId) {
pUserReq = pReqList[i];
} else {
removeRequest(pReqList[i]->self);
} }
} bool hasSubRequest = pUserReq != pRequest || pRequest->relation.prevRefId != 0;
if (pUserReq) { if (pUserReq) {
destroyCtxInRequest(pUserReq);
pUserReq->prevCode = code; pUserReq->prevCode = code;
memset(&pUserReq->relation, 0, sizeof(pUserReq->relation)); memset(&pUserReq->relation, 0, sizeof(pUserReq->relation));
} else { } else {
tscError("user req is missing"); tscError("User req is missing");
removeFromMostPrevReq(pRequest);
return; return;
} }
if (hasSubRequest)
removeFromMostPrevReq(pRequest);
else
releaseRequest(pUserReq->self);
doAsyncQuery(pUserReq, true); doAsyncQuery(pUserReq, true);
} }