From 0334a23918ebb008f81694e855141b8d8f5f72a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Neira=20Ayuso?= Date: Wed, 14 Aug 2013 12:19:19 +0200 Subject: json: fixed some leaks in the json parsing function This patch fixes some leaks in the json parsing function. After this patch, we use nft_jansson_free_root. This function uses json_decref and it decrements the reference count and it releases the node if needed. Signed-off-by: Alvaro Neira Ayuso Signed-off-by: Pablo Neira Ayuso --- src/chain.c | 20 ++++++++++++-------- src/internal.h | 4 +++- src/jansson.c | 21 +++++++++++++++++---- src/table.c | 16 ++++++++++------ 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/src/chain.c b/src/chain.c index da0299f..ac6e7ad 100644 --- a/src/chain.c +++ b/src/chain.c @@ -482,14 +482,18 @@ static inline int nft_str2hooknum(const char *hook) static int nft_chain_json_parse(struct nft_chain *c, char *json) { #ifdef JSON_PARSING - json_t *root; + json_t *root, *node; json_error_t error; uint64_t uval64; uint32_t policy; int32_t val32; const char *valstr; - root = nft_jansson_get_root(json, "chain", &error); + node = nft_jansson_create_root(json, &error); + if (node == NULL) + return -1; + + root = nft_jansson_get_node(node, "chain"); if (root == NULL) return -1; @@ -497,7 +501,7 @@ static int nft_chain_json_parse(struct nft_chain *c, char *json) if (valstr == NULL) goto err; - nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_NAME, strdup(valstr)); + nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_NAME, valstr); if (nft_jansson_value_parse_val(root, "handle", NFT_TYPE_U64, &uval64) == -1) @@ -518,7 +522,7 @@ static int nft_chain_json_parse(struct nft_chain *c, char *json) nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_PACKETS, uval64); if (nft_jansson_parse_family(root, &val32) != 0) - return -1; + goto err; nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_FAMILY, val32); @@ -527,7 +531,7 @@ static int nft_chain_json_parse(struct nft_chain *c, char *json) if (valstr == NULL) goto err; - nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_TABLE, strdup(valstr)); + nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_TABLE, valstr); if (nft_jansson_node_exist(root, "hooknum")) { valstr = nft_jansson_value_parse_str(root, "type"); @@ -535,7 +539,7 @@ static int nft_chain_json_parse(struct nft_chain *c, char *json) if (valstr == NULL) goto err; - nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_TYPE, strdup(valstr)); + nft_chain_attr_set_str(c, NFT_CHAIN_ATTR_TYPE, valstr); if (nft_jansson_value_parse_val(root, "prio", NFT_TYPE_S32, &val32) == -1) @@ -564,11 +568,11 @@ static int nft_chain_json_parse(struct nft_chain *c, char *json) nft_chain_attr_set_u32(c, NFT_CHAIN_ATTR_POLICY, policy); } - xfree(root); + nft_jansson_free_root(node); return 0; err: - xfree(root); + nft_jansson_free_root(node); return -1; #else errno = EOPNOTSUPP; diff --git a/src/internal.h b/src/internal.h index 62eb3c5..5ca2288 100644 --- a/src/internal.h +++ b/src/internal.h @@ -48,7 +48,9 @@ int nft_jansson_value_parse_val(json_t *root, const char *tag, int type, void *out); const char *nft_jansson_value_parse_str(json_t *root, const char *tag); bool nft_jansson_node_exist(json_t *root, const char *tag); -json_t *nft_jansson_get_root(char *json, const char *tag, json_error_t *err); +json_t *nft_jansson_create_root(char *json, json_error_t *err); +json_t *nft_jansson_get_node(json_t *root, const char *tag); +void nft_jansson_free_root(json_t *root); int nft_jansson_parse_family(json_t *root, void *out); #endif diff --git a/src/jansson.c b/src/jansson.c index cc3ab23..ca29863 100644 --- a/src/jansson.c +++ b/src/jansson.c @@ -72,7 +72,7 @@ bool nft_jansson_node_exist(json_t *root, const char *tag) return json_object_get(root, tag) != NULL; } -json_t *nft_jansson_get_root(char *json, const char *tag, json_error_t *err) +json_t *nft_jansson_create_root(char *json, json_error_t *err) { json_t *root; @@ -82,14 +82,27 @@ json_t *nft_jansson_get_root(char *json, const char *tag, json_error_t *err) return NULL; } - root = json_object_get(root, tag); - if (root == NULL) { + return root; +} + +json_t *nft_jansson_get_node(json_t *root, const char *tag) +{ + json_t *node; + + node = json_object_get(root, tag); + if (node == NULL) { errno = EINVAL; return NULL; } - return root; + return node; } + +void nft_jansson_free_root(json_t *root) +{ + json_decref(root); +} + int nft_jansson_parse_family(json_t *root, void *out) { const char *str; diff --git a/src/table.c b/src/table.c index 26bf60d..b51a383 100644 --- a/src/table.c +++ b/src/table.c @@ -269,13 +269,17 @@ err: static int nft_table_json_parse(struct nft_table *t, char *json) { #ifdef JSON_PARSING - json_t *root; + json_t *root, *node; json_error_t error; uint32_t table_flag; const char *str; int family; - root = nft_jansson_get_root(json, "table", &error); + node = nft_jansson_create_root(json, &error); + if (node == NULL) + return -1; + + root = nft_jansson_get_node(node, "table"); if (root == NULL) return -1; @@ -283,10 +287,10 @@ static int nft_table_json_parse(struct nft_table *t, char *json) if (str == NULL) goto err; - nft_table_attr_set_str(t, NFT_TABLE_ATTR_NAME, strdup(str)); + nft_table_attr_set_str(t, NFT_TABLE_ATTR_NAME, str); if (nft_jansson_parse_family(root, &family) != 0) - return -1; + goto err; nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FAMILY, family); @@ -296,10 +300,10 @@ static int nft_table_json_parse(struct nft_table *t, char *json) nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS, table_flag); - xfree(root); + nft_jansson_free_root(node); return 0; err: - xfree(root); + nft_jansson_free_root(node); return -1; #else errno = EOPNOTSUPP; -- cgit v1.2.3