fix: the rexm tool performs file system operations (... in rexm.c

The rexm tool performs file system operations (create, add, rename, remove, update) on example files using names derived directly from argv[2] and argv[3]
This commit is contained in:
orbisai0security 2026-04-17 04:41:34 +00:00
parent 6ef36c0a17
commit 7392ddfcfc

View File

@ -282,7 +282,7 @@ int main(int argc, char *argv[])
if (catIndex > 3) if (catIndex > 3)
{ {
char cat[12] = { 0 }; char cat[12] = { 0 };
strncpy(cat, argv[2], catIndex); snprintf(cat, sizeof(cat), "%.*s", catIndex, argv[2]); // Size-bounded copy, always null-terminated
bool catFound = false; bool catFound = false;
for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++) for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++)
{ {
@ -291,10 +291,23 @@ int main(int argc, char *argv[])
if (catFound) if (catFound)
{ {
strcpy(exName, argv[2]); // Register filename for new example creation // Security check: reject path traversal sequences and path separators
strncpy(exCategory, exName, TextFindIndex(exName, "_")); if (strchr(argv[2], '/') != NULL || strchr(argv[2], '\\') != NULL || strstr(argv[2], "..") != NULL)
{
LOG("WARNING: Example name contains invalid path characters\n");
}
else if (strlen(argv[2]) >= 256)
{
LOG("WARNING: Example name is too long\n");
}
else
{
snprintf(exName, 256, "%s", argv[2]); // Register filename for new example creation (size-bounded)
int exNameCatIdx = TextFindIndex(exName, "_");
snprintf(exCategory, exNameCatIdx + 1, "%s", exName); // Size-bounded copy, always null-terminated
opCode = OP_CREATE; opCode = OP_CREATE;
} }
}
else LOG("WARNING: Example category is not valid\n"); else LOG("WARNING: Example category is not valid\n");
} }
else LOG("WARNING: Example name does not include category\n"); else LOG("WARNING: Example name does not include category\n");
@ -316,7 +329,7 @@ int main(int argc, char *argv[])
if (catIndex > 3) if (catIndex > 3)
{ {
char cat[12] = { 0 }; char cat[12] = { 0 };
strncpy(cat, GetFileName(argv[2]), catIndex); snprintf(cat, sizeof(cat), "%.*s", catIndex, GetFileName(argv[2])); // Size-bounded copy, always null-terminated
bool catFound = false; bool catFound = false;
for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++) for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++)
{ {
@ -325,9 +338,10 @@ int main(int argc, char *argv[])
if (catFound) if (catFound)
{ {
strcpy(inFileName, argv[2]); // Register filename for addition snprintf(inFileName, sizeof(inFileName), "%s", argv[2]); // Register filename for addition (size-bounded)
strcpy(exName, GetFileNameWithoutExt(inFileName)); // Register example name snprintf(exName, 256, "%s", GetFileNameWithoutExt(inFileName)); // Register example name (size-bounded)
strncpy(exCategory, exName, TextFindIndex(exName, "_")); int exNameCatIdx = TextFindIndex(exName, "_");
snprintf(exCategory, exNameCatIdx + 1, "%s", exName); // Size-bounded copy, always null-terminated
opCode = OP_ADD; opCode = OP_ADD;
} }
else LOG("WARNING: Example category is not valid\n"); else LOG("WARNING: Example category is not valid\n");
@ -355,7 +369,7 @@ int main(int argc, char *argv[])
if (newCatIndex > 3) if (newCatIndex > 3)
{ {
char cat[12] = { 0 }; char cat[12] = { 0 };
strncpy(cat, argv[3], newCatIndex); snprintf(cat, sizeof(cat), "%.*s", newCatIndex, argv[3]); // Size-bounded copy, always null-terminated
bool newCatFound = false; bool newCatFound = false;
for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++) for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++)
{ {
@ -364,10 +378,12 @@ int main(int argc, char *argv[])
if (newCatFound) if (newCatFound)
{ {
strcpy(exName, argv[2]); // Register example name snprintf(exName, 256, "%s", argv[2]); // Register example name (size-bounded)
strncpy(exCategory, exName, TextFindIndex(exName, "_")); int exNameCatIdx = TextFindIndex(exName, "_");
strcpy(exRename, argv[3]); snprintf(exCategory, exNameCatIdx + 1, "%s", exName); // Size-bounded copy, always null-terminated
strncpy(exRecategory, exRename, TextFindIndex(exRename, "_")); snprintf(exRename, 256, "%s", argv[3]); // Register rename target (size-bounded)
int exRenameCatIdx = TextFindIndex(exRename, "_");
snprintf(exRecategory, exRenameCatIdx + 1, "%s", exRename); // Size-bounded copy, always null-terminated
opCode = OP_RENAME; opCode = OP_RENAME;
} }
else LOG("WARNING: Example new category is not valid\n"); else LOG("WARNING: Example new category is not valid\n");