[PATCH 4/6] libusbg: Remove fixed-size buffers from usbg_function.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux