Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions common/DcgmStringHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,15 @@ std::vector<std::string> dcgmTokenizeString(const std::string &src, const std::s
}

/*****************************************************************************/
void dcgmStrncpy(char *destination, const char *source, size_t destinationSize)
bool dcgmStrncpy(char *destination, const char *source, size_t destinationSize)
{
strncpy(destination, source, destinationSize);
destination[destinationSize - 1] = '\0';
if (nullptr == static_cast<char*>(memccpy(destination, source, '\0', destinationSize)))
{
destination[destinationSize - 1] = '\0';
return false;
}

return true;
}

namespace DcgmNs
Expand Down
10 changes: 9 additions & 1 deletion common/DcgmStringHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,20 @@ std::vector<std::string> dcgmTokenizeString(const std::string &src, const std::s
* Unlike strncpy(), This version actually NULL-terminates destionation
* if source is >= (destinationSize+1) in length.
*
* Unlike strncpy(), This version will now inform you if you attempt to
* copy a source that is larger than the destination buffer.
*
* Unlike strncpy(), If the source is shorter than the destination size
* this implementation will immediately stop once the null terminating
* string is encountered. Unlike its strncpy counterpart which will append
* null bytes until n bytes (destinationSize) are written.
*
* destination OUT: Destination buffer
* source IN: Source NULL-terminated c string.
* destinationSize IN: Actual buffer size of destination[].
* Pass sizeof(destination) here for fixed size char arrays.
*/
void dcgmStrncpy(char *destination, const char *source, size_t destinationSize);
bool dcgmStrncpy(char *destination, const char *source, size_t destinationSize);

/*****************************************************************************/
/*
Expand Down
18 changes: 18 additions & 0 deletions common/tests/StringHelpersTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,21 @@ TEST_CASE("ParseRangeString")
}
CHECK(indices[16] == 24);
}

TEST_CASE("dcgmStrncpy differing src sizes")
{
using namespace DcgmNs;
const std::string c_strSmallerThanBuffer = "TestString1";
const std::string c_strSizeOfBuffer = "TestString2TestString2!!";
const std::string c_strLargerThanBuffer = "TestString3TestString3TestString3";
std::vector<char> vDestination(25);

REQUIRE(true == dcgmStrncpy(vDestination.data(), c_strSmallerThanBuffer.c_str(), vDestination.size()));
REQUIRE(c_strSmallerThanBuffer == std::string(vDestination.begin(), vDestination.end()).c_str());

REQUIRE(true == dcgmStrncpy(vDestination.data(), c_strSizeOfBuffer.c_str(), vDestination.size()));
REQUIRE(c_strSizeOfBuffer == std::string(vDestination.begin(), vDestination.end()).c_str());

REQUIRE(false == dcgmStrncpy(vDestination.data(), c_strLargerThanBuffer.c_str(), vDestination.size()));
REQUIRE(c_strLargerThanBuffer != std::string(vDestination.begin(), vDestination.end()).c_str());
}
5 changes: 4 additions & 1 deletion dcgmi/DcgmiTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,10 @@ dcgmReturn_t DcgmiTest::HelperInitFieldValue(dcgmInjectFieldValue_t &injectField
injectFieldValue.value.i64 = atol(injectValue.c_str());
break;
case DCGM_FT_STRING:
dcgmStrncpy(injectFieldValue.value.str, injectValue.c_str(), sizeof(injectFieldValue.value.str));
if (false == dcgmStrncpy(injectFieldValue.value.str, injectValue.c_str(), sizeof(injectFieldValue.value.str)))
{
log_debug("String overflow error for the requested injectValue.");
}
break;
case DCGM_FT_DOUBLE:
injectFieldValue.value.dbl = atof(injectValue.c_str());
Expand Down
189 changes: 60 additions & 129 deletions dcgmlib/src/DcgmApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,12 @@ dcgmReturn_t helperGroupGetInfo(dcgmHandle_t pDcgmHandle,
return (dcgmReturn_t)msg.gi.cmdRet;
}

dcgmStrncpy(pDcgmGroupInfo->groupName, msg.gi.groupInfo.groupName, sizeof(pDcgmGroupInfo->groupName));
if (false == dcgmStrncpy(pDcgmGroupInfo->groupName,
msg.gi.groupInfo.groupName,
sizeof(pDcgmGroupInfo->groupName)))
{
DCGM_LOG_ERROR << "String overflow error for the requested groupInfo groupName field.";
}

if (hostEngineTimestamp)
{
Expand Down Expand Up @@ -917,57 +922,39 @@ dcgmReturn_t helperDeviceGetAttributes(dcgmHandle_t pDcgmHandle, int gpuId, dcgm

case DCGM_FI_DEV_UUID:
{
size_t length;
length = strlen(fv->value.str);
if (length + 1 > sizeof(pDcgmDeviceAttr->identifiers.uuid))
if (false == dcgmStrncpy(pDcgmDeviceAttr->identifiers.uuid,
fv->value.str,
sizeof(pDcgmDeviceAttr->identifiers.uuid)))
{
log_error("String overflow error for the requested UUID field");
dcgmStrncpy(
pDcgmDeviceAttr->identifiers.uuid, DCGM_STR_BLANK, sizeof(pDcgmDeviceAttr->identifiers.uuid));
}
else
{
dcgmStrncpy(
pDcgmDeviceAttr->identifiers.uuid, fv->value.str, sizeof(pDcgmDeviceAttr->identifiers.uuid));
log_error("String overflow error for the requested UUID field.");
dcgmStrncpy(pDcgmDeviceAttr->identifiers.uuid, DCGM_STR_BLANK, sizeof(pDcgmDeviceAttr->identifiers.uuid));
}

break;
}

case DCGM_FI_DEV_VBIOS_VERSION:
{
size_t length;
length = strlen(fv->value.str);
if (length + 1 > sizeof(pDcgmDeviceAttr->identifiers.vbios))
if (false == dcgmStrncpy(pDcgmDeviceAttr->identifiers.vbios,
fv->value.str,
sizeof(pDcgmDeviceAttr->identifiers.vbios)))
{
log_error("String overflow error for the requested VBIOS field");
dcgmStrncpy(
pDcgmDeviceAttr->identifiers.vbios, DCGM_STR_BLANK, sizeof(pDcgmDeviceAttr->identifiers.vbios));
}
else
{
dcgmStrncpy(
pDcgmDeviceAttr->identifiers.vbios, fv->value.str, sizeof(pDcgmDeviceAttr->identifiers.vbios));
log_error("String overflow error for the requested VBIOS field.");
dcgmStrncpy(pDcgmDeviceAttr->identifiers.vbios, DCGM_STR_BLANK, sizeof(pDcgmDeviceAttr->identifiers.vbios));
}

break;
}

case DCGM_FI_DEV_INFOROM_IMAGE_VER:
{
size_t length;
length = strlen(fv->value.str);
if (length + 1 > sizeof(pDcgmDeviceAttr->identifiers.inforomImageVersion))
{
log_error("String overflow error for the requested Inforom field");
dcgmStrncpy(pDcgmDeviceAttr->identifiers.inforomImageVersion,
DCGM_STR_BLANK,
sizeof(pDcgmDeviceAttr->identifiers.inforomImageVersion));
}
else
if (false == dcgmStrncpy(pDcgmDeviceAttr->identifiers.inforomImageVersion,
fv->value.str,
sizeof(pDcgmDeviceAttr->identifiers.inforomImageVersion)))
{
dcgmStrncpy(pDcgmDeviceAttr->identifiers.inforomImageVersion,
fv->value.str,
log_error("String overflow error for the requested Inforom field.");
dcgmStrncpy(pDcgmDeviceAttr->identifiers.inforomImageVersion,
DCGM_STR_BLANK,
sizeof(pDcgmDeviceAttr->identifiers.inforomImageVersion));
}

Expand All @@ -976,83 +963,55 @@ dcgmReturn_t helperDeviceGetAttributes(dcgmHandle_t pDcgmHandle, int gpuId, dcgm

case DCGM_FI_DEV_BRAND:
{
size_t length;
length = strlen(fv->value.str);
if (length + 1 > sizeof(pDcgmDeviceAttr->identifiers.brandName))
if (false == dcgmStrncpy(pDcgmDeviceAttr->identifiers.brandName,
fv->value.str,
sizeof(pDcgmDeviceAttr->identifiers.brandName)))
{
log_error("String overflow error for the requested brand name field");
log_error("String overflow error for the requested brand name field.");
dcgmStrncpy(pDcgmDeviceAttr->identifiers.brandName,
DCGM_STR_BLANK,
sizeof(pDcgmDeviceAttr->identifiers.brandName));
}
else
{
dcgmStrncpy(pDcgmDeviceAttr->identifiers.brandName,
fv->value.str,
sizeof(pDcgmDeviceAttr->identifiers.brandName));
}

break;
}

case DCGM_FI_DEV_NAME:
{
size_t length;
length = strlen(fv->value.str);
if (length + 1 > sizeof(pDcgmDeviceAttr->identifiers.deviceName))
if(false == dcgmStrncpy(pDcgmDeviceAttr->identifiers.deviceName,
fv->value.str,
sizeof(pDcgmDeviceAttr->identifiers.deviceName)))
{
log_error("String overflow error for the requested device name field");
dcgmStrncpy(pDcgmDeviceAttr->identifiers.deviceName,
log_error("String overflow error for the requested device name field.");
dcgmStrncpy(pDcgmDeviceAttr->identifiers.deviceName,
DCGM_STR_BLANK,
sizeof(pDcgmDeviceAttr->identifiers.deviceName));
}
else
{
dcgmStrncpy(pDcgmDeviceAttr->identifiers.deviceName,
fv->value.str,
sizeof(pDcgmDeviceAttr->identifiers.deviceName));
}

break;
}

case DCGM_FI_DEV_SERIAL:
{
size_t length;
length = strlen(fv->value.str);
if (length + 1 > sizeof(pDcgmDeviceAttr->identifiers.serial))
if(false == dcgmStrncpy(pDcgmDeviceAttr->identifiers.serial,
fv->value.str,
sizeof(pDcgmDeviceAttr->identifiers.serial)))
{
log_error("String overflow error for the requested serial field");
dcgmStrncpy(pDcgmDeviceAttr->identifiers.serial,
DCGM_STR_BLANK,
sizeof(pDcgmDeviceAttr->identifiers.serial));
}
else
{
dcgmStrncpy(pDcgmDeviceAttr->identifiers.serial,
fv->value.str,
sizeof(pDcgmDeviceAttr->identifiers.serial));
dcgmStrncpy(pDcgmDeviceAttr->identifiers.serial, DCGM_STR_BLANK, sizeof(pDcgmDeviceAttr->identifiers.serial));
}

break;
}

case DCGM_FI_DEV_PCI_BUSID:
{
size_t length;
length = strlen(fv->value.str);
if (length + 1 > sizeof(pDcgmDeviceAttr->identifiers.pciBusId))
if(false == dcgmStrncpy(pDcgmDeviceAttr->identifiers.pciBusId,
fv->value.str,
sizeof(pDcgmDeviceAttr->identifiers.pciBusId)))
{
log_error("String overflow error for the requested serial field");
dcgmStrncpy(pDcgmDeviceAttr->identifiers.pciBusId,
DCGM_STR_BLANK,
sizeof(pDcgmDeviceAttr->identifiers.pciBusId));
}
else
{
dcgmStrncpy(pDcgmDeviceAttr->identifiers.pciBusId,
fv->value.str,
sizeof(pDcgmDeviceAttr->identifiers.pciBusId));
dcgmStrncpy(pDcgmDeviceAttr->identifiers.pciBusId, DCGM_STR_BLANK, sizeof(pDcgmDeviceAttr->identifiers.pciBusId));
}

break;
Expand Down Expand Up @@ -1120,22 +1079,15 @@ dcgmReturn_t helperDeviceGetAttributes(dcgmHandle_t pDcgmHandle, int gpuId, dcgm

case DCGM_FI_DRIVER_VERSION:
{
size_t length;
length = strlen(fv->value.str);
if (length + 1 > sizeof(pDcgmDeviceAttr->identifiers.driverVersion))
if(false == dcgmStrncpy(pDcgmDeviceAttr->identifiers.driverVersion,
fv->value.str,
sizeof(pDcgmDeviceAttr->identifiers.driverVersion)))
{
log_error("String overflow error for the requested driver version field");
dcgmStrncpy(pDcgmDeviceAttr->identifiers.driverVersion,
DCGM_STR_BLANK,
dcgmStrncpy(pDcgmDeviceAttr->identifiers.driverVersion,
DCGM_STR_BLANK,
sizeof(pDcgmDeviceAttr->identifiers.driverVersion));
}
else
{
dcgmStrncpy(pDcgmDeviceAttr->identifiers.driverVersion,
fv->value.str,
sizeof(pDcgmDeviceAttr->identifiers.driverVersion));
}

break;
}

Expand Down Expand Up @@ -1580,33 +1532,23 @@ dcgmReturn_t helperVgpuInstanceGetAttributes(dcgmHandle_t pDcgmHandle,
{
case DCGM_FI_DEV_VGPU_VM_ID:
{
size_t length;
length = strlen(fv->value.str);
if (length + 1 > sizeof(pDcgmVgpuInstanceAttr->vmId))
if (false == dcgmStrncpy(pDcgmVgpuInstanceAttr->vmId, fv->value.str, sizeof(pDcgmVgpuInstanceAttr->vmId)))
{
log_error("String overflow error for the requested vGPU instance VM ID field");
dcgmStrncpy(pDcgmVgpuInstanceAttr->vmId, DCGM_STR_BLANK, sizeof(pDcgmVgpuInstanceAttr->vmId));
}
else
{
dcgmStrncpy(pDcgmVgpuInstanceAttr->vmId, fv->value.str, sizeof(pDcgmVgpuInstanceAttr->vmId));
}
break;
}

case DCGM_FI_DEV_VGPU_VM_NAME:
{
size_t length;
length = strlen(fv->value.str);
if (length + 1 > sizeof(pDcgmVgpuInstanceAttr->vmName))
if(false == dcgmStrncpy(pDcgmVgpuInstanceAttr->vmName,
fv->value.str,
sizeof(pDcgmVgpuInstanceAttr->vmName)))
{
log_error("String overflow error for the requested vGPU instance VM name field");
dcgmStrncpy(pDcgmVgpuInstanceAttr->vmName, DCGM_STR_BLANK, sizeof(pDcgmVgpuInstanceAttr->vmName));
}
else
{
dcgmStrncpy(pDcgmVgpuInstanceAttr->vmName, fv->value.str, sizeof(pDcgmVgpuInstanceAttr->vmName));
}
break;
}

Expand All @@ -1616,38 +1558,24 @@ dcgmReturn_t helperVgpuInstanceGetAttributes(dcgmHandle_t pDcgmHandle,

case DCGM_FI_DEV_VGPU_UUID:
{
size_t length;
length = strlen(fv->value.str);
if (length + 1 > sizeof(pDcgmVgpuInstanceAttr->vgpuUuid))
if(false == dcgmStrncpy(pDcgmVgpuInstanceAttr->vgpuUuid,
fv->value.str,
sizeof(pDcgmVgpuInstanceAttr->vgpuUuid)))
{
log_error("String overflow error for the requested vGPU instance UUID field");
dcgmStrncpy(
pDcgmVgpuInstanceAttr->vgpuUuid, DCGM_STR_BLANK, sizeof(pDcgmVgpuInstanceAttr->vgpuUuid));
}
else
{
dcgmStrncpy(
pDcgmVgpuInstanceAttr->vgpuUuid, fv->value.str, sizeof(pDcgmVgpuInstanceAttr->vgpuUuid));
dcgmStrncpy(pDcgmVgpuInstanceAttr->vgpuUuid, DCGM_STR_BLANK, sizeof(pDcgmVgpuInstanceAttr->vgpuUuid));
}
break;
}

case DCGM_FI_DEV_VGPU_DRIVER_VERSION:
{
size_t length;
length = strlen(fv->value.str);
if (length + 1 > sizeof(pDcgmVgpuInstanceAttr->vgpuDriverVersion))
if(false == dcgmStrncpy(pDcgmVgpuInstanceAttr->vgpuDriverVersion,
fv->value.str,
sizeof(pDcgmVgpuInstanceAttr->vgpuDriverVersion)))
{
log_error("String overflow error for the requested vGPU instance driver version field");
dcgmStrncpy(pDcgmVgpuInstanceAttr->vgpuDriverVersion,
DCGM_STR_BLANK,
sizeof(pDcgmVgpuInstanceAttr->vgpuDriverVersion));
}
else
{
dcgmStrncpy(pDcgmVgpuInstanceAttr->vgpuDriverVersion,
fv->value.str,
sizeof(pDcgmVgpuInstanceAttr->vgpuDriverVersion));
dcgmStrncpy(pDcgmVgpuInstanceAttr->vgpuDriverVersion, DCGM_STR_BLANK, sizeof(pDcgmVgpuInstanceAttr->vgpuDriverVersion));
}
break;
}
Expand Down Expand Up @@ -2733,7 +2661,10 @@ dcgmReturn_t tsapiFieldGroupCreate(dcgmHandle_t pDcgmHandle,
msg.header.version = dcgm_core_msg_fieldgroup_op_version;

msg.info.fg.version = dcgmFieldGroupInfo_version;
dcgmStrncpy(msg.info.fg.fieldGroupName, fieldGroupName, sizeof(msg.info.fg.fieldGroupName) - 1);
if(false == dcgmStrncpy(msg.info.fg.fieldGroupName, fieldGroupName, sizeof(msg.info.fg.fieldGroupName) - 1))
{
DCGM_LOG_ERROR << "String overflow error for the field grp name.";
}
msg.info.fg.numFieldIds = numFieldIds;
memcpy(msg.info.fg.fieldIds, fieldIds, sizeof(fieldIds[0]) * numFieldIds);

Expand Down
Loading