From f73a82a126916ec0b8bf695ae184ff7465d8e5ad Mon Sep 17 00:00:00 2001 From: Omar Kallel Date: Thu, 3 Jun 2021 16:57:17 +0100 Subject: [PATCH] Ticket refs #4935: icwmp: make all free of dynamic memory allocations (malloc, calloc, asprintf, strdup) in the end session --- common.c | 138 ++++++++++++++++++++++++---------- config.c | 5 +- cwmp.c | 2 +- cwmp_du_state.c | 49 +++++------- cwmp_uci.c | 54 ++++++------- datamodel_interface.c | 40 +++++----- download.c | 5 +- event.c | 10 +-- http.c | 14 ++-- inc/common.h | 8 +- netlink.c | 7 +- notifications.c | 15 ++-- test/cmocka/unit_test_icwmp.c | 23 +----- ubus.c | 16 ++-- upload.c | 62 ++++++++++----- xml.c | 125 ++++++++++++------------------ 16 files changed, 297 insertions(+), 276 deletions(-) diff --git a/common.c b/common.c index 1376786..35c4648 100755 --- a/common.c +++ b/common.c @@ -25,12 +25,18 @@ #include "cwmp_cli.h" #include "cwmp_du_state.h" -#define CURL_TIMEOUT 20 char *commandKey = NULL; long int flashsize = 256000000; static unsigned long int next_rand_seed = 1; struct cwmp cwmp_main = { 0 }; +LIST_HEAD(cwmp_memory_list); + +struct cwmp_mem { + struct list_head list; + char mem[0]; +}; + struct option cwmp_long_options[] = { { "boot-event", no_argument, NULL, 'b' }, { "get-rpc-methods", no_argument, NULL, 'g' }, { "command-input", no_argument, NULL, 'c' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { NULL, 0, NULL, 0 } }; struct FAULT_CPE FAULT_CPE_ARRAY[] = {[FAULT_CPE_METHOD_NOT_SUPPORTED] = { "9000", FAULT_9000, FAULT_CPE_TYPE_SERVER, "Method not supported" }, @@ -235,37 +241,6 @@ struct transfer_status { int please; /* number of times xferinfo is called while halted */ }; -int upload_file(const char *file_path, const char *url, const char *username, const char *password) -{ - int res_code = 0; - - CURL *curl = curl_easy_init(); - if (curl) { - char *userpass = NULL; - - curl_easy_setopt(curl, CURLOPT_URL, url); - curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY); - cwmp_asprintf(&userpass, "%s:%s", username, password); - curl_easy_setopt(curl, CURLOPT_USERPWD, userpass); - - curl_easy_setopt(curl, CURLOPT_TIMEOUT, CURL_TIMEOUT); - curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); - - FILE *fp = fopen(file_path, "rb"); - if (fp) { - curl_easy_setopt(curl, CURLOPT_READDATA, fp); - curl_easy_perform(curl); - fclose(fp); - } - - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res_code); - curl_easy_cleanup(curl); - FREE(userpass); - } - - return res_code; -} - void get_firewall_zone_name_by_wan_iface(char *if_wan, char **zone_name) { struct uci_section *s; @@ -370,28 +345,25 @@ int opkg_install_package(char *package_path) { FILE *fp; char path[1035]; - char *cmd = NULL; - cwmp_asprintf(&cmd, "opkg --force-depends --force-maintainer install %s", package_path); + char cmd[512]; + + snprintf(cmd, sizeof(cmd), "opkg --force-depends --force-maintainer install %s", package_path); if (cmd == NULL) return -1; fp = popen(cmd, "r"); if (fp == NULL) { - FREE(cmd); CWMP_LOG(INFO, "Failed to run command"); return -1; } /* Read the output a line at a time - output it. */ while (fgets(path, sizeof(path), fp) != NULL) { - if (strstr(path, "Installing") != NULL) { - FREE(cmd); + if (strstr(path, "Installing") != NULL) return 0; - } } /* close */ pclose(fp); - FREE(cmd); return -1; } @@ -495,3 +467,91 @@ int cwmp_get_fault_code_by_string(char *fault_code) return i; } + +/* + * Memory mgmt + */ + +void *icwmp_malloc(size_t size) +{ + struct cwmp_mem *m = malloc(sizeof(struct cwmp_mem) + size); + if (m == NULL) + return NULL; + list_add(&m->list, &cwmp_memory_list); + return (void *)m->mem; +} + +void *icwmp_calloc(int n, size_t size) +{ + struct cwmp_mem *m = calloc(n, sizeof(struct cwmp_mem) + size); + if (m == NULL) + return NULL; + list_add(&m->list, &cwmp_memory_list); + return (void *)m->mem; +} + +void *icwmp_realloc(void *n, size_t size) +{ + struct cwmp_mem *m = NULL; + if (n != NULL) { + m = container_of(n, struct cwmp_mem, mem); + list_del(&m->list); + } + struct cwmp_mem *new_m = realloc(m, sizeof(struct cwmp_mem) + size); + if (new_m == NULL) { + icwmp_free(m); + return NULL; + } else + m = new_m; + list_add(&m->list, &cwmp_memory_list); + return (void *)m->mem; +} + +char *icwmp_strdup(const char *s) +{ + size_t len = strlen(s) + 1; + void *new = icwmp_malloc(len); + if (new == NULL) + return NULL; + return (char *)memcpy(new, s, len); +} + +int icwmp_asprintf(char **s, const char *format, ...) +{ + int size; + char *str = NULL; + va_list arg; + + va_start(arg, format); + size = vasprintf(&str, format, arg); + va_end(arg); + + if (size < 0 || str == NULL) + return -1; + + *s = icwmp_strdup(str); + free(str); + if (*s == NULL) + return -1; + return 0; +} + +void icwmp_free(void *m) +{ + if (m == NULL) + return; + struct cwmp_mem *rm; + rm = container_of(m, struct cwmp_mem, mem); + list_del(&rm->list); + free(rm); +} + +void icwmp_cleanmem() +{ + struct cwmp_mem *mem; + while (cwmp_memory_list.next != &cwmp_memory_list) { + mem = list_entry(cwmp_memory_list.next, struct cwmp_mem, list); + list_del(&mem->list); + free(mem); + } +} diff --git a/config.c b/config.c index 6f1b77c..3cb54f3 100755 --- a/config.c +++ b/config.c @@ -325,10 +325,9 @@ int get_global_config(struct config *conf) if (value[0] == '/') conf->connection_request_path = strdup(value); else { - char *cr_path = NULL; - cwmp_asprintf(&cr_path, "/%s", value); + char cr_path[512]; + snprintf(cr_path, sizeof(cr_path), "/%s", value); conf->connection_request_path = strdup(cr_path); - free(cr_path); } } } else { diff --git a/cwmp.c b/cwmp.c index bc04f4b..5624731 100644 --- a/cwmp.c +++ b/cwmp.c @@ -201,7 +201,6 @@ int run_session_end_func() if (end_session_flag & END_SESSION_REBOOT) { CWMP_LOG(INFO, "Executing Reboot: end session request"); cwmp_reboot(commandKey); - FREE(commandKey); exit(EXIT_SUCCESS); } @@ -217,6 +216,7 @@ int run_session_end_func() exit(EXIT_SUCCESS); } + icwmp_cleanmem(); end_session_flag = 0; return CWMP_OK; } diff --git a/cwmp_du_state.c b/cwmp_du_state.c index df2c2ff..484a930 100644 --- a/cwmp_du_state.c +++ b/cwmp_du_state.c @@ -106,19 +106,17 @@ int cwmp_du_uninstall(char *package_name, char *package_env, char **fault_code) static char *get_software_module_object_eq(char *param1, char *val1, char *param2, char *val2, struct list_head *sw_parameters) { char *err = NULL; - char *sw_parameter_name = NULL; + char sw_parameter_name[128]; if (!param2) - cwmp_asprintf(&sw_parameter_name, "Device.SoftwareModules.DeploymentUnit.[%s==\\\"%s\\\"].", param1, val1); + snprintf(sw_parameter_name, sizeof(sw_parameter_name), "Device.SoftwareModules.DeploymentUnit.[%s==\\\"%s\\\"].", param1, val1); else - cwmp_asprintf(&sw_parameter_name, "Device.SoftwareModules.DeploymentUnit.[%s==\\\"%s\\\"&& %s==\\\"%s\\\"].", param1, val1, param2, val2); + snprintf(sw_parameter_name, sizeof(sw_parameter_name), "Device.SoftwareModules.DeploymentUnit.[%s==\\\"%s\\\"&& %s==\\\"%s\\\"].", param1, val1, param2, val2); err = cwmp_get_parameter_values(sw_parameter_name, sw_parameters); - FREE(sw_parameter_name); - if (err) { - FREE(err); + if (err) return NULL; - } + struct cwmp_dm_parameter *param_value = NULL; char instance[8]; list_for_each_entry (param_value, sw_parameters, list) { @@ -130,15 +128,15 @@ static char *get_software_module_object_eq(char *param1, char *val1, char *param static int get_deployment_unit_name_version(char *uuid, char **name, char **version, char **env) { - char *sw_by_uuid_instance = NULL, *name_param = NULL, *version_param = NULL, *environment_param = NULL; + char *sw_by_uuid_instance = NULL, name_param[128], version_param[128], environment_param[128]; LIST_HEAD(sw_parameters); sw_by_uuid_instance = get_software_module_object_eq("UUID", uuid, NULL, NULL, &sw_parameters); if (!sw_by_uuid_instance) return 0; - cwmp_asprintf(&name_param, "Device.SoftwareModules.DeploymentUnit.%s.Name", sw_by_uuid_instance); - cwmp_asprintf(&version_param, "Device.SoftwareModules.DeploymentUnit.%s.Version", sw_by_uuid_instance); - cwmp_asprintf(&environment_param, "Device.SoftwareModules.DeploymentUnit.%s.ExecutionEnvRef", sw_by_uuid_instance); + snprintf(name_param, sizeof(name_param), "Device.SoftwareModules.DeploymentUnit.%s.Name", sw_by_uuid_instance); + snprintf(version_param, sizeof(version_param), "Device.SoftwareModules.DeploymentUnit.%s.Version", sw_by_uuid_instance); + snprintf(environment_param, sizeof(environment_param), "Device.SoftwareModules.DeploymentUnit.%s.ExecutionEnvRef", sw_by_uuid_instance); struct cwmp_dm_parameter *param_value = NULL; list_for_each_entry (param_value, &sw_parameters, list) { @@ -156,15 +154,12 @@ static int get_deployment_unit_name_version(char *uuid, char **name, char **vers } } cwmp_free_all_dm_parameter_list(&sw_parameters); - FREE(name_param); - FREE(version_param); - FREE(environment_param); return 1; } static char *get_softwaremodules_uuid(char *url) { - char *sw_by_url_instance = NULL, *uuid_param = NULL, *uuid = NULL; + char *sw_by_url_instance = NULL, uuid_param[128], *uuid = NULL; LIST_HEAD(sw_parameters); @@ -172,7 +167,7 @@ static char *get_softwaremodules_uuid(char *url) if (!sw_by_url_instance) return NULL; - cwmp_asprintf(&uuid_param, "Device.SoftwareModules.DeploymentUnit.%s.UUID", sw_by_url_instance); + snprintf(uuid_param, sizeof(uuid_param), "Device.SoftwareModules.DeploymentUnit.%s.UUID", sw_by_url_instance); struct cwmp_dm_parameter *param_value = NULL; list_for_each_entry (param_value, &sw_parameters, list) { @@ -182,20 +177,19 @@ static char *get_softwaremodules_uuid(char *url) } } cwmp_free_all_dm_parameter_list(&sw_parameters); - FREE(uuid_param); return uuid; } static char *get_softwaremodules_url(char *uuid) { - char *sw_by_uuid_instance = NULL, *url_param = NULL, *url = NULL; + char *sw_by_uuid_instance = NULL, url_param[128], *url = NULL; LIST_HEAD(sw_parameters); sw_by_uuid_instance = get_software_module_object_eq("UUID", uuid, NULL, NULL, &sw_parameters); if (!sw_by_uuid_instance) return NULL; - cwmp_asprintf(&url_param, "Device.SoftwareModules.DeploymentUnit.%s.URL", sw_by_uuid_instance); + snprintf(url_param, sizeof(url_param), "Device.SoftwareModules.DeploymentUnit.%s.URL", sw_by_uuid_instance); struct cwmp_dm_parameter *param_value = NULL; list_for_each_entry (param_value, &sw_parameters, list) { @@ -205,7 +199,6 @@ static char *get_softwaremodules_url(char *uuid) } } cwmp_free_all_dm_parameter_list(&sw_parameters); - FREE(url_param); return url; } @@ -227,26 +220,23 @@ static bool environment_exists(char *environment_path) LIST_HEAD(environment_list); char *err = cwmp_get_parameter_values(environment_path, &environment_list); cwmp_free_all_dm_parameter_list(&environment_list); - if (err) { - FREE(err); + if (err) return false; - } else { + else return true; - } } static char *get_exec_env_name(char *environment_path) { - char *env_param = NULL, *env_name = ""; + char env_param[256], *env_name = ""; LIST_HEAD(environment_list); char *err = cwmp_get_parameter_values(environment_path, &environment_list); - if (err) { - FREE(err); + if (err) return strdup(""); - } + struct cwmp_dm_parameter *param_value = NULL; - cwmp_asprintf(&env_param, "%sName", environment_path); + snprintf(env_param, sizeof(env_param), "%sName", environment_path); list_for_each_entry (param_value, &environment_list, list) { if (strcmp(param_value->name, env_param) == 0) { env_name = strdup(param_value->value); @@ -254,7 +244,6 @@ static char *get_exec_env_name(char *environment_path) } } cwmp_free_all_dm_parameter_list(&environment_list); - FREE(env_param); return env_name; } diff --git a/cwmp_uci.c b/cwmp_uci.c index 449c5d5..59ea335 100644 --- a/cwmp_uci.c +++ b/cwmp_uci.c @@ -108,9 +108,9 @@ char *cwmp_uci_list_to_string(struct uci_list *list, char *delimitor) if (pos) list_val[pos - 1] = 0; - return strdup(list_val); + return icwmp_strdup(list_val); } else { - return strdup(""); + return icwmp_strdup(""); } } @@ -127,9 +127,9 @@ int cwmp_uci_get_option_value_string(char *package, char *section, char *option, if (ptr.o && ptr.o->type == UCI_TYPE_LIST) { *value = cwmp_uci_list_to_string(&ptr.o->v.list, " "); } else if (ptr.o && ptr.o->v.string) { - *value = strdup(ptr.o->v.string); + *value = icwmp_strdup(ptr.o->v.string); } else { - *value = strdup(""); + *value = icwmp_strdup(""); cwmp_uci_exit(); return -1; } @@ -185,12 +185,12 @@ int cwmp_uci_get_option_value_list(char *package, char *section, char *option, s uci_foreach_element(&ptr.o->v.list, e) { if ((e != NULL) && (e->name)) { - uci_list_elem = calloc(1, sizeof(struct config_uci_list)); + uci_list_elem = icwmp_calloc(1, sizeof(struct config_uci_list)); if (uci_list_elem == NULL) { uci_free_context(cwmp_uci_ctx); return -1; } - uci_list_elem->value = strdup(e->name); + uci_list_elem->value = icwmp_strdup(e->name); list_add_tail(&(uci_list_elem->list), list); size++; } else { @@ -237,13 +237,13 @@ int uci_get_list_value(char *cmd, struct list_head *list) uci_foreach_element(&ptr.o->v.list, e) { if ((e != NULL) && (e->name)) { - uci_list_elem = calloc(1, sizeof(struct config_uci_list)); + uci_list_elem = icwmp_calloc(1, sizeof(struct config_uci_list)); if (uci_list_elem == NULL) { free(t); uci_free_context(c); return CWMP_GEN_ERR; } - uci_list_elem->value = strdup(e->name); + uci_list_elem->value = icwmp_strdup(e->name); list_add_tail(&(uci_list_elem->list), list); size++; } else { @@ -356,12 +356,11 @@ int uci_set_value(char *path, char *value, uci_config_action action) uci_set_savedir(c, state_path); } - char *cmd = NULL; - cwmp_asprintf(&cmd, "%s=%s", path, value); + char cmd[256]; + snprintf(cmd, sizeof(cmd), "%s=%s", path, value); if (uci_lookup_ptr(c, &ptr, cmd, true) != UCI_OK) { uci_free_context(c); - FREE(cmd); return CWMP_GEN_ERR; } @@ -371,11 +370,9 @@ int uci_set_value(char *path, char *value, uci_config_action action) ret = uci_save(c, ptr.p); } else { CWMP_LOG(ERROR, "UCI delete not succeed %s", cmd); - FREE(cmd); return CWMP_GEN_ERR; } uci_free_context(c); - FREE(cmd); return CWMP_OK; } @@ -414,7 +411,11 @@ static inline void cwmp_uci_list_insert(struct uci_list *list, struct uci_list * list->next = ptr; } -static inline void cwmp_uci_list_add(struct uci_list *head, struct uci_list *ptr) { cwmp_uci_list_insert(head->prev, ptr); } +static inline void cwmp_uci_list_add(struct uci_list *head, struct uci_list *ptr) +{ // + cwmp_uci_list_insert(head->prev, ptr); +} + int cwmp_uci_get_value_by_section_string(struct uci_section *s, char *option, char **value) { struct uci_element *e; @@ -430,14 +431,14 @@ int cwmp_uci_get_value_by_section_string(struct uci_section *s, char *option, ch if (o->type == UCI_TYPE_LIST) { *value = cwmp_uci_list_to_string(&o->v.list, " "); } else { - *value = o->v.string ? strdup(o->v.string) : strdup(""); + *value = o->v.string ? icwmp_strdup(o->v.string) : icwmp_strdup(""); } return 0; } } not_found: - *value = strdup(""); + *value = icwmp_strdup(""); return -1; } @@ -452,7 +453,8 @@ int cwmp_uci_get_value_by_section_list(struct uci_section *s, char *option, stru struct uci_element *e; struct uci_option *o; struct uci_list *list; - char *pch = NULL, *spch = NULL, *dup; + char *pch = NULL, *spch = NULL; + char dup[256]; *value = NULL; @@ -470,12 +472,12 @@ int cwmp_uci_get_value_by_section_list(struct uci_section *s, char *option, stru case UCI_TYPE_STRING: if (!o->v.string || (o->v.string)[0] == '\0') return 0; - list = calloc(1, sizeof(struct uci_list)); + list = icwmp_calloc(1, sizeof(struct uci_list)); cwmp_uci_list_init(list); - dup = strdup(o->v.string); + snprintf(dup, sizeof(dup), "%s", o->v.string); pch = strtok_r(dup, " ", &spch); while (pch != NULL) { - e = calloc(1, sizeof(struct uci_element)); + e = icwmp_calloc(1, sizeof(struct uci_element)); e->name = pch; cwmp_uci_list_add(list, &e->list); pch = strtok_r(NULL, " ", &spch); @@ -494,7 +496,8 @@ struct uci_section *cwmp_uci_walk_section(char *package, char *stype, void *arg1 { struct uci_section *s = NULL; struct uci_element *e, *m; - char *value = NULL, *dup = NULL, *pch = NULL, *spch = NULL; + char *value = NULL, *pch = NULL, *spch = NULL; + char dup[256]; struct uci_list *list_value, *list_section; struct uci_ptr ptr = { 0 }; @@ -527,16 +530,14 @@ struct uci_section *cwmp_uci_walk_section(char *package, char *stype, void *arg1 break; case CWMP_CMP_OPTION_CONT_WORD: cwmp_uci_get_value_by_section_string(s, (char *)arg1, &value); - dup = strdup(value); + snprintf(dup, sizeof(dup), "%s", value); pch = strtok_r(dup, " ", &spch); while (pch != NULL) { - if (strcmp((char *)arg2, pch) == 0) { - FREE(dup); + if (strcmp((char *)arg2, pch) == 0) goto end; - } + pch = strtok_r(NULL, " ", &spch); } - FREE(dup); break; case CWMP_CMP_LIST_CONTAINING: cwmp_uci_get_value_by_section_list(s, (char *)arg1, &list_value); @@ -560,7 +561,6 @@ struct uci_section *cwmp_uci_walk_section(char *package, char *stype, void *arg1 s = NULL; } end: - FREE(value); return s; } diff --git a/datamodel_interface.c b/datamodel_interface.c index 7110e38..299bfd6 100755 --- a/datamodel_interface.c +++ b/datamodel_interface.c @@ -215,7 +215,7 @@ void ubus_get_single_parameter_callback(struct ubus_request *req, int type __att int fault_code = get_fault(msg); result->name = NULL; result->type = NULL; - cwmp_asprintf(&result->value, "%d", fault_code); + icwmp_asprintf(&result->value, "%d", fault_code); return; } const struct blobmsg_policy p[3] = { { "parameter", BLOBMSG_TYPE_STRING }, { "value", BLOBMSG_TYPE_STRING }, { "type", BLOBMSG_TYPE_STRING } }; @@ -227,9 +227,9 @@ void ubus_get_single_parameter_callback(struct ubus_request *req, int type __att blobmsg_parse(p, 3, tb, blobmsg_data(cur), blobmsg_len(cur)); if (!tb[0]) continue; - result->name = strdup(blobmsg_get_string(tb[0])); - result->value = strdup(tb[1] ? blobmsg_get_string(tb[1]) : ""); - result->type = strdup(tb[2] ? blobmsg_get_string(tb[2]) : ""); + result->name = icwmp_strdup(blobmsg_get_string(tb[0])); + result->value = icwmp_strdup(tb[1] ? blobmsg_get_string(tb[1]) : ""); + result->type = icwmp_strdup(tb[2] ? blobmsg_get_string(tb[2]) : ""); break; } } @@ -240,7 +240,7 @@ char *cwmp_get_single_parameter_value(char *parameter_name, struct cwmp_dm_param e = cwmp_ubus_call("usp.raw", "get", CWMP_UBUS_ARGS{ { "path", {.str_val = !parameter_name || parameter_name[0] == '\0' ? DM_ROOT_OBJ : parameter_name }, UBUS_String }, { "proto", {.str_val = "cwmp" }, UBUS_String } }, 2, ubus_get_single_parameter_callback, dm_parameter); if (e < 0) { CWMP_LOG(INFO, "get ubus method failed: Ubus err code: %d", e); - return strdup("9002"); + return "9002"; } if (dm_parameter->name == NULL) { @@ -274,11 +274,13 @@ char *cwmp_get_parameter_values(char *parameter_name, struct list_head *paramete e = cwmp_ubus_call("usp.raw", "get", CWMP_UBUS_ARGS{ { "path", {.str_val = !parameter_name || parameter_name[0] == '\0' ? DM_ROOT_OBJ : parameter_name }, UBUS_String }, { "proto", {.str_val = "cwmp" }, UBUS_String } }, 2, ubus_get_parameter_callback, &get_result); if (e < 0) { CWMP_LOG(INFO, "get ubus method failed: Ubus err code: %d", e); - return strdup("9002"); + return "9002"; } - if (get_result.type == FAULT) - return strdup(get_result.fault); + if (get_result.type == FAULT) { + CWMP_LOG(INFO, "Get parameter_values failed: fault_code: %s", get_result.fault); + return icwmp_strdup(get_result.fault); + } return NULL; } @@ -289,12 +291,12 @@ char *cwmp_get_parameter_names(char *object_name, bool next_level, struct list_h e = cwmp_ubus_call("usp.raw", "object_names", CWMP_UBUS_ARGS{ { "path", {.str_val = object_name }, UBUS_String }, { "next-level", {.bool_val = next_level }, UBUS_Bool }, { "proto", {.str_val = "cwmp" }, UBUS_String } }, 3, ubus_get_parameter_callback, &get_result); if (e < 0) { CWMP_LOG(INFO, "object_names ubus method failed: Ubus err code: %d", e); - return strdup("9002"); + return "9002"; } if (get_result.type == FAULT) { - CWMP_LOG(INFO, "Get parameter_values failed: fault_code: %s", get_result.fault); - return strdup(get_result.fault); + CWMP_LOG(INFO, "GetParameterNames failed: fault_code: %s", get_result.fault); + return icwmp_strdup(get_result.fault); } return NULL; @@ -394,11 +396,11 @@ char *cwmp_add_object(char *object_name, char *key, char **instance) if (e < 0) { CWMP_LOG(INFO, "add_object ubus method failed: Ubus err code: %d", e); - return strdup("9002"); + return "9002"; } if (add_result.status == false) { CWMP_LOG(INFO, "AddObject failed"); - return strdup(add_result.fault); + return icwmp_strdup(add_result.fault); } return NULL; } @@ -411,12 +413,12 @@ char *cwmp_delete_object(char *object_name, char *key) ubus_objects_callback, &add_result); if (e < 0) { CWMP_LOG(INFO, "del_object ubus method failed: Ubus err code: %d", e); - return strdup("9002"); + return "9002"; } if (add_result.status == false) { CWMP_LOG(INFO, "DeleteObject failed"); - return strdup(add_result.fault); + return icwmp_strdup(add_result.fault); } return NULL; @@ -450,12 +452,12 @@ char *cwmp_get_parameter_attributes(char *parameter_name, struct list_head *para ubus_parameter_attributes_callback, &get_result); if (e < 0) { CWMP_LOG(INFO, "getm_attributes ubus method failed: Ubus err code: %d", e); - return strdup("9002"); + return "9002"; } if (get_result.type == FAULT) { CWMP_LOG(INFO, "GetParameterAttributes failed"); - return strdup(get_result.fault); + return icwmp_strdup(get_result.fault); } return NULL; @@ -471,12 +473,12 @@ char *cwmp_set_parameter_attributes(char *parameter_name, char *notification) 3, ubus_parameter_attributes_callback, &set_result); if (e < 0) { CWMP_LOG(INFO, "setm_attributes ubus method failed: Ubus err code: %d", e); - return strdup("9002"); + return "9002"; } if (set_result.type == FAULT) { CWMP_LOG(INFO, "SetParameterAttributes failed"); - return strdup(set_result.fault); + return icwmp_strdup(set_result.fault); } return NULL; diff --git a/download.c b/download.c index 71631a3..e541c3f 100644 --- a/download.c +++ b/download.c @@ -40,12 +40,12 @@ int download_file(const char *file_path, const char *url, const char *username, int res_code = 0; CURL *curl = curl_easy_init(); if (curl) { - char *userpass = NULL; + char userpass[1024]; curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L); if (username != NULL && strlen(username) > 0) { - cwmp_asprintf(&userpass, "%s:%s", username, password); + snprintf(userpass, sizeof(userpass), "%s:%s", username, password); curl_easy_setopt(curl, CURLOPT_USERPWD, userpass); } if (strncmp(url, "https://", 8) == 0) @@ -64,7 +64,6 @@ int download_file(const char *file_path, const char *url, const char *username, curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res_code); curl_easy_cleanup(curl); - FREE(userpass); } return res_code; diff --git a/event.c b/event.c index e62977c..550b1c3 100644 --- a/event.c +++ b/event.c @@ -438,8 +438,8 @@ void connection_request_ip_value_change(struct cwmp *cwmp, int version) { char *bip = NULL; struct event_container *event_container; - char *ip_version = (version == IPv6) ? strdup("ipv6") : strdup("ip"); - char *ip_value = (version == IPv6) ? strdup(cwmp->conf.ipv6) : strdup(cwmp->conf.ip); + char *ip_version = (version == IPv6) ? "ipv6" : "ip"; + char *ip_value = (version == IPv6) ? cwmp->conf.ipv6 : cwmp->conf.ip; if (version == IPv6) cwmp_load_saved_session(cwmp, &bip, CR_IPv6); @@ -449,8 +449,6 @@ void connection_request_ip_value_change(struct cwmp *cwmp, int version) if (bip == NULL) { bkp_session_simple_insert_in_parent("connection_request", ip_version, ip_value); bkp_session_save(); - FREE(ip_version); - FREE(ip_value); return; } if (strcmp(bip, ip_value) != 0) { @@ -459,8 +457,6 @@ void connection_request_ip_value_change(struct cwmp *cwmp, int version) if (event_container == NULL) { FREE(bip); pthread_mutex_unlock(&(cwmp->mutex_session_queue)); - FREE(ip_version); - FREE(ip_value); return; } cwmp_save_event_container(event_container); @@ -470,8 +466,6 @@ void connection_request_ip_value_change(struct cwmp *cwmp, int version) pthread_cond_signal(&(cwmp->threshold_session_send)); } FREE(bip); - FREE(ip_version); - FREE(ip_value); } void connection_request_port_value_change(struct cwmp *cwmp, int port) diff --git a/http.c b/http.c index 6e5a3a5..3d91e25 100644 --- a/http.c +++ b/http.c @@ -49,19 +49,19 @@ int http_client_init(struct cwmp *cwmp) if (dhcp_dis && cwmp->retry_count_session > 0 && strcmp(dhcp_dis, "enable") == 0) { uci_get_state_value(UCI_DHCP_ACS_URL, &acs_var_stat); if (acs_var_stat) { - if (cwmp_asprintf(&http_c.url, "%s", acs_var_stat) == -1) { + if (icwmp_asprintf(&http_c.url, "%s", acs_var_stat) == -1) { free(acs_var_stat); free(dhcp_dis); return -1; } } else { - if (cwmp_asprintf(&http_c.url, "%s", cwmp->conf.acsurl) == -1) { + if (icwmp_asprintf(&http_c.url, "%s", cwmp->conf.acsurl) == -1) { free(dhcp_dis); return -1; } } } else { - if (cwmp_asprintf(&http_c.url, "%s", cwmp->conf.acsurl) == -1) { + if (icwmp_asprintf(&http_c.url, "%s", cwmp->conf.acsurl) == -1) { if (dhcp_dis) free(dhcp_dis); return -1; @@ -96,7 +96,7 @@ int http_client_init(struct cwmp *cwmp) void http_client_exit(void) { - FREE(http_c.url); + icwmp_free(http_c.url); if (http_c.header_list) { curl_slist_free_all(http_c.header_list); @@ -231,7 +231,6 @@ int http_send_message(struct cwmp *cwmp, char *msg_out, int msg_out_len, char ** char *zone_name = NULL; get_firewall_zone_name_by_wan_iface(cwmp->conf.default_wan_iface, &zone_name); update_firewall_cwmp_file(cwmp->conf.connection_request_port, zone_name ? zone_name : "wan", ip_acs, tmp); - FREE(zone_name); /* * Restart firewall service @@ -290,7 +289,7 @@ static void http_cr_new_client(int client, bool service_available) int8_t auth_status = 0; bool auth_digest_checked = false; bool method_is_get = false; - char *cr_http_get_head = NULL; + char cr_http_get_head[512]; pthread_mutex_lock(&mutex_config_load); fp = fdopen(client, "r+"); @@ -302,7 +301,7 @@ static void http_cr_new_client(int client, bool service_available) service_available = false; goto http_end; } - cwmp_asprintf(&cr_http_get_head, "GET %s HTTP/1.1", cwmp_main.conf.connection_request_path); + snprintf(cr_http_get_head, sizeof(cr_http_get_head), "GET %s HTTP/1.1", cwmp_main.conf.connection_request_path); while (fgets(buffer, sizeof(buffer), fp)) { if (!strncasecmp(buffer, cr_http_get_head, strlen(cr_http_get_head))) method_is_get = true; @@ -324,7 +323,6 @@ static void http_cr_new_client(int client, bool service_available) else auth_status = 0; http_end: - FREE(cr_http_get_head); if (!service_available || !method_is_get) { CWMP_LOG(INFO, "Receive Connection Request: Return 503 Service Unavailable"); fputs("HTTP/1.1 503 Service Unavailable\r\n", fp); diff --git a/inc/common.h b/inc/common.h index b4a6b52..ae2956d 100644 --- a/inc/common.h +++ b/inc/common.h @@ -486,7 +486,6 @@ void cwmp_factory_reset(); void get_firewall_zone_name_by_wan_iface(char *if_wan, char **zone_name); int update_firewall_cwmp_file(int port, char *zone_name, char *ip_addr, int ip_type); int download_file(const char *file_path, const char *url, const char *username, const char *password); -int upload_file(const char *file_path, const char *url, const char *username, const char *password); long int get_file_size(char *file_name); int cwmp_check_image(); void cwmp_apply_firmware(); @@ -496,6 +495,13 @@ int icwmp_rand(void); void icwmp_srand(unsigned int seed); int cwmp_get_fault_code(int fault_code); int cwmp_get_fault_code_by_string(char *fault_code); +void *icwmp_malloc(size_t size); +void *icwmp_calloc(int n, size_t size); +void *icwmp_realloc(void *n, size_t size); +char *icwmp_strdup(const char *s); +int icwmp_asprintf(char **s, const char *format, ...); +void icwmp_free(void *m); +void icwmp_cleanmem(); #ifndef FREE #define FREE(x) \ do { \ diff --git a/netlink.c b/netlink.c index ab3873a..ce55f0f 100644 --- a/netlink.c +++ b/netlink.c @@ -118,8 +118,7 @@ static void freecwmp_netlink_interface(struct nlmsghdr *nlh) inet_ntop(AF_INET, &(addr), if_addr, INET_ADDRSTRLEN); - if (cwmp_main.conf.ip) - FREE(cwmp_main.conf.ip); + FREE(cwmp_main.conf.ip); cwmp_main.conf.ip = strdup(if_addr); uci_set_value(UCI_CPE_IP, cwmp_main.conf.ip, CWMP_CMD_SET_STATE); connection_request_ip_value_change(&cwmp_main, IPv4); @@ -137,8 +136,8 @@ static void freecwmp_netlink_interface(struct nlmsghdr *nlh) rth = RTA_NEXT(rth, rtl); continue; } - if (cwmp_main.conf.ipv6) - FREE(cwmp_main.conf.ipv6); + + FREE(cwmp_main.conf.ipv6); cwmp_main.conf.ipv6 = strdup(pradd_v6); uci_set_value(UCI_CPE_IPV6, cwmp_main.conf.ipv6, CWMP_CMD_SET_STATE); connection_request_ip_value_change(&cwmp_main, IPv6); diff --git a/notifications.c b/notifications.c index e3f7124..63ba163 100644 --- a/notifications.c +++ b/notifications.c @@ -47,10 +47,9 @@ void cwmp_update_enabled_notify_file_callback(struct ubus_request *req, int type blobmsg_parse(p, 4, tb, blobmsg_data(cur), blobmsg_len(cur)); if (!tb[0]) continue; - char *notif_line = NULL; - cwmp_asprintf(¬if_line, "parameter:%s notifcation:%s type:%s value:%s", blobmsg_get_string(tb[0]), tb[3] ? blobmsg_get_string(tb[3]) : "", tb[2] ? blobmsg_get_string(tb[2]) : "", tb[1] ? blobmsg_get_string(tb[1]) : ""); + char notif_line[1024]; + snprintf(notif_line, sizeof(notif_line), "parameter:%s notifcation:%s type:%s value:%s", blobmsg_get_string(tb[0]), tb[3] ? blobmsg_get_string(tb[3]) : "", tb[2] ? blobmsg_get_string(tb[2]) : "", tb[1] ? blobmsg_get_string(tb[1]) : ""); fprintf(fp, "%s\n", notif_line); - FREE(notif_line); } fclose(fp); } @@ -213,13 +212,12 @@ static void udplw_server_param(struct addrinfo **res) struct addrinfo hints = { 0 }; struct cwmp *cwmp = &cwmp_main; struct config *conf; - char *port; + char port[32]; conf = &(cwmp->conf); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; - cwmp_asprintf(&port, "%d", conf->lw_notification_port); + snprintf(port, sizeof(port), "%d", conf->lw_notification_port); getaddrinfo(conf->lw_notification_hostname, port, &hints, res); - //FREE(port); } static void message_compute_signature(char *msg_out, char *signature) @@ -283,7 +281,7 @@ static void free_all_list_lw_notify() void cwmp_lwnotification() { - char *msg, *msg_out; + char msg[1024], *msg_out; char signature[41]; struct addrinfo *servaddr; struct cwmp *cwmp = &cwmp_main; @@ -293,11 +291,10 @@ void cwmp_lwnotification() udplw_server_param(&servaddr); xml_prepare_lwnotification_message(&msg_out); message_compute_signature(msg_out, signature); - cwmp_asprintf(&msg, "%s \n %s: %s \n %s: %s \n %s: %zd\n %s: %s\n\n%s", "POST /HTTPS/1.1", "HOST", conf->lw_notification_hostname, "Content-Type", "test/xml; charset=utf-8", "Content-Lenght", strlen(msg_out), "Signature", signature, msg_out); + snprintf(msg, sizeof(msg), "%s \n %s: %s \n %s: %s \n %s: %zd\n %s: %s\n\n%s", "POST /HTTPS/1.1", "HOST", conf->lw_notification_hostname, "Content-Type", "test/xml; charset=utf-8", "Content-Lenght", strlen(msg_out), "Signature", signature, msg_out); send_udp_message(servaddr, msg); free_all_list_lw_notify(); //freeaddrinfo(servaddr); //To check - FREE(msg); FREE(msg_out); } diff --git a/test/cmocka/unit_test_icwmp.c b/test/cmocka/unit_test_icwmp.c index 760ad33..8a1d4a9 100755 --- a/test/cmocka/unit_test_icwmp.c +++ b/test/cmocka/unit_test_icwmp.c @@ -46,7 +46,6 @@ void dm_get_parameter_values_test(void **state) break; } cwmp_free_all_dm_parameter_list(¶meters_list); - FREE(fault); /* * Test of non valid parameter path @@ -55,7 +54,6 @@ void dm_get_parameter_values_test(void **state) assert_non_null(fault); assert_string_equal(fault, "9005"); cwmp_free_all_dm_parameter_list(¶meters_list); - FREE(fault); /* * Test of valid multi-instance_object_path @@ -63,7 +61,6 @@ void dm_get_parameter_values_test(void **state) fault = cwmp_get_parameter_values("Device.WiFi.SSID.", ¶meters_list); assert_null(fault); cwmp_free_all_dm_parameter_list(¶meters_list); - FREE(fault); /* * Test of valid not multi-instance_object_path @@ -71,7 +68,6 @@ void dm_get_parameter_values_test(void **state) fault = cwmp_get_parameter_values("Device.DeviceInfo.", ¶meters_list); assert_null(fault); cwmp_free_all_dm_parameter_list(¶meters_list); - FREE(fault); /* * Test of non valid object path @@ -80,7 +76,6 @@ void dm_get_parameter_values_test(void **state) assert_non_null(fault); assert_string_equal(fault, "9005"); cwmp_free_all_dm_parameter_list(¶meters_list); - FREE(fault); } void dm_set_multiple_parameter_values_test(void **state) @@ -230,7 +225,6 @@ void dm_add_object_test(void **state) assert_non_null(instance); assert_null(fault); cwmp_transaction_commit(); - FREE(fault); FREE(instance); /* @@ -242,7 +236,6 @@ void dm_add_object_test(void **state) assert_string_equal(fault, "9005"); assert_null(instance); cwmp_transaction_commit(); - FREE(fault); FREE(instance); /* @@ -254,7 +247,6 @@ void dm_add_object_test(void **state) assert_string_equal(fault, "9005"); assert_null(instance); cwmp_transaction_commit(); - FREE(fault); FREE(instance); } @@ -269,7 +261,6 @@ void dm_delete_object_test(void **state) fault = cwmp_delete_object("Device.WiFi.SSID.2.", "del_ssid"); assert_null(fault); cwmp_transaction_commit(); - FREE(fault); /* * Delete not valid path object @@ -279,7 +270,6 @@ void dm_delete_object_test(void **state) assert_non_null(fault); assert_string_equal(fault, "9005"); cwmp_transaction_commit(); - FREE(fault); /* * Delte valid path not writable object @@ -289,7 +279,6 @@ void dm_delete_object_test(void **state) assert_non_null(fault); assert_string_equal(fault, "9005"); cwmp_transaction_commit(); - FREE(fault); } void dm_get_parameter_names_test(void **state) @@ -309,7 +298,6 @@ void dm_get_parameter_names_test(void **state) } assert_int_not_equal(nbre_objs, 0); cwmp_free_all_dm_parameter_list(¶meters_list); - FREE(fault); nbre_objs = 0; /* @@ -322,7 +310,6 @@ void dm_get_parameter_names_test(void **state) } assert_int_not_equal(nbre_objs, 0); cwmp_free_all_dm_parameter_list(¶meters_list); - FREE(fault); nbre_objs = 0; /* @@ -331,7 +318,6 @@ void dm_get_parameter_names_test(void **state) fault = cwmp_get_parameter_names("Device.Devicenfo.", true, ¶meters_list); assert_non_null(fault); assert_string_equal(fault, "9005"); - FREE(fault); } void dm_set_parameter_attributes_test(void **state) @@ -380,7 +366,6 @@ void dm_get_parameter_attributes_test(void **state) break; } cwmp_free_all_dm_parameter_list(¶meters_list); - FREE(fault); /* * Test of non valid parameter path @@ -389,7 +374,6 @@ void dm_get_parameter_attributes_test(void **state) assert_non_null(fault); assert_string_equal(fault, "9005"); cwmp_free_all_dm_parameter_list(¶meters_list); - FREE(fault); /* * Test of valid multi-instance_object_path @@ -397,7 +381,6 @@ void dm_get_parameter_attributes_test(void **state) fault = cwmp_get_parameter_attributes("Device.WiFi.SSID.", ¶meters_list); assert_null(fault); cwmp_free_all_dm_parameter_list(¶meters_list); - FREE(fault); /* * Test of valid not multi-instance_object_path @@ -405,7 +388,6 @@ void dm_get_parameter_attributes_test(void **state) fault = cwmp_get_parameter_attributes("Device.DeviceInfo.", ¶meters_list); assert_null(fault); cwmp_free_all_dm_parameter_list(¶meters_list); - FREE(fault); /* * Test of non valid object path @@ -414,7 +396,6 @@ void dm_get_parameter_attributes_test(void **state) assert_non_null(fault); assert_string_equal(fault, "9005"); cwmp_free_all_dm_parameter_list(¶meters_list); - FREE(fault); } /* @@ -505,5 +486,7 @@ int main(void) cmocka_unit_test(soap_inform_message_test), }; - return cmocka_run_group_tests(tests, NULL, NULL); + int ret = cmocka_run_group_tests(tests, NULL, NULL); + icwmp_cleanmem(); + return ret; } diff --git a/ubus.c b/ubus.c index f1c5018..5d6a865 100755 --- a/ubus.c +++ b/ubus.c @@ -63,13 +63,13 @@ static int cwmp_handle_command(struct ubus_context *ctx, struct ubus_object *obj blob_buf_init(&b, 0); char *cmd = blobmsg_data(tb[COMMAND_NAME]); - char *info; + char info[128]; if (!strcmp("reload_end_session", cmd)) { CWMP_LOG(INFO, "triggered ubus reload_end_session"); cwmp_set_end_session(END_SESSION_RELOAD); blobmsg_add_u32(&b, "status", 0); - if (cwmp_asprintf(&info, "icwmpd config will reload at the end of the session") == -1) + if (snprintf(info, sizeof(info), "icwmpd config will reload at the end of the session") == -1) return -1; } else if (!strcmp("reload", cmd)) { CWMP_LOG(INFO, "triggered ubus reload"); @@ -82,20 +82,20 @@ static int cwmp_handle_command(struct ubus_context *ctx, struct ubus_object *obj cwmp_apply_acs_changes(); pthread_mutex_unlock(&(cwmp_main.mutex_session_queue)); blobmsg_add_u32(&b, "status", 0); - if (cwmp_asprintf(&info, "icwmpd config reloaded") == -1) + if (snprintf(info, sizeof(info), "icwmpd config reloaded") == -1) return -1; } } else if (!strcmp("reboot_end_session", cmd)) { CWMP_LOG(INFO, "triggered ubus reboot_end_session"); cwmp_set_end_session(END_SESSION_REBOOT); blobmsg_add_u32(&b, "status", 0); - if (cwmp_asprintf(&info, "icwmpd will reboot at the end of the session") == -1) + if (snprintf(info, sizeof(info), "icwmpd will reboot at the end of the session") == -1) return -1; } else if (!strcmp("action_end_session", cmd)) { CWMP_LOG(INFO, "triggered ubus action_end_session"); cwmp_set_end_session(END_SESSION_EXTERNAL_ACTION); blobmsg_add_u32(&b, "status", 0); - if (cwmp_asprintf(&info, "icwmpd will execute the scheduled action commands at the end of the session") == -1) + if (snprintf(info, sizeof(info), "icwmpd will execute the scheduled action commands at the end of the session") == -1) return -1; } else if (!strcmp("exit", cmd)) { pthread_t exit_thread; @@ -109,10 +109,9 @@ static int cwmp_handle_command(struct ubus_context *ctx, struct ubus_object *obj CWMP_LOG(ERROR, "%s", piderr); } blobmsg_add_u32(&b, "status", 0); - if (cwmp_asprintf(&info, "icwmpd daemon stopped") == -1) + if (snprintf(info, sizeof(info), "icwmpd daemon stopped") == -1) return -1; blobmsg_add_string(&b, "info", info); - free(info); ubus_send_reply(ctx, req, b.head); @@ -129,12 +128,11 @@ static int cwmp_handle_command(struct ubus_context *ctx, struct ubus_object *obj } else { blobmsg_add_u32(&b, "status", -1); - if (cwmp_asprintf(&info, "%s command is not supported", cmd) == -1) + if (snprintf(info, sizeof(info), "%s command is not supported", cmd) == -1) return -1; } blobmsg_add_string(&b, "info", info); - free(info); ubus_send_reply(ctx, req, b.head); diff --git a/upload.c b/upload.c index 7e52f8f..dc60853 100644 --- a/upload.c +++ b/upload.c @@ -9,6 +9,7 @@ */ #include +#include #include "common.h" #include "upload.h" @@ -20,6 +21,8 @@ #include "cwmp_uci.h" #include "event.h" +#define CURL_TIMEOUT 20 + LIST_HEAD(list_upload); pthread_cond_t threshold_upload; @@ -27,15 +30,12 @@ pthread_mutex_t mutex_upload = PTHREAD_MUTEX_INITIALIZER; int lookup_vcf_name(char *instance, char **value) { - char *vcf_name_parameter = NULL; + char vcf_name_parameter[256]; char *err = NULL; LIST_HEAD(vcf_parameters); - cwmp_asprintf(&vcf_name_parameter, "Device.DeviceInfo.VendorConfigFile.%s.Name", instance); - if ((err = cwmp_get_parameter_values(vcf_name_parameter, &vcf_parameters)) != NULL) { - FREE(vcf_name_parameter); - FREE(err); + snprintf(vcf_name_parameter, sizeof(vcf_name_parameter), "Device.DeviceInfo.VendorConfigFile.%s.Name", instance); + if ((err = cwmp_get_parameter_values(vcf_name_parameter, &vcf_parameters)) != NULL) return -1; - } struct cwmp_dm_parameter *param_value = NULL; list_for_each_entry (param_value, &vcf_parameters, list) { *value = strdup(param_value->value); @@ -47,15 +47,12 @@ int lookup_vcf_name(char *instance, char **value) int lookup_vlf_name(char *instance, char **value) { - char *vlf_name_parameter = NULL; + char vlf_name_parameter[256]; char *err = NULL; LIST_HEAD(vlf_parameters); - cwmp_asprintf(&vlf_name_parameter, "Device.DeviceInfo.VendorLogFile.%s.Name", instance); - if ((err = cwmp_get_parameter_values(vlf_name_parameter, &vlf_parameters)) != NULL) { - FREE(vlf_name_parameter); - FREE(err); + snprintf(vlf_name_parameter, sizeof(vlf_name_parameter), "Device.DeviceInfo.VendorLogFile.%s.Name", instance); + if ((err = cwmp_get_parameter_values(vlf_name_parameter, &vlf_parameters)) != NULL) return -1; - } struct cwmp_dm_parameter *param_value = NULL; list_for_each_entry (param_value, &vlf_parameters, list) { *value = strdup(param_value->value); @@ -65,6 +62,36 @@ int lookup_vlf_name(char *instance, char **value) return 0; } +int upload_file(const char *file_path, const char *url, const char *username, const char *password) +{ + int res_code = 0; + + CURL *curl = curl_easy_init(); + if (curl) { + char userpass[256]; + + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY); + snprintf(userpass, sizeof(userpass), "%s:%s", username, password); + curl_easy_setopt(curl, CURLOPT_USERPWD, userpass); + + curl_easy_setopt(curl, CURLOPT_TIMEOUT, CURL_TIMEOUT); + curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); + + FILE *fp = fopen(file_path, "rb"); + if (fp) { + curl_easy_setopt(curl, CURLOPT_READDATA, fp); + curl_easy_perform(curl); + fclose(fp); + } + + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &res_code); + curl_easy_cleanup(curl); + } + + return res_code; +} + int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptransfer_complete) { int error = FAULT_CPE_NO_FAULT; @@ -72,7 +99,7 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans struct transfer_complete *p; char *name = ""; upload_startTime = mix_get_time(); - char *file_path = NULL; + char file_path[128]; bkp_session_delete_upload(pupload); bkp_session_save(); @@ -80,7 +107,7 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans if (pupload->f_instance && isdigit(pupload->f_instance[0])) { lookup_vcf_name(pupload->f_instance, &name); if (name && strlen(name) > 0) { - cwmp_asprintf(&file_path, "/tmp/%s", name); + snprintf(file_path, sizeof(file_path), "/tmp/%s", name); cwmp_uci_export_package(name, file_path); FREE(name); } else { @@ -88,14 +115,14 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans goto end_upload; } } else { - file_path = strdup("/tmp/all_configs"); + snprintf(file_path, sizeof(file_path), "/tmp/all_configs"); cwmp_uci_export(file_path); } } else { if (pupload->f_instance && isdigit(pupload->f_instance[0])) { lookup_vlf_name(pupload->f_instance, &name); if (name && strlen(name) > 0) { - cwmp_asprintf(&file_path, "/tmp/%s", name); + snprintf(file_path, sizeof(file_path), "/tmp/%s", name); copy(name, file_path); FREE(name); } else @@ -104,7 +131,7 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans } else error = FAULT_CPE_UPLOAD_FAILURE; } - if (error != FAULT_CPE_NO_FAULT || file_path == NULL || strlen(file_path) <= 0) { + if (error != FAULT_CPE_NO_FAULT || strlen(file_path) <= 0) { error = FAULT_CPE_UPLOAD_FAILURE; goto end_upload; } @@ -114,7 +141,6 @@ int cwmp_launch_upload(struct upload *pupload, struct transfer_complete **ptrans else error = FAULT_CPE_UPLOAD_FAILURE; remove(file_path); - FREE(file_path); end_upload: p = calloc(1, sizeof(struct transfer_complete)); diff --git a/xml.c b/xml.c index 0757699..ee4d754 100755 --- a/xml.c +++ b/xml.c @@ -162,7 +162,8 @@ void xml_exit(void) int xml_send_message(struct cwmp *cwmp, struct session *session, struct rpc *rpc) { - char *s, *c, *msg_out = NULL, *msg_in = NULL; + char *s, *msg_out = NULL, *msg_in = NULL; + char c[512]; int msg_out_len = 0, f, r = 0; mxml_node_t *b; @@ -218,20 +219,19 @@ int xml_send_message(struct cwmp *cwmp, struct session *session, struct rpc *rpc /* get NoMoreRequests or HolRequest*/ session->hold_request = false; - if (cwmp_asprintf(&c, "%s:%s", ns.cwmp, "NoMoreRequests") == -1) + + if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "NoMoreRequests") == -1) goto error; b = mxmlFindElement(session->tree_in, session->tree_in, c, NULL, NULL, MXML_DESCEND); - FREE(c); if (b) { b = mxmlWalkNext(b, session->tree_in, MXML_DESCEND_FIRST); if (b && b->type == MXML_OPAQUE && b->value.opaque) session->hold_request = atoi(b->value.opaque); } else { - if (cwmp_asprintf(&c, "%s:%s", ns.cwmp, "HoldRequests") == -1) + if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "HoldRequests") == -1) goto error; b = mxmlFindElement(session->tree_in, session->tree_in, c, NULL, NULL, MXML_DESCEND); - FREE(c); if (b) { b = mxmlWalkNext(b, session->tree_in, MXML_DESCEND_FIRST); if (b && b->type == MXML_OPAQUE && b->value.opaque) @@ -277,11 +277,11 @@ int xml_prepare_msg_out(struct session *session) int xml_set_cwmp_id(struct session *session) { - char *c; + char c[32]; mxml_node_t *b; /* define cwmp id */ - if (cwmp_asprintf(&c, "%u", ++(cwmp_main.cwmp_id)) == -1) + if (snprintf(c, sizeof(c), "%u", ++(cwmp_main.cwmp_id)) == -1) return -1; b = mxmlFindElement(session->tree_out, session->tree_out, "cwmp:ID", NULL, NULL, MXML_DESCEND); @@ -289,7 +289,6 @@ int xml_set_cwmp_id(struct session *session) return -1; b = mxmlNewOpaque(b, c); - FREE(c); if (!b) return -1; @@ -298,29 +297,27 @@ int xml_set_cwmp_id(struct session *session) int xml_set_cwmp_id_rpc_cpe(struct session *session) { - char *c; + char c[512]; mxml_node_t *b; /* handle cwmp:ID */ - if (cwmp_asprintf(&c, "%s:%s", ns.cwmp, "ID") == -1) + if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "ID") == -1) return -1; b = mxmlFindElement(session->tree_in, session->tree_in, c, NULL, NULL, MXML_DESCEND); - FREE(c); if (b) { /* ACS send ID parameter */ b = mxmlWalkNext(b, session->tree_in, MXML_DESCEND_FIRST); if (!b || b->type != MXML_OPAQUE || !b->value.opaque) return 0; - c = strdup(b->value.opaque); + snprintf(c, sizeof(c), "%s", b->value.opaque); b = mxmlFindElement(session->tree_out, session->tree_out, "cwmp:ID", NULL, NULL, MXML_DESCEND); if (!b) return -1; b = mxmlNewOpaque(b, c); - FREE(c); if (!b) return -1; } else { @@ -343,14 +340,13 @@ int xml_handle_message(struct session *session) /* get method */ - if (cwmp_asprintf(&c, "%s:%s", ns.soap_env, "Body") == -1) { + if (icwmp_asprintf(&c, "%s:%s", ns.soap_env, "Body") == -1) { CWMP_LOG(INFO, "Internal error"); session->fault_code = FAULT_CPE_INTERNAL_ERROR; goto fault; } b = mxmlFindElement(session->tree_in, session->tree_in, c, NULL, NULL, MXML_DESCEND); - FREE(c); if (!b) { CWMP_LOG(INFO, "Invalid received message"); @@ -451,7 +447,7 @@ const char *whitespace_cb(mxml_node_t *node, int where) static int xml_prepare_events_inform(struct session *session, mxml_node_t *tree) { mxml_node_t *node, *b1, *b2; - char *c = NULL; + char c[128]; int n = 0; struct list_head *ilist; struct event_container *event_container; @@ -483,11 +479,10 @@ static int xml_prepare_events_inform(struct session *session, mxml_node_t *tree) n++; } if (n) { - if (cwmp_asprintf(&c, "cwmp:EventStruct[%u]", n) == -1) + if (snprintf(c, sizeof(c), "cwmp:EventStruct[%u]", n) == -1) return -1; mxmlElementSetAttr(b1, "xsi:type", "soap_enc:Array"); mxmlElementSetAttr(b1, "soap_enc:arrayType", c); - free(c); } return 0; @@ -596,7 +591,7 @@ int xml_prepare_lwnotification_message(char **msg_out) if (cwmp_asprintf(&c, "%ld", time(NULL)) == -1) goto error; b = mxmlNewOpaque(b, c); - free(c); + FREE(c); if (!b) goto error; @@ -679,7 +674,7 @@ int cwmp_rpc_acs_prepare_message_inform(struct cwmp *cwmp, struct session *sessi struct cwmp_dm_parameter *dm_parameter; struct event_container *event_container; mxml_node_t *tree, *b, *node, *parameter_list; - char *c = NULL; + char c[256]; int size = 0; struct list_head *ilist, *jlist; @@ -787,23 +782,18 @@ int cwmp_rpc_acs_prepare_message_inform(struct cwmp *cwmp, struct session *sessi LIST_HEAD(list_inform); for (i = 0; i < inform_parameters_nbre; i++) { char *fault = cwmp_get_single_parameter_value(forced_inform_parameters[i], &cwmp_dm_param); - if (fault != NULL) { - FREE(fault); + if (fault != NULL) continue; - } if (xml_prepare_parameters_inform(&cwmp_dm_param, parameter_list, &size)) goto error; - FREE(cwmp_dm_param.name); - FREE(cwmp_dm_param.value); - FREE(cwmp_dm_param.type); } - if (cwmp_asprintf(&c, "cwmp:ParameterValueStruct[%d]", size) == -1) + + if (snprintf(c, sizeof(c), "cwmp:ParameterValueStruct[%d]", size) == -1) goto error; mxmlElementSetAttr(parameter_list, "xsi:type", "soap_enc:Array"); mxmlElementSetAttr(parameter_list, "soap_enc:arrayType", c); - free(c); session->tree_out = tree; return 0; @@ -1156,7 +1146,7 @@ int cwmp_handle_rpc_cpe_get_parameter_values(struct session *session, struct rpc char *parameter_name = NULL; int counter = 0, fault_code = FAULT_CPE_INTERNAL_ERROR; #ifdef ACS_MULTI - char *c = NULL; + char c[256]; #endif b = session->body_in; @@ -1188,7 +1178,6 @@ int cwmp_handle_rpc_cpe_get_parameter_values(struct session *session, struct rpc char *err = cwmp_get_parameter_values(parameter_name, ¶meters_list); if (err) { fault_code = cwmp_get_fault_code_by_string(err); - FREE(err); goto fault; } struct cwmp_dm_parameter *param_value = NULL; @@ -1231,11 +1220,10 @@ int cwmp_handle_rpc_cpe_get_parameter_values(struct session *session, struct rpc if (!b) goto fault; - if (cwmp_asprintf(&c, "cwmp:ParameterValueStruct[%d]", counter) == -1) + if (snprintf(c, sizeof(c), "cwmp:ParameterValueStruct[%d]", counter) == -1) goto fault; mxmlElementSetAttr(b, "soap_enc:arrayType", c); - FREE(c); #endif return 0; @@ -1261,7 +1249,7 @@ int cwmp_handle_rpc_cpe_get_parameter_names(struct session *session, struct rpc int counter = 0, fault_code = FAULT_CPE_INTERNAL_ERROR; LIST_HEAD(parameters_list); #ifdef ACS_MULTI - char *c = NULL; + char c[256]; #endif n = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Body", NULL, NULL, MXML_DESCEND); if (!n) @@ -1295,7 +1283,6 @@ int cwmp_handle_rpc_cpe_get_parameter_names(struct session *session, struct rpc char *err = cwmp_get_parameter_names(parameter_name, strcmp(NextLevel, "true") == 0 || strcmp(NextLevel, "1") == 0 ? true : false, ¶meters_list); if (err) { fault_code = cwmp_get_fault_code_by_string(err); - FREE(err); goto fault; } } @@ -1330,11 +1317,10 @@ int cwmp_handle_rpc_cpe_get_parameter_names(struct session *session, struct rpc if (!b) goto fault; - if (cwmp_asprintf(&c, "cwmp:ParameterInfoStruct[%d]", counter) == -1) + if (snprintf(c, sizeof(c), "cwmp:ParameterInfoStruct[%d]", counter) == -1) goto fault; mxmlElementSetAttr(b, "soap_enc:arrayType", c); - FREE(c); #endif return 0; @@ -1359,7 +1345,7 @@ int cwmp_handle_rpc_cpe_get_parameter_attributes(struct session *session, struct int counter = 0, fault_code = FAULT_CPE_INTERNAL_ERROR; LIST_HEAD(parameters_list); #ifdef ACS_MULTI - char *c = NULL; + char c[256]; #endif b = session->body_in; n = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Body", NULL, NULL, MXML_DESCEND); @@ -1389,7 +1375,6 @@ int cwmp_handle_rpc_cpe_get_parameter_attributes(struct session *session, struct char *err = cwmp_get_parameter_attributes(parameter_name, ¶meters_list); if (err) { fault_code = cwmp_get_fault_code_by_string(err); - FREE(err); goto fault; } struct cwmp_dm_parameter *param_value = NULL; @@ -1439,11 +1424,10 @@ int cwmp_handle_rpc_cpe_get_parameter_attributes(struct session *session, struct if (!b) goto fault; - if (cwmp_asprintf(&c, "cwmp:ParameterAttributeStruct[%d]", counter) == -1) + if (snprintf(c, sizeof(c), "cwmp:ParameterAttributeStruct[%d]", counter) == -1) goto fault; mxmlElementSetAttr(b, "soap_enc:arrayType", c); - FREE(c); #endif return 0; @@ -1493,40 +1477,35 @@ int cwmp_handle_rpc_cpe_set_parameter_values(struct session *session, struct rpc LIST_HEAD(list_set_param_value); while (b) { if (b && b->type == MXML_OPAQUE && b->value.opaque && b->parent->type == MXML_ELEMENT && !strcmp(b->parent->value.element.name, "Name")) { - parameter_name = strdup(b->value.opaque); + parameter_name = icwmp_strdup(b->value.opaque); if (is_duplicated_parameter(b, session)) { fault_code = FAULT_CPE_INVALID_ARGUMENTS; goto fault; } - FREE(parameter_value); } if (b && b->type == MXML_ELEMENT && !strcmp(b->value.element.name, "Name") && !b->child) { - parameter_name = strdup(""); + parameter_name = icwmp_strdup(""); } if (b && b->type == MXML_OPAQUE && b->value.opaque && b->parent->type == MXML_ELEMENT && !strcmp(b->parent->value.element.name, "Value")) { int whitespace = 0; - parameter_value = strdup((char *)mxmlGetOpaque(b)); + parameter_value = icwmp_strdup((char *)mxmlGetOpaque(b)); n = b->parent; while ((b = mxmlWalkNext(b, n, MXML_DESCEND))) { v = (char *)mxmlGetOpaque(b); if (!whitespace) break; - cwmp_asprintf(&c, "%s %s", parameter_value, v); - FREE(parameter_value); - parameter_value = strdup(c); - //FREE(c); + icwmp_asprintf(&c, "%s %s", parameter_value, v); + parameter_value = icwmp_strdup(c); } b = n->last_child; } if (b && b->type == MXML_ELEMENT && !strcmp(b->value.element.name, "Value") && !b->child) { - parameter_value = strdup(""); + parameter_value = icwmp_strdup(""); } if (parameter_name && parameter_value) { add_dm_parameter_to_list(&list_set_param_value, parameter_name, parameter_value, NULL, 0, false); - FREE(parameter_name); - FREE(parameter_value); } b = mxmlWalkNext(b, session->body_in, MXML_DESCEND); } @@ -1599,15 +1578,15 @@ error: int cwmp_handle_rpc_cpe_set_parameter_attributes(struct session *session, struct rpc *rpc) { mxml_node_t *n, *b = session->body_in; - char *c, *parameter_name = NULL, *parameter_notification = NULL; + char *parameter_name = NULL, *parameter_notification = NULL; int fault_code = FAULT_CPE_INTERNAL_ERROR; + char c[256]; /* handle cwmp:SetParameterAttributes */ - if (cwmp_asprintf(&c, "%s:%s", ns.cwmp, "SetParameterAttributes") == -1) + if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "SetParameterAttributes") == -1) goto fault; n = mxmlFindElement(session->tree_in, session->tree_in, c, NULL, NULL, MXML_DESCEND); - FREE(c); if (!n) goto fault; @@ -1646,7 +1625,6 @@ int cwmp_handle_rpc_cpe_set_parameter_attributes(struct session *session, struct char *err = cwmp_set_parameter_attributes(parameter_name, parameter_notification); if (err) { fault_code = cwmp_get_fault_code_by_string(err); - FREE(err); goto fault; } parameter_name = NULL; @@ -1716,7 +1694,6 @@ int cwmp_handle_rpc_cpe_add_object(struct session *session, struct rpc *rpc) char *err = cwmp_add_object(object_name, parameter_key ? parameter_key : "", &instance); if (err) { fault_code = cwmp_get_fault_code_by_string(err); - FREE(err); goto fault; } } else { @@ -1800,7 +1777,6 @@ int cwmp_handle_rpc_cpe_delete_object(struct session *session, struct rpc *rpc) char *err = cwmp_delete_object(object_name, parameter_key ? parameter_key : ""); if (err) { fault_code = cwmp_get_fault_code_by_string(err); - FREE(err); goto fault; } } else { @@ -1853,7 +1829,7 @@ int cwmp_handle_rpc_cpe_get_rpc_methods(struct session *session, struct rpc *rpc int i, counter = 0; #ifdef ACS_MULTI mxml_node_t *b = session->body_in; - char *c = NULL; + char c[128]; #endif n = mxmlFindElement(session->tree_out, session->tree_out, "soap_env:Body", NULL, NULL, MXML_DESCEND); @@ -1887,11 +1863,10 @@ int cwmp_handle_rpc_cpe_get_rpc_methods(struct session *session, struct rpc *rpc goto fault; mxmlElementSetAttr(b, "xsi:type", "soap_enc:Array"); - if (cwmp_asprintf(&c, "xsd:string[%d]", counter) == -1) + if (snprintf(c, sizeof(c), "xsd:string[%d]", counter) == -1) goto fault; mxmlElementSetAttr(b, "soap_enc:arrayType", c); - FREE(c); #endif return 0; @@ -2054,7 +2029,7 @@ int cwmp_handle_rpc_cpe_reboot(struct session *session, struct rpc *rpc) while (b) { if (b && b->type == MXML_OPAQUE && b->value.opaque && b->parent->type == MXML_ELEMENT && !strcmp(b->parent->value.element.name, "CommandKey")) { command_key = b->value.opaque; - commandKey = strdup(b->value.opaque); + commandKey = icwmp_strdup(b->value.opaque); } b = mxmlWalkNext(b, session->body_in, MXML_DESCEND); } @@ -2180,15 +2155,14 @@ int cwmp_handle_rpc_cpe_change_du_state(struct session *session, struct rpc *rpc struct change_du_state *change_du_state = NULL; struct operations *elem = NULL; int error = FAULT_CPE_NO_FAULT; - char *c; + char c[256]; - if (cwmp_asprintf(&c, "%s:%s", ns.cwmp, "ChangeDUState") == -1) { + if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "ChangeDUState") == -1) { error = FAULT_CPE_INTERNAL_ERROR; goto fault; } n = mxmlFindElement(session->tree_in, session->tree_in, c, NULL, NULL, MXML_DESCEND); - FREE(c); if (!n) return -1; @@ -2353,20 +2327,19 @@ int create_download_upload_response(mxml_node_t *tree_out, enum load_type ltype) int cwmp_handle_rpc_cpe_download(struct session *session, struct rpc *rpc) { mxml_node_t *n, *b = session->body_in; - char *c, *tmp, *file_type = NULL; + char c[256], *tmp, *file_type = NULL; int error = FAULT_CPE_NO_FAULT; struct download *download = NULL, *idownload; struct list_head *ilist; time_t scheduled_time = 0; time_t download_delay = 0; - if (cwmp_asprintf(&c, "%s:%s", ns.cwmp, "Download") == -1) { + if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "Download") == -1) { error = FAULT_CPE_INTERNAL_ERROR; goto fault; } n = mxmlFindElement(session->tree_in, session->tree_in, c, NULL, NULL, MXML_DESCEND); - FREE(c); if (!n) return -1; @@ -2477,20 +2450,19 @@ fault: int cwmp_handle_rpc_cpe_schedule_download(struct session *session, struct rpc *rpc) { mxml_node_t *n, *t, *b = session->body_in; - char *c, *tmp, *file_type = NULL; + char c[256], *tmp, *file_type = NULL; char *windowmode0 = NULL, *windowmode1 = NULL; int i = 0, j = 0; int error = FAULT_CPE_NO_FAULT; struct download *schedule_download = NULL; time_t schedule_download_delay[4] = { 0, 0, 0, 0 }; - if (cwmp_asprintf(&c, "%s:%s", ns.cwmp, "ScheduleDownload") == -1) { + if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "ScheduleDownload") == -1) { error = FAULT_CPE_INTERNAL_ERROR; goto fault; } n = mxmlFindElement(session->tree_in, session->tree_in, c, NULL, NULL, MXML_DESCEND); - FREE(c); if (!n) return -1; @@ -2514,7 +2486,6 @@ int cwmp_handle_rpc_cpe_schedule_download(struct session *session, struct rpc *r error = FAULT_CPE_INTERNAL_ERROR; goto fault; } - FREE(tmp); } else { schedule_download->file_type = strdup(b->value.opaque); file_type = strdup(b->value.opaque); @@ -2559,14 +2530,12 @@ int cwmp_handle_rpc_cpe_schedule_download(struct session *session, struct rpc *r error = FAULT_CPE_INTERNAL_ERROR; goto fault; } - FREE(tmp); } else if (i == 1) { tmp = windowmode1; if (cwmp_asprintf(&windowmode1, "%s %s", tmp, t->value.opaque) == -1) { error = FAULT_CPE_INTERNAL_ERROR; goto fault; } - FREE(tmp); } } @@ -2604,6 +2573,8 @@ int cwmp_handle_rpc_cpe_schedule_download(struct session *session, struct rpc *r } FREE(file_type); + FREE(windowmode0); + FREE(windowmode1); if (error != FAULT_CPE_NO_FAULT) goto fault; @@ -2655,20 +2626,21 @@ error: int cwmp_handle_rpc_cpe_upload(struct session *session, struct rpc *rpc) { mxml_node_t *n, *b = session->body_in; - char *c, *tmp, *file_type = NULL; + char *tmp, *file_type = NULL; int error = FAULT_CPE_NO_FAULT; struct upload *upload = NULL, *iupload; struct list_head *ilist; time_t scheduled_time = 0; time_t upload_delay = 0; + char c[256]; - if (cwmp_asprintf(&c, "%s:%s", ns.cwmp, "Upload") == -1) { + if (snprintf(c, sizeof(c), "%s:%s", ns.cwmp, "Upload") == -1) { error = FAULT_CPE_INTERNAL_ERROR; goto fault; } n = mxmlFindElement(session->tree_in, session->tree_in, c, NULL, NULL, MXML_DESCEND); - FREE(c); + if (!n) return -1; b = n; @@ -2696,7 +2668,6 @@ int cwmp_handle_rpc_cpe_upload(struct session *session, struct rpc *rpc) if (isdigit(b->value.opaque[0])) { upload->f_instance = strdup(b->value.opaque); } - FREE(tmp); } } if (b && b->type == MXML_OPAQUE && b->value.opaque && b->parent->type == MXML_ELEMENT && !strcmp(b->parent->value.element.name, "URL")) {