0
0
Fork 0
mirror of https://github.com/netdata/netdata.git synced 2025-04-14 01:29:11 +00:00

more perflib error checking ()

* more perflib error checking

* more checks

* fix comparison
This commit is contained in:
Costa Tsaousis 2025-02-12 21:36:04 +02:00 committed by GitHub
parent 0453c3aed9
commit d57c5c503b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 65 additions and 40 deletions
src/libnetdata/os/windows-perflib

View file

@ -236,20 +236,22 @@ static BOOL getCounterData(
// --------------------------------------------------------------------------------------------------------------------
static inline BOOL isValidPointer(PERF_DATA_BLOCK *pDataBlock __maybe_unused, void *ptr __maybe_unused) {
#ifdef NETDATA_INTERNAL_CHECKS
return (PBYTE)ptr >= (PBYTE)pDataBlock + pDataBlock->TotalByteLength ? FALSE : TRUE;
#else
return TRUE;
#endif
ALWAYS_INLINE
static BOOL isValidPointer(PERF_DATA_BLOCK *pDataBlock, void *ptr) {
return
!pDataBlock ||
(PBYTE)ptr < (PBYTE)pDataBlock ||
(PBYTE)ptr >= (PBYTE)pDataBlock + pDataBlock->TotalByteLength ? FALSE : TRUE;
}
static inline BOOL isValidStructure(PERF_DATA_BLOCK *pDataBlock __maybe_unused, void *ptr __maybe_unused, size_t length __maybe_unused) {
#ifdef NETDATA_INTERNAL_CHECKS
return (PBYTE)ptr + length > (PBYTE)pDataBlock + pDataBlock->TotalByteLength ? FALSE : TRUE;
#else
return TRUE;
#endif
ALWAYS_INLINE
static BOOL isValidStructure(PERF_DATA_BLOCK *pDataBlock, void *ptr, size_t length) {
return
!pDataBlock ||
!length || length > pDataBlock->TotalByteLength ||
(PBYTE)ptr < (PBYTE)pDataBlock ||
(PBYTE)ptr > (PBYTE)ptr + length || // Check for pointer arithmetic overflow
(PBYTE)ptr + length > (PBYTE)pDataBlock + pDataBlock->TotalByteLength ? FALSE : TRUE;
}
static inline PERF_DATA_BLOCK *getDataBlock(BYTE *pBuffer) {
@ -273,7 +275,8 @@ static inline PERF_DATA_BLOCK *getDataBlock(BYTE *pBuffer) {
return pDataBlock;
}
static inline PERF_OBJECT_TYPE *getObjectType(PERF_DATA_BLOCK* pDataBlock, PERF_OBJECT_TYPE *lastObjectType) {
ALWAYS_INLINE
static PERF_OBJECT_TYPE *getObjectType(PERF_DATA_BLOCK* pDataBlock, PERF_OBJECT_TYPE *lastObjectType) {
PERF_OBJECT_TYPE* pObjectType = NULL;
if(!lastObjectType)
@ -282,18 +285,20 @@ static inline PERF_OBJECT_TYPE *getObjectType(PERF_DATA_BLOCK* pDataBlock, PERF_
pObjectType = (PERF_OBJECT_TYPE *)((PBYTE)lastObjectType + lastObjectType->TotalByteLength);
if(pObjectType && (!isValidPointer(pDataBlock, pObjectType) || !isValidStructure(pDataBlock, pObjectType, pObjectType->TotalByteLength))) {
nd_log(NDLS_COLLECTORS, NDLP_ERR,
"WINDOWS: PERFLIB: Invalid ObjectType!");
nd_log(NDLS_COLLECTORS, NDLP_ERR, "WINDOWS: PERFLIB: %s(): Invalid ObjectType!", __FUNCTION__);
pObjectType = NULL;
}
return pObjectType;
}
inline PERF_OBJECT_TYPE *getObjectTypeByIndex(PERF_DATA_BLOCK *pDataBlock, DWORD ObjectNameTitleIndex) {
ALWAYS_INLINE
PERF_OBJECT_TYPE *getObjectTypeByIndex(PERF_DATA_BLOCK *pDataBlock, DWORD ObjectNameTitleIndex) {
PERF_OBJECT_TYPE *po = NULL;
for(DWORD o = 0; o < pDataBlock->NumObjectTypes ; o++) {
po = getObjectType(pDataBlock, po);
if(!po) break;
if(po->ObjectNameTitleIndex == ObjectNameTitleIndex)
return po;
}
@ -301,60 +306,68 @@ inline PERF_OBJECT_TYPE *getObjectTypeByIndex(PERF_DATA_BLOCK *pDataBlock, DWORD
return NULL;
}
static inline PERF_INSTANCE_DEFINITION *getInstance(
ALWAYS_INLINE
static PERF_INSTANCE_DEFINITION *getInstance(
PERF_DATA_BLOCK *pDataBlock,
PERF_OBJECT_TYPE *pObjectType,
PERF_COUNTER_BLOCK *lastCounterBlock
) {
PERF_INSTANCE_DEFINITION *pInstance;
if(unlikely(!pObjectType))
return NULL;
PERF_INSTANCE_DEFINITION *pInstance;
if(!lastCounterBlock)
pInstance = (PERF_INSTANCE_DEFINITION *)((PBYTE)pObjectType + pObjectType->DefinitionLength);
else
pInstance = (PERF_INSTANCE_DEFINITION *)((PBYTE)lastCounterBlock + lastCounterBlock->ByteLength);
if(pInstance && (!isValidPointer(pDataBlock, pInstance) || !isValidStructure(pDataBlock, pInstance, pInstance->ByteLength))) {
nd_log(NDLS_COLLECTORS, NDLP_ERR,
"WINDOWS: PERFLIB: Invalid Instance Definition!");
nd_log(NDLS_COLLECTORS, NDLP_ERR, "WINDOWS: PERFLIB: %s(): Invalid Instance Definition!", __FUNCTION__);
pInstance = NULL;
}
return pInstance;
}
static inline PERF_COUNTER_BLOCK *getObjectTypeCounterBlock(
ALWAYS_INLINE
static PERF_COUNTER_BLOCK *getObjectTypeCounterBlock(
PERF_DATA_BLOCK *pDataBlock,
PERF_OBJECT_TYPE *pObjectType
) {
if(unlikely(!pObjectType))
return NULL;
PERF_COUNTER_BLOCK *pCounterBlock = (PERF_COUNTER_BLOCK *)((PBYTE)pObjectType + pObjectType->DefinitionLength);
if(pCounterBlock && (!isValidPointer(pDataBlock, pCounterBlock) || !isValidStructure(pDataBlock, pCounterBlock, pCounterBlock->ByteLength))) {
nd_log(NDLS_COLLECTORS, NDLP_ERR,
"WINDOWS: PERFLIB: Invalid ObjectType CounterBlock!");
nd_log(NDLS_COLLECTORS, NDLP_ERR, "WINDOWS: PERFLIB: %s(): Invalid ObjectType CounterBlock!", __FUNCTION__);
pCounterBlock = NULL;
}
return pCounterBlock;
}
static inline PERF_COUNTER_BLOCK *getInstanceCounterBlock(
ALWAYS_INLINE
static PERF_COUNTER_BLOCK *getInstanceCounterBlock(
PERF_DATA_BLOCK *pDataBlock,
PERF_OBJECT_TYPE *pObjectType,
PERF_OBJECT_TYPE *pObjectType __maybe_unused,
PERF_INSTANCE_DEFINITION *pInstance
) {
(void)pObjectType;
if(unlikely(!pInstance))
return NULL;
PERF_COUNTER_BLOCK *pCounterBlock = (PERF_COUNTER_BLOCK *)((PBYTE)pInstance + pInstance->ByteLength);
if(pCounterBlock && (!isValidPointer(pDataBlock, pCounterBlock) || !isValidStructure(pDataBlock, pCounterBlock, pCounterBlock->ByteLength))) {
nd_log(NDLS_COLLECTORS, NDLP_ERR,
"WINDOWS: PERFLIB: Invalid Instance CounterBlock!");
nd_log(NDLS_COLLECTORS, NDLP_ERR, "WINDOWS: PERFLIB: %s(): Invalid Instance CounterBlock!", __FUNCTION__);
pCounterBlock = NULL;
}
return pCounterBlock;
}
inline PERF_INSTANCE_DEFINITION *getInstanceByPosition(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, DWORD instancePosition) {
ALWAYS_INLINE
PERF_INSTANCE_DEFINITION *getInstanceByPosition(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, DWORD instancePosition) {
PERF_INSTANCE_DEFINITION *pi = NULL;
PERF_COUNTER_BLOCK *pc = NULL;
for(DWORD i = 0; i <= instancePosition ;i++) {
@ -364,17 +377,19 @@ inline PERF_INSTANCE_DEFINITION *getInstanceByPosition(PERF_DATA_BLOCK *pDataBlo
return pi;
}
static inline PERF_COUNTER_DEFINITION *getCounterDefinition(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, PERF_COUNTER_DEFINITION *lastCounterDefinition) {
PERF_COUNTER_DEFINITION *pCounterDefinition = NULL;
ALWAYS_INLINE
static PERF_COUNTER_DEFINITION *getCounterDefinition(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, PERF_COUNTER_DEFINITION *lastCounterDefinition) {
if(unlikely(!pObjectType))
return NULL;
PERF_COUNTER_DEFINITION *pCounterDefinition = NULL;
if(!lastCounterDefinition)
pCounterDefinition = (PERF_COUNTER_DEFINITION *)((PBYTE)pObjectType + pObjectType->HeaderLength);
else
pCounterDefinition = (PERF_COUNTER_DEFINITION *)((PBYTE)lastCounterDefinition + lastCounterDefinition->ByteLength);
if(pCounterDefinition && (!isValidPointer(pDataBlock, pCounterDefinition) || !isValidStructure(pDataBlock, pCounterDefinition, pCounterDefinition->ByteLength))) {
nd_log(NDLS_COLLECTORS, NDLP_ERR,
"WINDOWS: PERFLIB: Invalid Counter Definition!");
nd_log(NDLS_COLLECTORS, NDLP_ERR, "WINDOWS: PERFLIB: %s(): Invalid Counter Definition!", __FUNCTION__);
pCounterDefinition = NULL;
}
@ -383,7 +398,8 @@ static inline PERF_COUNTER_DEFINITION *getCounterDefinition(PERF_DATA_BLOCK *pDa
// --------------------------------------------------------------------------------------------------------------------
static inline BOOL getEncodedStringToUTF8(char *dst, size_t dst_len, DWORD CodePage, char *start, DWORD length) {
ALWAYS_INLINE
static BOOL getEncodedStringToUTF8(char *dst, size_t dst_len, DWORD CodePage, char *start, DWORD length) {
static __thread wchar_t unicode[PERFLIB_MAX_NAME_LENGTH];
WCHAR *tempBuffer; // Temporary buffer for Unicode data
@ -411,29 +427,34 @@ static inline BOOL getEncodedStringToUTF8(char *dst, size_t dst_len, DWORD CodeP
return TRUE;
}
inline BOOL getInstanceName(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, PERF_INSTANCE_DEFINITION *pInstance,
ALWAYS_INLINE
BOOL getInstanceName(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, PERF_INSTANCE_DEFINITION *pInstance,
char *buffer, size_t bufferLen) {
(void)pDataBlock;
if (!pInstance || !buffer || !bufferLen) return FALSE;
if (!pObjectType || !pInstance || !buffer || !bufferLen)
return FALSE;
return getEncodedStringToUTF8(buffer, bufferLen, pObjectType->CodePage,
((char *)pInstance + pInstance->NameOffset), pInstance->NameLength);
}
inline BOOL getSystemName(PERF_DATA_BLOCK *pDataBlock, char *buffer, size_t bufferLen) {
ALWAYS_INLINE
BOOL getSystemName(PERF_DATA_BLOCK *pDataBlock, char *buffer, size_t bufferLen) {
return getEncodedStringToUTF8(buffer, bufferLen, 0,
((char *)pDataBlock + pDataBlock->SystemNameOffset), pDataBlock->SystemNameLength);
}
inline bool ObjectTypeHasInstances(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType) {
ALWAYS_INLINE
BOOL ObjectTypeHasInstances(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType) {
(void)pDataBlock;
return pObjectType->NumInstances != PERF_NO_INSTANCES && pObjectType->NumInstances > 0;
return pObjectType && pObjectType->NumInstances != PERF_NO_INSTANCES && pObjectType->NumInstances > 0 ? TRUE : FALSE;
}
PERF_OBJECT_TYPE *perflibFindObjectTypeByName(PERF_DATA_BLOCK *pDataBlock, const char *name) {
PERF_OBJECT_TYPE* pObjectType = NULL;
for(DWORD o = 0; o < pDataBlock->NumObjectTypes; o++) {
pObjectType = getObjectType(pDataBlock, pObjectType);
if(!pObjectType) break;
if(strcmp(name, RegistryFindNameByID(pObjectType->ObjectNameTitleIndex)) == 0)
return pObjectType;
}
@ -515,6 +536,9 @@ failed:
}
bool perflibGetObjectCounter(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, COUNTER_DATA *cd) {
if (unlikely(!pObjectType))
goto cleanup;
PERF_COUNTER_DEFINITION *pCounterDefinition = NULL;
for(DWORD c = 0; c < pObjectType->NumCounters ;c++) {
pCounterDefinition = getCounterDefinition(pDataBlock, pObjectType, pCounterDefinition);
@ -544,6 +568,7 @@ bool perflibGetObjectCounter(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObj
return cd->updated;
}
cleanup:
cd->previous = cd->current;
cd->current = RAW_DATA_EMPTY;
cd->updated = false;

View file

@ -71,7 +71,7 @@ int perflibQueryAndTraverse(DWORD id,
perflib_counter_cb counterCb,
void *data);
bool ObjectTypeHasInstances(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType);
BOOL ObjectTypeHasInstances(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType);
BOOL getInstanceName(PERF_DATA_BLOCK *pDataBlock, PERF_OBJECT_TYPE *pObjectType, PERF_INSTANCE_DEFINITION *pInstance,
char *buffer, size_t bufferLen);