From 7392ddfcfce9498b460e8958cb0adbac641a3d48 Mon Sep 17 00:00:00 2001 From: orbisai0security Date: Fri, 17 Apr 2026 04:41:34 +0000 Subject: [PATCH] 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] --- tools/rexm/rexm.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 84780988f..1da51028b 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -282,7 +282,7 @@ int main(int argc, char *argv[]) if (catIndex > 3) { 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; for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++) { @@ -291,9 +291,22 @@ int main(int argc, char *argv[]) if (catFound) { - strcpy(exName, argv[2]); // Register filename for new example creation - strncpy(exCategory, exName, TextFindIndex(exName, "_")); - opCode = OP_CREATE; + // Security check: reject path traversal sequences and path separators + 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; + } } else LOG("WARNING: Example category is not valid\n"); } @@ -316,7 +329,7 @@ int main(int argc, char *argv[]) if (catIndex > 3) { 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; for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++) { @@ -325,9 +338,10 @@ int main(int argc, char *argv[]) if (catFound) { - strcpy(inFileName, argv[2]); // Register filename for addition - strcpy(exName, GetFileNameWithoutExt(inFileName)); // Register example name - strncpy(exCategory, exName, TextFindIndex(exName, "_")); + snprintf(inFileName, sizeof(inFileName), "%s", argv[2]); // Register filename for addition (size-bounded) + snprintf(exName, 256, "%s", GetFileNameWithoutExt(inFileName)); // Register example name (size-bounded) + int exNameCatIdx = TextFindIndex(exName, "_"); + snprintf(exCategory, exNameCatIdx + 1, "%s", exName); // Size-bounded copy, always null-terminated opCode = OP_ADD; } else LOG("WARNING: Example category is not valid\n"); @@ -355,7 +369,7 @@ int main(int argc, char *argv[]) if (newCatIndex > 3) { 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; for (int i = 0; i < REXM_MAX_EXAMPLE_CATEGORIES; i++) { @@ -364,10 +378,12 @@ int main(int argc, char *argv[]) if (newCatFound) { - strcpy(exName, argv[2]); // Register example name - strncpy(exCategory, exName, TextFindIndex(exName, "_")); - strcpy(exRename, argv[3]); - strncpy(exRecategory, exRename, TextFindIndex(exRename, "_")); + snprintf(exName, 256, "%s", argv[2]); // Register example name (size-bounded) + int exNameCatIdx = TextFindIndex(exName, "_"); + snprintf(exCategory, exNameCatIdx + 1, "%s", exName); // Size-bounded copy, always null-terminated + 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; } else LOG("WARNING: Example new category is not valid\n");