Re: [PATCH 2/2 libnftnl] Check memory allocations in setters

2016-06-10 Thread Pablo Neira Ayuso
On Fri, Jun 10, 2016 at 12:20:54PM +0200, Carlos Falgueras García wrote:
> When you set an object attribute the memory is copied, sometimes an
> allocations is needed and it must be checked. Before this patch all setters
> method return void, so this patch makes all setters return int instead void
> to communicate the error to user.
> 
> Summary:
>   * All setters return int instead void
>   * All memory allocations inside setters are checked
>   * Unsetters are used if is possible in order to consolidate
> 
> Signed-off-by: Carlos Falgueras García 
> ---
>  include/libnftnl/chain.h   | 16 +++---
>  include/libnftnl/expr.h| 12 +--
>  include/libnftnl/gen.h |  8 +++
>  include/libnftnl/rule.h| 12 +--
>  include/libnftnl/ruleset.h |  2 +-
>  include/libnftnl/set.h | 20 -
>  include/libnftnl/table.h   | 12 +--
>  src/chain.c| 54 
> +-
>  src/expr.c | 36 ++-
>  src/expr/dynset.c  |  5 -
>  src/expr/immediate.c   |  6 +++---
>  src/expr/log.c |  7 --
>  src/expr/lookup.c  |  5 -
>  src/gen.c  | 20 ++---
>  src/rule.c | 46 ---
>  src/ruleset.c  | 19 ++--
>  src/set.c  | 40 ++
>  src/set_elem.c | 33 ++--
>  src/table.c| 28 +---
>  19 files changed, 210 insertions(+), 171 deletions(-)
> 
> diff --git a/include/libnftnl/chain.h b/include/libnftnl/chain.h
> index 954b39f..6419dee 100644
> --- a/include/libnftnl/chain.h
> +++ b/include/libnftnl/chain.h
> @@ -36,14 +36,14 @@ enum nftnl_chain_attr {
>  
>  bool nftnl_chain_is_set(const struct nftnl_chain *c, uint16_t attr);
>  void nftnl_chain_unset(struct nftnl_chain *c, uint16_t attr);
> -void nftnl_chain_set(struct nftnl_chain *t, uint16_t attr, const void *data);
> -void nftnl_chain_set_data(struct nftnl_chain *t, uint16_t attr,
> -  const void *data, uint32_t data_len);
> -void nftnl_chain_set_u8(struct nftnl_chain *t, uint16_t attr, uint8_t data);
> -void nftnl_chain_set_u32(struct nftnl_chain *t, uint16_t attr, uint32_t 
> data);
> -void nftnl_chain_set_s32(struct nftnl_chain *t, uint16_t attr, int32_t data);
> -void nftnl_chain_set_u64(struct nftnl_chain *t, uint16_t attr, uint64_t 
> data);
> -void nftnl_chain_set_str(struct nftnl_chain *t, uint16_t attr, const char 
> *str);
> +int nftnl_chain_set(struct nftnl_chain *t, uint16_t attr, const void *data);
> +int nftnl_chain_set_data(struct nftnl_chain *t, uint16_t attr,
> +  const void *data, uint32_t data_len);
> +int nftnl_chain_set_u8(struct nftnl_chain *t, uint16_t attr, uint8_t data);
> +int nftnl_chain_set_u32(struct nftnl_chain *t, uint16_t attr, uint32_t data);
> +int nftnl_chain_set_s32(struct nftnl_chain *t, uint16_t attr, int32_t data);
> +int nftnl_chain_set_u64(struct nftnl_chain *t, uint16_t attr, uint64_t data);

_set_uXX never fail, so leave them using void as this just makes this
more complicated.

Please only update _set_data() and _set_str() as in my original patch
that I handed over to you. Thanks.
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2 libnftnl] Check memory allocations in setters

2016-06-10 Thread Carlos Falgueras García
When you set an object attribute the memory is copied, sometimes an
allocations is needed and it must be checked. Before this patch all setters
method return void, so this patch makes all setters return int instead void
to communicate the error to user.

Summary:
* All setters return int instead void
* All memory allocations inside setters are checked
* Unsetters are used if is possible in order to consolidate

Signed-off-by: Carlos Falgueras García 
---
 include/libnftnl/chain.h   | 16 +++---
 include/libnftnl/expr.h| 12 +--
 include/libnftnl/gen.h |  8 +++
 include/libnftnl/rule.h| 12 +--
 include/libnftnl/ruleset.h |  2 +-
 include/libnftnl/set.h | 20 -
 include/libnftnl/table.h   | 12 +--
 src/chain.c| 54 +-
 src/expr.c | 36 ++-
 src/expr/dynset.c  |  5 -
 src/expr/immediate.c   |  6 +++---
 src/expr/log.c |  7 --
 src/expr/lookup.c  |  5 -
 src/gen.c  | 20 ++---
 src/rule.c | 46 ---
 src/ruleset.c  | 19 ++--
 src/set.c  | 40 ++
 src/set_elem.c | 33 ++--
 src/table.c| 28 +---
 19 files changed, 210 insertions(+), 171 deletions(-)

diff --git a/include/libnftnl/chain.h b/include/libnftnl/chain.h
index 954b39f..6419dee 100644
--- a/include/libnftnl/chain.h
+++ b/include/libnftnl/chain.h
@@ -36,14 +36,14 @@ enum nftnl_chain_attr {
 
 bool nftnl_chain_is_set(const struct nftnl_chain *c, uint16_t attr);
 void nftnl_chain_unset(struct nftnl_chain *c, uint16_t attr);
-void nftnl_chain_set(struct nftnl_chain *t, uint16_t attr, const void *data);
-void nftnl_chain_set_data(struct nftnl_chain *t, uint16_t attr,
-const void *data, uint32_t data_len);
-void nftnl_chain_set_u8(struct nftnl_chain *t, uint16_t attr, uint8_t data);
-void nftnl_chain_set_u32(struct nftnl_chain *t, uint16_t attr, uint32_t data);
-void nftnl_chain_set_s32(struct nftnl_chain *t, uint16_t attr, int32_t data);
-void nftnl_chain_set_u64(struct nftnl_chain *t, uint16_t attr, uint64_t data);
-void nftnl_chain_set_str(struct nftnl_chain *t, uint16_t attr, const char 
*str);
+int nftnl_chain_set(struct nftnl_chain *t, uint16_t attr, const void *data);
+int nftnl_chain_set_data(struct nftnl_chain *t, uint16_t attr,
+const void *data, uint32_t data_len);
+int nftnl_chain_set_u8(struct nftnl_chain *t, uint16_t attr, uint8_t data);
+int nftnl_chain_set_u32(struct nftnl_chain *t, uint16_t attr, uint32_t data);
+int nftnl_chain_set_s32(struct nftnl_chain *t, uint16_t attr, int32_t data);
+int nftnl_chain_set_u64(struct nftnl_chain *t, uint16_t attr, uint64_t data);
+int nftnl_chain_set_str(struct nftnl_chain *t, uint16_t attr, const char *str);
 
 const void *nftnl_chain_get(const struct nftnl_chain *c, uint16_t attr);
 const void *nftnl_chain_get_data(const struct nftnl_chain *c, uint16_t attr,
diff --git a/include/libnftnl/expr.h b/include/libnftnl/expr.h
index f192103..d6ad630 100644
--- a/include/libnftnl/expr.h
+++ b/include/libnftnl/expr.h
@@ -20,13 +20,13 @@ struct nftnl_expr *nftnl_expr_alloc(const char *name);
 void nftnl_expr_free(const struct nftnl_expr *expr);
 
 bool nftnl_expr_is_set(const struct nftnl_expr *expr, uint16_t type);
-void nftnl_expr_set(struct nftnl_expr *expr, uint16_t type, const void *data, 
uint32_t data_len);
+int nftnl_expr_set(struct nftnl_expr *expr, uint16_t type, const void *data, 
uint32_t data_len);
 #define nftnl_expr_set_data nftnl_expr_set
-void nftnl_expr_set_u8(struct nftnl_expr *expr, uint16_t type, uint8_t data);
-void nftnl_expr_set_u16(struct nftnl_expr *expr, uint16_t type, uint16_t data);
-void nftnl_expr_set_u32(struct nftnl_expr *expr, uint16_t type, uint32_t data);
-void nftnl_expr_set_u64(struct nftnl_expr *expr, uint16_t type, uint64_t data);
-void nftnl_expr_set_str(struct nftnl_expr *expr, uint16_t type, const char 
*str);
+int nftnl_expr_set_u8(struct nftnl_expr *expr, uint16_t type, uint8_t data);
+int nftnl_expr_set_u16(struct nftnl_expr *expr, uint16_t type, uint16_t data);
+int nftnl_expr_set_u32(struct nftnl_expr *expr, uint16_t type, uint32_t data);
+int nftnl_expr_set_u64(struct nftnl_expr *expr, uint16_t type, uint64_t data);
+int nftnl_expr_set_str(struct nftnl_expr *expr, uint16_t type, const char 
*str);
 
 const void *nftnl_expr_get(const struct nftnl_expr *expr, uint16_t type, 
uint32_t *data_len);
 #define nftnl_expr_get_data nftnl_expr_get
diff --git a/include/libnftnl/gen.h b/include/libnftnl/gen.h
index d0f638f..04054c7 100644
--- a/include/libnftnl/gen.h
+++ b/include/libnftnl/gen.h
@@ -25,14 +25,14 @@ enum {
 
 bool nftnl_gen_is_set(const struct 

Re: [PATCH 2/2,libnftnl] Check memory allocations in setters

2016-06-02 Thread Pablo Neira Ayuso
On Thu, Jun 02, 2016 at 12:40:24PM +0200, Carlos Falgueras García wrote:
> When you set an object attribute the memory is copied, sometimes an
> allocations is needed and it must be checked. By now all setters methods
> returns void, so the policy adopted in case of error is keep the object
> unchanged.
> 
> What this patch makes:
>   * All memory allocations inside setters are checked
>   * The object remains unchanged in case of error
>   * Unsetters are used if is possible in order to consolidate
> 
> Signed-off-by: Carlos Falgueras García 
> ---
>  src/chain.c  | 26 +-
>  src/expr/dynset.c|  8 +++-
>  src/expr/immediate.c |  9 ++---
>  src/expr/log.c   | 12 +---
>  src/expr/lookup.c|  8 +++-
>  src/rule.c   | 28 +---
>  src/set.c| 18 --
>  src/set_elem.c   | 21 +
>  8 files changed, 88 insertions(+), 42 deletions(-)
> 
> diff --git a/src/chain.c b/src/chain.c
> index 990c576..c4c4ff7 100644
> --- a/src/chain.c
> +++ b/src/chain.c
> @@ -168,6 +168,8 @@ static uint32_t nftnl_chain_validate[NFTNL_CHAIN_MAX + 1] 
> = {
>  void nftnl_chain_set_data(struct nftnl_chain *c, uint16_t attr,
>const void *data, uint32_t data_len)
>  {
> + char *newstr;
> +
>   if (attr > NFTNL_CHAIN_MAX)
>   return;
>  
> @@ -178,10 +180,12 @@ void nftnl_chain_set_data(struct nftnl_chain *c, 
> uint16_t attr,
>   strncpy(c->name, data, NFT_CHAIN_MAXNAMELEN);
>   break;
>   case NFTNL_CHAIN_TABLE:
> - if (c->table)
> - xfree(c->table);
> + newstr = strdup(data);
> + if (!newstr)
> + return;
>  
> - c->table = strdup(data);
> + nftnl_chain_unset(c, attr);
> + c->table = newstr;

This looks a bit tangled. Probably something more simple, like this
below?

xfree(c->table);
c->table = strdup(data);
if (!c->table)
return;

Another comment below.

[...]
> diff --git a/src/expr/log.c b/src/expr/log.c
> index c3dc0a6..369174f 100644
> --- a/src/expr/log.c
> +++ b/src/expr/log.c
> @@ -34,13 +34,17 @@ static int nftnl_expr_log_set(struct nftnl_expr *e, 
> uint16_t type,
>const void *data, uint32_t data_len)
>  {
>   struct nftnl_expr_log *log = nftnl_expr_data(e);
> + char *newstr;
>  
>   switch(type) {
>   case NFTNL_EXPR_LOG_PREFIX:
> - if (log->prefix)
> - xfree(log->prefix);
> + newstr = strdup(data);
> + if (!newstr)
> + return -1;
>  
> - log->prefix = strdup(data);
> + if (log->flags & (1 << NFTNL_EXPR_LOG_PREFIX))
> + xfree(log->prefix);
> + log->prefix = newstr;
>   break;
>   case NFTNL_EXPR_LOG_GROUP:
>   log->group = *((uint16_t *)data);
> @@ -60,6 +64,8 @@ static int nftnl_expr_log_set(struct nftnl_expr *e, 
> uint16_t type,
>   default:
>   return -1;
>   }
> +
> + log->flags |= (1 << type);

Do we need this here?

>   return 0;
>  }
>  
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/2,libnftnl] Check memory allocations in setters

2016-06-02 Thread Carlos Falgueras García
When you set an object attribute the memory is copied, sometimes an
allocations is needed and it must be checked. By now all setters methods
returns void, so the policy adopted in case of error is keep the object
unchanged.

What this patch makes:
* All memory allocations inside setters are checked
* The object remains unchanged in case of error
* Unsetters are used if is possible in order to consolidate

Signed-off-by: Carlos Falgueras García 
---
 src/chain.c  | 26 +-
 src/expr/dynset.c|  8 +++-
 src/expr/immediate.c |  9 ++---
 src/expr/log.c   | 12 +---
 src/expr/lookup.c|  8 +++-
 src/rule.c   | 28 +---
 src/set.c| 18 --
 src/set_elem.c   | 21 +
 8 files changed, 88 insertions(+), 42 deletions(-)

diff --git a/src/chain.c b/src/chain.c
index 990c576..c4c4ff7 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -168,6 +168,8 @@ static uint32_t nftnl_chain_validate[NFTNL_CHAIN_MAX + 1] = 
{
 void nftnl_chain_set_data(struct nftnl_chain *c, uint16_t attr,
 const void *data, uint32_t data_len)
 {
+   char *newstr;
+
if (attr > NFTNL_CHAIN_MAX)
return;
 
@@ -178,10 +180,12 @@ void nftnl_chain_set_data(struct nftnl_chain *c, uint16_t 
attr,
strncpy(c->name, data, NFT_CHAIN_MAXNAMELEN);
break;
case NFTNL_CHAIN_TABLE:
-   if (c->table)
-   xfree(c->table);
+   newstr = strdup(data);
+   if (!newstr)
+   return;
 
-   c->table = strdup(data);
+   nftnl_chain_unset(c, attr);
+   c->table = newstr;
break;
case NFTNL_CHAIN_HOOKNUM:
memcpy(>hooknum, data, sizeof(c->hooknum));
@@ -208,16 +212,20 @@ void nftnl_chain_set_data(struct nftnl_chain *c, uint16_t 
attr,
c->family = *((uint32_t *)data);
break;
case NFTNL_CHAIN_TYPE:
-   if (c->type)
-   xfree(c->type);
+   newstr = strdup(data);
+   if (!newstr)
+   return;
 
-   c->type = strdup(data);
+   nftnl_chain_unset(c, attr);
+   c->type = newstr;
break;
case NFTNL_CHAIN_DEV:
-   if (c->dev)
-   xfree(c->dev);
+   newstr = strdup(data);
+   if (!newstr)
+   return;
 
-   c->dev = strdup(data);
+   nftnl_chain_unset(c, attr);
+   c->dev = newstr;
break;
}
c->flags |= (1 << attr);
diff --git a/src/expr/dynset.c b/src/expr/dynset.c
index c8d97a5..e54d9e9 100644
--- a/src/expr/dynset.c
+++ b/src/expr/dynset.c
@@ -37,6 +37,7 @@ nftnl_expr_dynset_set(struct nftnl_expr *e, uint16_t type,
 const void *data, uint32_t data_len)
 {
struct nftnl_expr_dynset *dynset = nftnl_expr_data(e);
+   char *newstr;
 
switch (type) {
case NFTNL_EXPR_DYNSET_SREG_KEY:
@@ -52,7 +53,12 @@ nftnl_expr_dynset_set(struct nftnl_expr *e, uint16_t type,
dynset->timeout = *((uint64_t *)data);
break;
case NFTNL_EXPR_DYNSET_SET_NAME:
-   dynset->set_name = strdup((const char *)data);
+   newstr = strdup(data);
+   if (!newstr)
+   return -1;
+
+   xfree(dynset->set_name);
+   dynset->set_name = newstr;
break;
case NFTNL_EXPR_DYNSET_SET_ID:
dynset->set_id = *((uint32_t *)data);
diff --git a/src/expr/immediate.c b/src/expr/immediate.c
index eb2ca0f..60e7ae4 100644
--- a/src/expr/immediate.c
+++ b/src/expr/immediate.c
@@ -30,6 +30,7 @@ nftnl_expr_immediate_set(struct nftnl_expr *e, uint16_t type,
const void *data, uint32_t data_len)
 {
struct nftnl_expr_immediate *imm = nftnl_expr_data(e);
+   char *newstr;
 
switch(type) {
case NFTNL_EXPR_IMM_DREG:
@@ -43,10 +44,12 @@ nftnl_expr_immediate_set(struct nftnl_expr *e, uint16_t 
type,
imm->data.verdict = *((uint32_t *)data);
break;
case NFTNL_EXPR_IMM_CHAIN:
-   if (imm->data.chain)
-   xfree(imm->data.chain);
+   newstr = strdup(data);
+   if (!newstr)
+   return -1;
 
-   imm->data.chain = strdup(data);
+   xfree(imm->data.chain);
+   imm->data.chain = newstr;
break;
default:
return -1;
diff --git a/src/expr/log.c b/src/expr/log.c
index c3dc0a6..369174f 100644
--- a/src/expr/log.c
+++ b/src/expr/log.c
@@ -34,13 +34,17 @@ static int nftnl_expr_log_set(struct