From cf3c9191510735699da14bb5a680f6af9b8a8dcf Mon Sep 17 00:00:00 2001 From: Romain Forlot Date: Thu, 17 May 2018 00:26:01 +0200 Subject: Good usage of strncat and strncpy This change ensure that there are no write over the destination buffer size Change-Id: Ic213e70fab83dfae39a8ff030c823a6ce68aab64 Signed-off-by: Romain Forlot --- ctl-lib/ctl-action.c | 27 +++++++++++++-------------- ctl-lib/ctl-config.c | 39 ++++++++++++++++++++++++--------------- ctl-lib/ctl-lua.c | 41 +++++++++++++++++++++++++---------------- ctl-lib/ctl-lua.h | 5 ----- ctl-lib/ctl-plugin.c | 21 +++++++++++++-------- 5 files changed, 75 insertions(+), 58 deletions(-) diff --git a/ctl-lib/ctl-action.c b/ctl-lib/ctl-action.c index e1329e2..f25e137 100644 --- a/ctl-lib/ctl-action.c +++ b/ctl-lib/ctl-action.c @@ -139,29 +139,28 @@ static void ActionDynRequest(AFB_ReqT request) { void ParseURI(const char *uri, char **first, char **second) { - size_t first_len = 0, second_len = 0; - const char *tmp; + char *tmp; if(! uri || ! first || ! second) { return; } - tmp = strchr(uri, '#'); - first_len = strlen(uri); - + tmp = strdup(uri); if (!tmp) { - *first = calloc(1, sizeof(char) * first_len); - strcpy(*first, uri); + *first = NULL; + *second = NULL; + return; } - else { - second_len = strlen(tmp); - first_len = first_len - second_len; - *first = calloc(1, sizeof(char) * first_len); - *second = calloc(1, sizeof(char) * second_len); + *first = tmp; - strncpy(*first, uri, first_len); - strncpy(*second, tmp+1, second_len); + tmp = strchrnul(tmp, '#'); + if(tmp[0] == '\0') { + *second = NULL; + } + else { + tmp[0] = '\0'; + *second = &tmp[1]; } } diff --git a/ctl-lib/ctl-config.c b/ctl-lib/ctl-config.c index cac8c75..581440c 100644 --- a/ctl-lib/ctl-config.c +++ b/ctl-lib/ctl-config.c @@ -42,12 +42,14 @@ int CtlConfigMagicNew() { return ((long)rand()); } - json_object* CtlConfigScan(const char *dirList, const char *prefix) { - char controlFile [CONTROL_MAXPATH_LEN]; +json_object* CtlConfigScan(const char *dirList, const char *prefix) { + char controlFile[CONTROL_MAXPATH_LEN]; const char *binderName = GetBinderName(); - strncpy(controlFile, prefix, strlen(prefix)+1); - strncat(controlFile, binderName, strlen(binderName)); + controlFile[CONTROL_MAXPATH_LEN - 1] = '\0'; + + strncpy(controlFile, prefix, CONTROL_MAXPATH_LEN - 1); + strncat(controlFile, binderName, CONTROL_MAXPATH_LEN - strlen(controlFile) - 1); // search for default dispatch config file json_object* responseJ = ScanForConfig(dirList, CTL_SCAN_RECURSIVE, controlFile, ".json"); @@ -57,33 +59,38 @@ int CtlConfigMagicNew() { char* ConfigSearch(AFB_ApiT apiHandle, json_object *responseJ) { // We load 1st file others are just warnings - char filepath[CONTROL_MAXPATH_LEN]; + size_t p_length; + char *filepath; + const char *filename; + const char*fullpath; + for (int index = 0; index < json_object_array_length(responseJ); index++) { json_object *entryJ = json_object_array_get_idx(responseJ, index); - char *filename; - char*fullpath; int err = wrap_json_unpack(entryJ, "{s:s, s:s !}", "fullpath", &fullpath, "filename", &filename); if (err) { AFB_ApiError(apiHandle, "CTL-INIT HOOPs invalid JSON entry= %s", json_object_get_string(entryJ)); } - if (index == 0) { - strncpy(filepath, fullpath, strlen(fullpath)+1); - strncat(filepath, "/", strlen("/")); - strncat(filepath, filename, strlen(filename)); + p_length = strlen(fullpath) + 1 + strlen(filename); + filepath = malloc(p_length + 1); + if (index == 0 && filepath) { + strncpy(filepath, fullpath, p_length); + strncat(filepath, "/", p_length - strlen(filepath)); + strncat(filepath, filename, p_length - strlen(filepath)); } } json_object_put(responseJ); - return strndup(filepath, sizeof(filepath)); + return filepath; } char* CtlConfigSearch(AFB_ApiT apiHandle, const char *dirList, const char *prefix) { // search for default dispatch config file json_object* responseJ = CtlConfigScan (dirList, prefix); - if(responseJ) return ConfigSearch(apiHandle, responseJ); + if(responseJ) + return ConfigSearch(apiHandle, responseJ); return NULL; } @@ -172,6 +179,7 @@ json_object* LoadAdditionalsFiles(AFB_ApiT apiHandle, CtlConfigT *ctlHandle, con json_object* CtlUpdateSectionConfig(AFB_ApiT apiHandle, CtlConfigT *ctlHandle, const char *key, json_object *sectionJ, json_object *filesJ) { json_object *sectionArrayJ; + char *oneFile; const char *bindingPath = GetBindingDirPath(apiHandle); if(! json_object_is_type(sectionJ, json_type_array)) { @@ -196,7 +204,7 @@ json_object* CtlUpdateSectionConfig(AFB_ApiT apiHandle, CtlConfigT *ctlHandle, c AFB_ApiError(apiHandle, "No config files found in search path. No changes has been made\n -- %s\n -- %s", CONTROL_CONFIG_PATH, bindingPath); return sectionArrayJ; } - const char *oneFile = ConfigSearch(apiHandle, responseJ); + oneFile = ConfigSearch(apiHandle, responseJ); if (oneFile) { json_object *newSectionJ, *newFileJ = json_object_from_file(oneFile); json_object_object_get_ex(newFileJ, key, &newSectionJ); @@ -215,12 +223,13 @@ json_object* CtlUpdateSectionConfig(AFB_ApiT apiHandle, CtlConfigT *ctlHandle, c AFB_ApiError(apiHandle, "No config files found in search path. No changes has been made\n -- %s\n -- %s", CONTROL_CONFIG_PATH, bindingPath); return sectionArrayJ; } - const char *oneFile = ConfigSearch(apiHandle, responseJ); + oneFile = ConfigSearch(apiHandle, responseJ); json_object *newSectionJ = json_object_from_file(oneFile); LoadAdditionalsFiles(apiHandle, ctlHandle, key, newSectionJ); wrap_json_optarray_for_all(newSectionJ, wrap_json_array_add, sectionArrayJ); } + free(oneFile); return sectionArrayJ; } diff --git a/ctl-lib/ctl-lua.c b/ctl-lib/ctl-lua.c index c2f2376..449ae09 100644 --- a/ctl-lib/ctl-lua.c +++ b/ctl-lib/ctl-lua.c @@ -738,13 +738,14 @@ int LuaLoadScript(const char *luaScriptPath) { } static int LuaDoScript(json_object *queryJ, CtlSourceT *source) { - const char *uid = NULL, *func = NULL; - char luaScriptPath[CONTROL_MAXPATH_LEN]; - char *filename, *fullpath; + const char *uid = NULL, *func = NULL, *filename = NULL, *fullpath = NULL; + char *luaScriptPath = NULL; int index, err = 0; + size_t p_length = 0; json_object *argsJ = NULL; static json_object *luaScriptPathJ = NULL; + if (!queryJ) { return -1; } @@ -756,15 +757,20 @@ static int LuaDoScript(json_object *queryJ, CtlSourceT *source) { "args", &argsJ); if (err) { + AFB_ApiError(source->api, "LUA-DOSCRIPT-SCAN: Miss something in JSON object uid|[spath]|action|[args]: %s", json_object_get_string(queryJ)); return -1; } - // search for filename=script in CONTROL_LUA_PATH + // search for filename=uid*.lua or fallback on bindername*.lua in current directory if (!luaScriptPathJ) { - strncpy(luaScriptPath, CONTROL_DOSCRIPT_PRE, strlen(CONTROL_DOSCRIPT_PRE) + 1); - strncat(luaScriptPath, "-", strlen("-")); - strncat(luaScriptPath, uid, strlen(uid)); - luaScriptPathJ = ScanForConfig(luaScriptPath, CTL_SCAN_RECURSIVE, luaScriptPath, ".lua"); + luaScriptPathJ = ScanForConfig(".", CTL_SCAN_RECURSIVE, uid, ".lua"); + if (!luaScriptPathJ) + luaScriptPathJ = ScanForConfig(".", CTL_SCAN_RECURSIVE, GetBinderName(), ".lua"); + } + + if(!luaScriptPathJ) { + AFB_ApiError(source->api, "LUA-DOSCRIPT-SCAN: No script found"); + return -1; } for (index = 0; index < json_object_array_length(luaScriptPathJ); index++) { @@ -773,14 +779,17 @@ static int LuaDoScript(json_object *queryJ, CtlSourceT *source) { err = wrap_json_unpack(entryJ, "{s:s, s:s !}", "fullpath", &fullpath, "filename", &filename); if (err) { AFB_ApiError(source->api, "LUA-DOSCRIPT-SCAN:HOOPs invalid config file path = %s", json_object_get_string(entryJ)); - return -2; + return -1; } // Ignoring other found script. Only take the first one. if (!index) { - strncpy(luaScriptPath, fullpath, strlen(fullpath) + 1); - strncat(luaScriptPath, "/", strlen("/")); - strncat(luaScriptPath, filename, strlen(filename)); + p_length = strlen(fullpath) + 1 + strlen(filename); + luaScriptPath = malloc(p_length + 1); + + strncpy(luaScriptPath, fullpath, CONTROL_MAXPATH_LEN - 1); + strncat(luaScriptPath, "/", CONTROL_MAXPATH_LEN - strlen(luaScriptPath) - 1); + strncat(luaScriptPath, filename, CONTROL_MAXPATH_LEN - strlen(luaScriptPath) - 1); } } @@ -792,13 +801,13 @@ static int LuaDoScript(json_object *queryJ, CtlSourceT *source) { // if no func name given try to deduct from filename if (!func && (func = (char*) GetMidleName(filename)) != NULL) { - strncpy(luaScriptPath, "_", strlen("_") + 1); - strncat(luaScriptPath, func, strlen(func)); + strncpy(luaScriptPath, "_", CONTROL_MAXPATH_LEN - 1); + strncat(luaScriptPath, func, CONTROL_MAXPATH_LEN - strlen(luaScriptPath) - 1); func = luaScriptPath; } if (!func) { AFB_ApiError(source->api, "LUA-DOSCRIPT:FAIL to deduct funcname from %s", filename); - return -5; + return -1; } // load function (should exist in CONTROL_PATH_LUA @@ -807,7 +816,7 @@ static int LuaDoScript(json_object *queryJ, CtlSourceT *source) { // Push AFB client context on the stack LuaAfbSourceT *afbSource = LuaSourcePush(luaState, source); if (!afbSource) - return -6; + return -1; return 0; } diff --git a/ctl-lib/ctl-lua.h b/ctl-lib/ctl-lua.h index e1c88f6..ba40991 100644 --- a/ctl-lib/ctl-lua.h +++ b/ctl-lib/ctl-lua.h @@ -29,11 +29,6 @@ extern "C" { #define _GNU_SOURCE #endif -// prefix start debug script -#ifndef CONTROL_DOSCRIPT_PRE -#define CONTROL_DOSCRIPT_PRE "debug" -#endif - // default event name used by LUA #ifndef CONTROL_LUA_EVENT #define CONTROL_LUA_EVENT "luaevt" diff --git a/ctl-lib/ctl-plugin.c b/ctl-lib/ctl-plugin.c index 0029b68..d20950f 100644 --- a/ctl-lib/ctl-plugin.c +++ b/ctl-lib/ctl-plugin.c @@ -112,9 +112,12 @@ static int PluginLoadCOne(AFB_ApiT apiHandle, const char *pluginpath, json_objec int Lua2cAddOne(luaL_Reg *l2cFunc, const char* l2cName, int index) { if(ctlPlugin->ctlL2cFunc->l2cCount) {index += ctlPlugin->ctlL2cFunc->l2cCount+1;} - char funcName[CONTROL_MAXPATH_LEN]; - strncpy(funcName, "lua2c_", strlen ("lua2c_")+1); - strncat(funcName, l2cName, strlen (l2cName)); + char *funcName; + size_t p_length = 6 + strlen(l2cName); + funcName = malloc(p_length + 1); + + strncpy(funcName, "lua2c_", p_length); + strncat(funcName, l2cName, p_length - strlen (funcName)); Lua2cFunctionT l2cFunction = (Lua2cFunctionT) dlsym(dlHandle, funcName); if (!l2cFunction) { @@ -194,6 +197,8 @@ static int LoadFoundPlugins(AFB_ApiT apiHandle, json_object *scanResult, json_ob size_t len; json_object *object = NULL; + pluginpath[CONTROL_MAXPATH_LEN - 1] = '\0'; + if (!json_object_is_type(scanResult, json_type_array)) return -1; @@ -210,13 +215,13 @@ static int LoadFoundPlugins(AFB_ApiT apiHandle, json_object *scanResult, json_ob return -1; } - /* Make sure you don't load two found libraries */ ext = strrchr(filename, '.'); - strncpy(pluginpath, fullpath, strlen (fullpath)+1); - strncat(pluginpath, "/", strlen ("/")); - strncat(pluginpath, filename, strlen (filename)); + strncpy(pluginpath, fullpath, CONTROL_MAXPATH_LEN - 1); + strncat(pluginpath, "/", CONTROL_MAXPATH_LEN - strlen(pluginpath) - 1); + strncat(pluginpath, filename, CONTROL_MAXPATH_LEN - strlen (pluginpath) - 1); if(!strcasecmp(ext, CTL_PLUGIN_EXT)) { + /* Make sure you don't load two found libraries */ if(ext && !strcasecmp(ext, CTL_PLUGIN_EXT) && i > 0) { AFB_ApiWarning(apiHandle, "Plugin multiple instances in searchpath will use %s/%s", fullpath, filename); return 0; @@ -259,7 +264,7 @@ static char *GetDefaultSearchPath(AFB_ApiT apiHandle) strncat(searchPath, CONTROL_PLUGIN_PATH, CTL_PLGN_len); } - strncat(searchPath, ":", 1); + strncat(searchPath, ":", sizeof(searchPath) - 1); strncat(searchPath, bindingPath, bindingPath_len); return searchPath; -- cgit 1.2.3-korg