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