[PATCH 6/6] libusbg: Replace sprintf with snprintf.

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

 



Usage of sprintf() may be dangerous in some cases
so use snprintf() to avoid writing after allocated
memory.

Replace USBG_MAX_PATH_SIZE with PATH_MAX from limits.h
to be consistent with maximum size of path.

Signed-off-by: Krzysztof Opasiak <k.opasiak@xxxxxxxxxxx>
---
 include/usbg/usbg.h |    1 -
 src/usbg.c          |  189 +++++++++++++++++++++++++++++++++------------------
 2 files changed, 121 insertions(+), 69 deletions(-)

diff --git a/include/usbg/usbg.h b/include/usbg/usbg.h
index f19b1b2..bf5eafb 100644
--- a/include/usbg/usbg.h
+++ b/include/usbg/usbg.h
@@ -38,7 +38,6 @@
 #define LANG_US_ENG		0x0409
 
 #define USBG_MAX_STR_LENGTH 256
-#define USBG_MAX_PATH_LENGTH 256
 #define USBG_MAX_NAME_LENGTH 40
 
 /*
diff --git a/src/usbg.c b/src/usbg.c
index 2da4a63..808e6c6 100644
--- a/src/usbg.c
+++ b/src/usbg.c
@@ -302,24 +302,28 @@ static int file_select(const struct dirent *dent)
 
 static int usbg_read_buf(char *path, char *name, char *file, char *buf)
 {
-	char p[USBG_MAX_STR_LENGTH];
+	char p[PATH_MAX];
 	FILE *fp;
+	int nmb;
 	int ret = USBG_SUCCESS;
 
-	sprintf(p, "%s/%s/%s", path, name, file);
+	nmb = snprintf(p, PATH_MAX, "%s/%s/%s", path, name, file);
+	if (nmb < PATH_MAX) {
+		fp = fopen(p, "r");
+		if (fp) {
+			/* Successfully opened */
+			if (!fgets(buf, USBG_MAX_STR_LENGTH, fp)) {
+				ERROR("read error");
+				ret = USBG_ERROR_IO;
+			}
 
-	fp = fopen(p, "r");
-	if (fp) {
-		/* Successfully opened */
-		if (!fgets(buf, USBG_MAX_STR_LENGTH, fp)) {
-			ERROR("read error");
-			ret = USBG_ERROR_IO;
+			fclose(fp);
+		} else {
+			/* Set error correctly */
+			ret = usbg_translate_error(errno);
 		}
-
-		fclose(fp);
 	} else {
-		/* Set error correctly */
-		ret = usbg_translate_error(errno);
+		ret = USBG_ERROR_PATH_TOO_LONG;
 	}
 
 	return ret;
@@ -365,25 +369,29 @@ static int usbg_read_string(char *path, char *name, char *file, char *buf)
 
 static int usbg_write_buf(char *path, char *name, char *file, char *buf)
 {
-	char p[USBG_MAX_STR_LENGTH];
+	char p[PATH_MAX];
 	FILE *fp;
+	int nmb;
 	int ret = USBG_SUCCESS;
 
-	sprintf(p, "%s/%s/%s", path, name, file);
+	nmb = snprintf(p, PATH_MAX, "%s/%s/%s", path, name, file);
+	if (nmb < PATH_MAX) {
+		fp = fopen(p, "w");
+		if (fp) {
+			fputs(buf, fp);
+			fflush(fp);
 
-	fp = fopen(p, "w");
-	if (fp) {
-		fputs(buf, fp);
-		fflush(fp);
+			ret = ferror(fp);
+			if (ret)
+				ret = usbg_translate_error(errno);
 
-		ret = ferror(fp);
-		if (ret)
+			fclose(fp);
+		} else {
+			/* Set error correctly */
 			ret = usbg_translate_error(errno);
-
-		fclose(fp);
+		}
 	} else {
-		/* Set error correctly */
-		ret = usbg_translate_error(errno);
+		ret = USBG_ERROR_PATH_TOO_LONG;
 	}
 
 	return ret;
@@ -393,9 +401,12 @@ static int usbg_write_int(char *path, char *name, char *file, int value,
 		char *str)
 {
 	char buf[USBG_MAX_STR_LENGTH];
+	int nmb;
 
-	sprintf(buf, str, value);
-	return usbg_write_buf(path, name, file, buf);
+	nmb = snprintf(buf, USBG_MAX_STR_LENGTH, str, value);
+	return nmb < USBG_MAX_STR_LENGTH ?
+			usbg_write_buf(path, name, file, buf)
+			: USBG_ERROR_INVALID_PARAM;
 }
 
 #define usbg_write_dec(p, n, f, v)	usbg_write_int(p, n, f, v, "%d\n")
@@ -691,18 +702,23 @@ static int usbg_parse_config_strs(char *path, char *name,
 {
 	DIR *dir;
 	int ret;
-	char spath[USBG_MAX_PATH_LENGTH];
-
-	sprintf(spath, "%s/%s/%s/0x%x", path, name, STRINGS_DIR, lang);
-
-	/* Check if directory exist */
-	dir = opendir(spath);
-	if (dir) {
-		closedir(dir);
-		ret = usbg_read_string(spath, "", "configuration",
-				c_strs->configuration);
+	int nmb;
+	char spath[PATH_MAX];
+
+	nmb = snprintf(spath, PATH_MAX, "%s/%s/%s/0x%x", path, name,
+			STRINGS_DIR, lang);
+	if (nmb < PATH_MAX) {
+		/* Check if directory exist */
+		dir = opendir(spath);
+		if (dir) {
+			closedir(dir);
+			ret = usbg_read_string(spath, "", "configuration",
+					c_strs->configuration);
+		} else {
+			ret = usbg_translate_error(errno);
+		}
 	} else {
-		ret = usbg_translate_error(errno);
+		ret = USBG_ERROR_PATH_TOO_LONG;
 	}
 
 	return ret;
@@ -871,10 +887,16 @@ static int usbg_parse_gadget_strs(char *path, char *name, int lang,
 		usbg_gadget_strs *g_strs)
 {
 	int ret;
+	int nmb;
 	DIR *dir;
-	char spath[USBG_MAX_PATH_LENGTH];
+	char spath[PATH_MAX];
 
-	sprintf(spath, "%s/%s/%s/0x%x", path, name, STRINGS_DIR, lang);
+	nmb = snprintf(spath, PATH_MAX, "%s/%s/%s/0x%x", path, name,
+			STRINGS_DIR, lang);
+	if (nmb >= PATH_MAX) {
+		ret = USBG_ERROR_PATH_TOO_LONG;
+		goto out;
+	}
 
 	/* Check if directory exist */
 	dir = opendir(spath);
@@ -1081,10 +1103,15 @@ usbg_binding *usbg_get_link_binding(usbg_config *c, usbg_function *f)
 
 static int usbg_create_empty_gadget(usbg_state *s, char *name, usbg_gadget **g)
 {
-	char gpath[USBG_MAX_PATH_LENGTH];
+	char gpath[PATH_MAX];
+	int nmb;
 	int ret = USBG_SUCCESS;
 
-	sprintf(gpath, "%s/%s", s->path, name);
+	nmb = snprintf(gpath, PATH_MAX, "%s/%s", s->path, name);
+	if (nmb >= PATH_MAX) {
+		ret = USBG_ERROR_PATH_TOO_LONG;
+		goto out;
+	}
 
 	*g = usbg_allocate_gadget(s->path, name, s);
 	if (*g) {
@@ -1109,6 +1136,7 @@ static int usbg_create_empty_gadget(usbg_state *s, char *name, usbg_gadget **g)
 		ret = USBG_ERROR_NO_MEM;
 	}
 
+out:
 	return ret;
 }
 
@@ -1339,13 +1367,19 @@ static int usbg_check_dir(char *path)
 int usbg_set_gadget_strs(usbg_gadget *g, int lang,
 		usbg_gadget_strs *g_strs)
 {
-	char path[USBG_MAX_PATH_LENGTH];
+	char path[PATH_MAX];
+	int nmb;
 	int ret = USBG_ERROR_INVALID_PARAM;
 
 	if (!g || !g_strs)
 		goto out;
 
-	sprintf(path, "%s/%s/%s/0x%x", g->path, g->name, STRINGS_DIR, lang);
+	nmb = snprintf(path, PATH_MAX, "%s/%s/%s/0x%x", g->path, g->name,
+			STRINGS_DIR, lang);
+	if (nmb >= PATH_MAX) {
+		ret = USBG_ERROR_PATH_TOO_LONG;
+		goto out;
+	}
 
 	ret = usbg_check_dir(path);
 	if (ret == USBG_SUCCESS) {
@@ -1366,15 +1400,20 @@ out:
 
 int usbg_set_gadget_serial_number(usbg_gadget *g, int lang, char *serno)
 {
-	char path[USBG_MAX_PATH_LENGTH];
 	int ret = USBG_ERROR_INVALID_PARAM;
 
 	if (g && serno) {
-		sprintf(path, "%s/%s/%s/0x%x", g->path, g->name, STRINGS_DIR, lang);
-
-		ret = usbg_check_dir(path);
-		if (ret == USBG_SUCCESS)
-			ret = usbg_write_string(path, "", "serialnumber", serno);
+		char path[PATH_MAX];
+		int nmb;
+		nmb = snprintf(path, PATH_MAX, "%s/%s/%s/0x%x", g->path,
+				g->name, STRINGS_DIR, lang);
+		if (nmb < PATH_MAX) {
+			ret = usbg_check_dir(path);
+			if (ret == USBG_SUCCESS)
+				ret = usbg_write_string(path, "", "serialnumber", serno);
+		} else {
+			ret = USBG_ERROR_PATH_TOO_LONG;
+		}
 	}
 
 	return ret;
@@ -1382,15 +1421,20 @@ int usbg_set_gadget_serial_number(usbg_gadget *g, int lang, char *serno)
 
 int usbg_set_gadget_manufacturer(usbg_gadget *g, int lang, char *mnf)
 {
-	char path[USBG_MAX_PATH_LENGTH];
 	int ret = USBG_ERROR_INVALID_PARAM;
 
 	if (g && mnf) {
-		sprintf(path, "%s/%s/%s/0x%x", g->path, g->name, STRINGS_DIR, lang);
-
-		ret = usbg_check_dir(path);
-		if (ret == USBG_SUCCESS)
-			ret = usbg_write_string(path, "", "manufacturer", mnf);
+		char path[PATH_MAX];
+		int nmb;
+		nmb = snprintf(path, PATH_MAX, "%s/%s/%s/0x%x", g->path,
+				g->name, STRINGS_DIR, lang);
+		if (nmb < PATH_MAX) {
+			ret = usbg_check_dir(path);
+			if (ret == USBG_SUCCESS)
+				ret = usbg_write_string(path, "", "manufacturer", mnf);
+		} else {
+			ret = USBG_ERROR_PATH_TOO_LONG;
+		}
 	}
 
 	return ret;
@@ -1398,15 +1442,20 @@ int usbg_set_gadget_manufacturer(usbg_gadget *g, int lang, char *mnf)
 
 int usbg_set_gadget_product(usbg_gadget *g, int lang, char *prd)
 {
-	char path[USBG_MAX_PATH_LENGTH];
 	int ret = USBG_ERROR_INVALID_PARAM;
 
 	if (g && prd) {
-		sprintf(path, "%s/%s/%s/0x%x", g->path, g->name, STRINGS_DIR, lang);
-
-		ret = usbg_check_dir(path);
-		if (ret == USBG_SUCCESS)
-			ret = usbg_write_string(path, "", "product", prd);
+		char path[PATH_MAX];
+		int nmb;
+		nmb = snprintf(path, PATH_MAX, "%s/%s/%s/0x%x", g->path,
+				g->name, STRINGS_DIR, lang);
+		if (nmb < PATH_MAX) {
+			ret = usbg_check_dir(path);
+			if (ret == USBG_SUCCESS)
+				ret = usbg_write_string(path, "", "product", prd);
+		} else {
+			ret = USBG_ERROR_PATH_TOO_LONG;
+		}
 	}
 
 	return ret;
@@ -1625,13 +1674,17 @@ int usbg_set_config_string(usbg_config *c, int lang, char *str)
 	int ret = USBG_ERROR_INVALID_PARAM;
 
 	if (c && str) {
-		char path[USBG_MAX_PATH_LENGTH];
-
-		sprintf(path, "%s/%s/%s/0x%x", c->path, c->name, STRINGS_DIR, lang);
-
-		ret = usbg_check_dir(path);
-		if (ret == USBG_SUCCESS)
-			ret = usbg_write_string(path, "", "configuration", str);
+		char path[PATH_MAX];
+		int nmb;
+		nmb = snprintf(path, PATH_MAX, "%s/%s/%s/0x%x", c->path,
+				c->name, STRINGS_DIR, lang);
+		if (nmb < PATH_MAX) {
+			ret = usbg_check_dir(path);
+			if (ret == USBG_SUCCESS)
+				ret = usbg_write_string(path, "", "configuration", str);
+		} else {
+			ret = USBG_ERROR_PATH_TOO_LONG;
+		}
 	}
 
 	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