Path and name length should not be placed in constant size buffer but in allocated memory. Use also PATH_MAX macro from limits.h instead of internal library macro. Handle overflows of snprintf in related funcitons. Signed-off-by: Krzysztof Opasiak <k.opasiak@xxxxxxxxxxx> --- src/usbg.c | 91 +++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 26 deletions(-) diff --git a/src/usbg.c b/src/usbg.c index 50b30e1..171f8f4 100644 --- a/src/usbg.c +++ b/src/usbg.c @@ -70,8 +70,8 @@ struct usbg_function TAILQ_ENTRY(usbg_function) fnode; usbg_gadget *parent; - char name[USBG_MAX_NAME_LENGTH]; - char path[USBG_MAX_PATH_LENGTH]; + char *name; + char *path; usbg_function_type type; }; @@ -415,6 +415,8 @@ static inline void usbg_free_binding(usbg_binding *b) static inline void usbg_free_function(usbg_function *f) { + free(f->path); + free(f->name); free(f); } @@ -510,6 +512,28 @@ static usbg_config *usbg_allocate_config(char *path, char *name, return c; } +static usbg_function *usbg_allocate_function(char *path, char *name, + usbg_gadget *parent) +{ + usbg_function *f; + + f = malloc(sizeof(usbg_config)); + if (f) { + f->name = strdup(name); + f->path = strdup(path); + f->parent = parent; + + if (!(f->name) || !(f->path)) { + free(f->name); + free(f->path); + free(f); + f = NULL; + } + } + + return f; +} + static int usbg_parse_function_net_attrs(usbg_function *f, usbg_function_attrs *f_attrs) { @@ -589,19 +613,20 @@ static int usbg_parse_functions(char *path, usbg_gadget *g) int ret = USBG_SUCCESS; struct dirent **dent; - char fpath[USBG_MAX_PATH_LENGTH]; + char fpath[PATH_MAX]; - sprintf(fpath, "%s/%s/%s", path, g->name, FUNCTIONS_DIR); + n = snprintf(fpath, PATH_MAX, "%s/%s/%s", path, g->name, FUNCTIONS_DIR); + if (n >= PATH_MAX) { + ret = USBG_ERROR_PATH_TOO_LONG; + goto out; + } n = scandir(fpath, &dent, file_select, alphasort); if (n >= 0) { for (i = 0; i < n; i++) { if (ret == USBG_SUCCESS) { - f = malloc(sizeof(usbg_function)); + f = usbg_allocate_function(fpath, dent[i]->d_name, g); if (f) { - f->parent = g; - strcpy(f->name, dent[i]->d_name); - strcpy(f->path, fpath); f->type = usbg_lookup_function_type( strtok(dent[i]->d_name, ".")); TAILQ_INSERT_TAIL(&g->functions, f, fnode); @@ -616,6 +641,7 @@ static int usbg_parse_functions(char *path, usbg_gadget *g) ret = usbg_translate_error(errno); } +out: return ret; } @@ -1353,10 +1379,11 @@ int usbg_set_gadget_product(usbg_gadget *g, int lang, char *prd) int usbg_create_function(usbg_gadget *g, usbg_function_type type, char *instance, usbg_function_attrs *f_attrs, usbg_function **f) { - char fpath[USBG_MAX_PATH_LENGTH]; - char name[USBG_MAX_STR_LENGTH]; + char fpath[PATH_MAX]; + char name[PATH_MAX]; usbg_function *func; int ret = USBG_ERROR_INVALID_PARAM; + int n; if (!g || !f) return ret; @@ -1364,24 +1391,38 @@ int usbg_create_function(usbg_gadget *g, usbg_function_type type, /** * @todo Check for legal function type */ - sprintf(name, "%s.%s", function_names[type], instance); + n = snprintf(name, PATH_MAX, "%s.%s", function_names[type], instance); + if (n >= PATH_MAX) { + ret = USBG_ERROR_PATH_TOO_LONG; + goto out; + } + func = usbg_get_function(g, name); if (func) { ERROR("duplicate function name\n"); - return USBG_ERROR_EXIST; + ret = USBG_ERROR_EXIST; + goto out; } - sprintf(fpath, "%s/%s/%s/%s", g->path, g->name, FUNCTIONS_DIR, name); + n = snprintf(fpath, PATH_MAX, "%s/%s/%s", g->path, g->name, + FUNCTIONS_DIR); + if (n >= PATH_MAX) { + ret = USBG_ERROR_PATH_TOO_LONG; + goto out; + } - *f = malloc(sizeof(usbg_function)); + *f = usbg_allocate_function(fpath, name, g); func = *f; - if (func) { - strcpy(func->name, name); - sprintf(func->path, "%s/%s/%s", g->path, g->name, FUNCTIONS_DIR); + if (!func) { + ERRORNO("allocating function\n"); + ret = USBG_ERROR_NO_MEM; + } + + n = snprintf(&(fpath[n]), PATH_MAX, "/%s", name); + if (n < PATH_MAX) { func->type = type; ret = mkdir(fpath, S_IRWXU | S_IRWXG | S_IRWXO); - if (!ret) { /* Success */ ret = USBG_SUCCESS; @@ -1390,17 +1431,15 @@ int usbg_create_function(usbg_gadget *g, usbg_function_type type, } else { ret = usbg_translate_error(errno); } + } - if (ret == USBG_SUCCESS) - INSERT_TAILQ_STRING_ORDER(&g->functions, fhead, name, + if (ret == USBG_SUCCESS) + INSERT_TAILQ_STRING_ORDER(&g->functions, fhead, name, func, fnode); - else - usbg_free_function(func); - } else { - ERRORNO("allocating function\n"); - ret = USBG_ERROR_NO_MEM; - } + else + usbg_free_function(func); +out: return ret; } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html