diff --git a/src/common.c b/src/common.c index 8e3d02aa3faa0abaf54aa277f0bfcf6fed2d2be7..0cf5f134d47618a0bd31dc7af9639de767083c8a 100644 --- a/src/common.c +++ b/src/common.c @@ -22,6 +22,7 @@ */ #include "common.h" +#include "strncpyt.h" #define GLOB_CHAR "[[+*]+" #define GLOB_EXPR "[=><]+" @@ -41,7 +42,6 @@ const char *DMT_TYPE[] = { }; static bool is_node_instance(char *path); -static bool is_leaf(char *path, char *); bool match(const char *string, const char *pattern); struct uci_context *uci_ctx = NULL; @@ -578,13 +578,19 @@ static bool leaf_same_group(char *path) { return false; } -static bool is_leaf(char *path, char *node) { +static bool is_leaf(char *path, char *node, size_t maxlen) { DEBUG("entry path|%s|", path); char *ret = NULL; - ret = strchr(path, DELIM); - if(ret != NULL) { - strncpy(node, path, strlen(path) - strlen(ret)+1); + ret = strchr(path, DELIM); + if (ret != NULL) { + size_t retlen = (size_t)(ret - path) + 1; + + if (retlen > maxlen) + retlen = maxlen; + + memcpy(node, path, retlen); + node[retlen] = 0; } return (ret==NULL); @@ -600,7 +606,7 @@ void process_result(struct blob_buf *bb, unsigned int len) { DEBUG("Entry node |%s|, len|%u|", rnode->name, len); if(leaf_same_group(rnode->name)) { - if(is_leaf(rnode->name+len, pn)) { + if(is_leaf(rnode->name+len, pn, sizeof(pn) - 1)) { //INFO("add leaf |%s|", rnode->name+len); add_data_blob(bb, rnode->name+len, rnode->value, rnode->type); } else { @@ -611,13 +617,13 @@ void process_result(struct blob_buf *bb, unsigned int len) { } else { push(); char temp[NAME_MAX] = {'\0'}; - strncpy(temp, rnode->name, len); - strncat(temp, pn, strlen(pn)); + memcpy(temp, rnode->name, len); + strncat(temp, pn, sizeof(temp) - 1); //INFO("Push1 |%s|, node|%s|", temp, pn); len = strlen(temp); char table_name[NAME_MAX]={'\0'}; - strncpy(table_name, pn, strlen(pn)-1); + strcpy(table_name, pn); if(is_node_instance(rnode->name + len)) { //INFO("Open table |%s|", table_name); @@ -641,7 +647,7 @@ void process_result(struct blob_buf *bb, unsigned int len) { //INFO("Closing table for |%s|", g_result[rtop].key); blobmsg_close_table(bb,g_result[rtop].cookie); } - if(is_leaf(rnode->name, pn)) { + if(is_leaf(rnode->name, pn, sizeof(pn) - 1)) { //INFO("add in blob|%s|, value|%s|, type|%s|", rnode->name, rnode->value, rnode->type); add_data_blob(bb, rnode->name, rnode->value, rnode->type); } else { @@ -656,7 +662,8 @@ void process_result(struct blob_buf *bb, unsigned int len) { len = strlen(pn); char table_name[NAME_MAX]={'\0'}; - strncpy(table_name, pn, len-1); + + memcpy(table_name, pn, len - 1); if(is_node_instance(rnode->name + len)) { //INFO("Open table |%s|", table_name); @@ -1006,11 +1013,11 @@ static void dereference_path(char *ref, char *l_op, char *r_op, char *op) { char path[NAME_MAX]={'\0'}; char ref_path[NAME_MAX]={'\0'}; char *node = NULL; - strncpy(path, p->ref_path, strlen(p->ref_path)+1); - strncat(path, ref, strlen(ref)); + strncpyt(path, p->ref_path, sizeof(path)); + strncat(path, ref, sizeof(path) - 1); node = bbf_get_value_by_id(path); - strncpy(ref_path, node, strlen(node)+1); - strncat(ref_path, l_op, strlen(l_op)); + strncpyt(ref_path, node, sizeof(ref_path)); + strncat(ref_path, l_op, sizeof(ref_path) - 1); DEBUG("de ref|%s|, path|%s|, node|%s|", ref_path, path, node); free(node); @@ -1077,8 +1084,8 @@ static void solve(char *exp) { pathnode *p=head; while(p!=NULL) { char name[NAME_MAX]={'\0'}; - strncpy(name, p->ref_path, strlen(p->ref_path)+1); - strncat(name, token, strlen(token)); + strncpyt(name, p->ref_path, sizeof(name)); + strncat(name, token, sizeof(name) - 1); if(bbf_get_name_exp(name, operator, operand)){ insert(strdup(p->ref_path), false); } @@ -1188,8 +1195,8 @@ void filter_results(char *path, size_t start, size_t end) { pathnode *p=head; while(p!=NULL) { char name[NAME_MAX]={'\0'}; - strncpy(name, p->ref_path, strlen(p->ref_path)+1); - strncat(name, pp, strlen(pp)); + strncpy(name, p->ref_path, sizeof(name)); + strncat(name, pp, sizeof(name) - 1); DEBUG("Final path[%s], ref |%s|", name, p->ref_path); insert(strdup(name), false); p = p->next; diff --git a/src/strncpyt.h b/src/strncpyt.h new file mode 100644 index 0000000000000000000000000000000000000000..77eca01d2049b9e200c8aa4e4c772500f2e3460f --- /dev/null +++ b/src/strncpyt.h @@ -0,0 +1,22 @@ +#ifndef STRNCPYT_H +#define STRNCPYT_H + +#include <string.h> + +/* glibc doesn't guarantee a 0 termianted string on strncpy + */ +#ifdef __GLIBC__ + +/* strncpy with always 0 terminated string + */ +static inline void strncpyt(char *dst, const char *src, size_t n) +{ + strncpy(dst, src, n - 1); + dst[n - 1] = 0; +} + +#else +#define strncpyt strncpy +#endif + +#endif diff --git a/src/usp.c b/src/usp.c index aadd4798f1dac535b6d0929247d7a8b2047b988d..f6b9db4ea91ffe5b3425494278fc4b85c1f46cec 100644 --- a/src/usp.c +++ b/src/usp.c @@ -41,6 +41,7 @@ #include "operate.h" #include "common.h" #include "add_delete.h" +#include "strncpyt.h" #define USP "usp" #define USP_GRA "usp." @@ -189,7 +190,6 @@ int usp_add_del_handler(struct ubus_context *ctx, struct ubus_object *obj, struct blob_buf bb = {}; size_t path_len; char *blob_msg = NULL; - size_t blog_msg_len=0; INFO("Entry method|%s| ubus name|%s|", method, obj->name); @@ -214,8 +214,7 @@ int usp_add_del_handler(struct ubus_context *ctx, struct ubus_object *obj, (char *)blobmsg_data(tb[DM_ADD_PATH])); } else { blob_msg = blobmsg_data(tb[DM_ADD_PATH]); - blog_msg_len = strlen(blob_msg)+1; - strncpy(path, blob_msg, blog_msg_len); + strncpyt(path, blob_msg, sizeof(path)); } path_len = strlen(path); @@ -252,7 +251,6 @@ int usp_get_handler(struct ubus_context *ctx, struct ubus_object *obj, char path[PATH_MAX]; struct blob_buf bb = {}; char *blob_msg = NULL; - size_t blog_msg_len=0; INFO("Entry method|%s| ubus name|%s|", method, obj->name); @@ -277,8 +275,7 @@ int usp_get_handler(struct ubus_context *ctx, struct ubus_object *obj, (char *)blobmsg_data(tb[DM_GET_PATH])); } else { blob_msg = blobmsg_data(tb[DM_GET_PATH]); - blog_msg_len = strlen(blob_msg)+1; - strncpy(path, blob_msg, blog_msg_len); + strncpyt(path, blob_msg, sizeof(path)); } filter_results(path, 0, strlen(path)); @@ -312,7 +309,6 @@ int usp_set(struct ubus_context *ctx, struct ubus_object *obj, struct blob_attr *tb[__DM_SET_MAX] = {NULL}; char path[PATH_MAX]={'\0'}, value[NAME_MAX]={'\0'}; char *blob_msg = NULL; - size_t blog_msg_len=0; void *array = NULL; if(blobmsg_parse(dm_set_policy, __DM_SET_MAX, tb, blob_data(msg), blob_len(msg))) { @@ -344,8 +340,7 @@ int usp_set(struct ubus_context *ctx, struct ubus_object *obj, (char *)blobmsg_data(tb[DM_SET_PATH])); } else { blob_msg = blobmsg_data(tb[DM_SET_PATH]); - blog_msg_len = strlen(blob_msg)+1; - strncpy(path, blob_msg, blog_msg_len); + strncpyt(path, blob_msg, sizeof(path)); } filter_results(path, 0, strlen(path)); @@ -354,8 +349,7 @@ int usp_set(struct ubus_context *ctx, struct ubus_object *obj, if (tb[DM_SET_VALUE]) { blob_msg = blobmsg_data(tb[DM_SET_VALUE]); - blog_msg_len = strlen(blob_msg)+1; - strncpy(value, blob_msg, blog_msg_len); + strncpyt(value, blob_msg, sizeof(value)); create_set_response(&bb, value); } if(tb[DM_SET_VALUE_TABLE]) { @@ -388,7 +382,6 @@ int usp_operate(struct ubus_context *ctx, struct ubus_object *obj, char cmd[NAME_MAX]={'\0'}; INFO("Entry method|%s| ubus name|%s|", method, obj->name); char *blob_msg = NULL; - size_t blog_msg_len=0; if(blobmsg_parse(dm_operate_policy, __DM_OPERATE_MAX, tb, blob_data(msg), blob_len(msg))) { ERR("Failed to parse blob"); @@ -417,12 +410,10 @@ int usp_operate(struct ubus_context *ctx, struct ubus_object *obj, (char *)blobmsg_data(tb[DM_OPERATE_PATH])); } else { blob_msg = blobmsg_data(tb[DM_OPERATE_PATH]); - blog_msg_len = strlen(blob_msg)+1; - strncpy(path, blob_msg, blog_msg_len); + strncpyt(path, blob_msg, sizeof(path)); } blob_msg = blobmsg_data(tb[DM_OPERATE_ACTION]); - blog_msg_len = strlen(blob_msg)+1; - strncpy(cmd, blob_msg, blog_msg_len); + strncpyt(cmd, blob_msg, sizeof(cmd)); filter_results(path, 0, strlen(path)); @@ -507,7 +498,7 @@ static void add_granular_objects(struct ubus_context *ctx, int gn_level) p = head; while(p!=NULL) { char obj_path[MAXNAMLEN]=USP_GRA; - strncat(obj_path,p->ref_path,strlen(p->ref_path)); + strncat(obj_path,p->ref_path,sizeof(obj_path) - 1); size_t len = strlen(obj_path); if (obj_path[len-1] == DELIM)