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.opas...@samsung.com>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to