Re: [ovs-dev] [patch v2] conntrack: Fix possible uninitialized memory.

2019-02-04 Thread Darrell Ball via dev


On 2/4/19, 8:53 AM, "ovs-dev-boun...@openvswitch.org on behalf of Aaron 
Conole"  wrote:

Darrell Ball  writes:

> There are a few cases where padding may be undefined according to
> the C standard. Practically, it seems implementations don't have issue,
> but it is better to be safe. The code paths modified are not hot ones.
> Found by inspection.

Better to be safe how?  What do implementations not have issue with?
I'm having trouble understanding this commit message as a rationale for
the change.

The conn keys are used in a hash calculation



> Signed-off-by: Darrell Ball 
> ---
>
> v2: Found another one; will double check for others later.

Were there actual problems observed somewhere?  From what I can see,
none of these accesses did any kind of bit-wise structure memcmp().
Rather, I see use of named fields when doing comparisons.  This tells me
that the pad bits should be irrelevant.  Probably I missed something.

OTOH, I guess you might also be interested in fixing:

   'struct ct_addr first_addr = ct_addr;' on line 2181 of conntrack.c

Existing structure copy should work


and the 'process_ftp_ctl_v6' function.  Those do possibly use memcmp()
with indeterminate pad bits, if I'm reading them correctly (but just
cursory reading).

Existing structure copy and the memset zero should work.

>  lib/conntrack.c | 13 +
>  1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/lib/conntrack.c b/lib/conntrack.c
> index e1f4041..e7033a8 100644
> --- a/lib/conntrack.c
> +++ b/lib/conntrack.c
> @@ -747,6 +747,7 @@ static struct conn *
>  conn_lookup(struct conntrack *ct, const struct conn_key *key, long long 
now)
>  {
>  struct conn_lookup_ctx ctx;
> +memset(, 0, sizeof ctx);
>  ctx.conn = NULL;
>  ctx.key = *key;
>  ctx.hash = conn_key_hash(key, ct->hash_basis);

How does this help?  Looking at conn_key_hash it seems to only use those
defined sections of the struct (ie: it doesn't walk the raw memory, it
pulls the fields it needs by assignment).  conn_key_cmp also compares
named fields.

Again, For the hash; conn_key has padding


> @@ -896,6 +897,7 @@ conn_not_found(struct conntrack *ct, struct dp_packet 
*pkt,
>  
>  if (nat_action_info) {
>  nc->nat_info = xmemdup(nat_action_info, sizeof 
*nc->nat_info);
> +memset(conn_for_un_nat_copy, 0, sizeof 
*conn_for_un_nat_copy);

Was there an observable bug related to the pad bits here?  

No, it is just adhering to C standard
Implementations are 'very unlikely' to have issue.

I didn't walk this path deep enough, but in conntrack.c I didn't see any 
related
memcmp() calls.

Again, for the hash later


>  if (alg_exp) {
>  if (alg_exp->nat_rpl_dst) {
> @@ -934,8 +936,6 @@ conn_not_found(struct conntrack *ct, struct dp_packet 
*pkt,
>  ct_rwlock_unlock(>resources_lock);
>  }
>  conn_for_un_nat_copy->conn_type = CT_CONN_TYPE_UN_NAT;
> -conn_for_un_nat_copy->nat_info = NULL;
> -conn_for_un_nat_copy->alg = NULL;

If this was needed here before, isn't it still needed now?  There are a
interrim assignments from 'nc', and I think that won't be changed by
doing a memset() (ie: does this still cause a double free if you drop it?).

Not related to double free
Oops, this is still needed in present code base


>  nat_packet(pkt, nc, ctx->icmp_related);
>  }
>  hmap_insert(>buckets[bucket].connections, >node, 
ctx->hash);
> @@ -1262,6 +1262,7 @@ process_one(struct conntrack *ct, struct dp_packet 
*pkt,
>   ct->hash_basis,
>   alg_src_ip_wc(ct_alg_ctl));
>  if (alg_exp) {
> +memset(_exp_entry, 0, sizeof alg_exp_entry);
>  alg_exp_entry = *alg_exp;
>  alg_exp = _exp_entry;
>  }
> @@ -2024,7 +2025,9 @@ conn_key_hash(const struct conn_key *key, uint32_t 
basis)
>  static void
>  conn_key_reverse(struct conn_key *key)
>  {
> -struct ct_endpoint tmp = key->src;
> +struct ct_endpoint tmp;
> +memset(, 0, sizeof tmp);
> +tmp = key->src;

I don't understand the reason to clear the pad bits of tmp here - you
only use the named fields and they should be of the same size (and if
not, the compiler should be performing integer widening / truncation
properly).  Did I miss something?

This change was previously removed in V3.


>  key->src = key->dst;
>  key->dst = tmp;
>  }
> @@ -2614,7 +2617,9 @@ static struct alg_exp_node *
>  

Re: [ovs-dev] [patch v2] conntrack: Fix possible uninitialized memory.

2019-02-04 Thread Aaron Conole
Darrell Ball  writes:

> There are a few cases where padding may be undefined according to
> the C standard. Practically, it seems implementations don't have issue,
> but it is better to be safe. The code paths modified are not hot ones.
> Found by inspection.

Better to be safe how?  What do implementations not have issue with?
I'm having trouble understanding this commit message as a rationale for
the change.

> Signed-off-by: Darrell Ball 
> ---
>
> v2: Found another one; will double check for others later.

Were there actual problems observed somewhere?  From what I can see,
none of these accesses did any kind of bit-wise structure memcmp().
Rather, I see use of named fields when doing comparisons.  This tells me
that the pad bits should be irrelevant.  Probably I missed something.

OTOH, I guess you might also be interested in fixing:

   'struct ct_addr first_addr = ct_addr;' on line 2181 of conntrack.c

and the 'process_ftp_ctl_v6' function.  Those do possibly use memcmp()
with indeterminate pad bits, if I'm reading them correctly (but just
cursory reading).

>  lib/conntrack.c | 13 +
>  1 file changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/lib/conntrack.c b/lib/conntrack.c
> index e1f4041..e7033a8 100644
> --- a/lib/conntrack.c
> +++ b/lib/conntrack.c
> @@ -747,6 +747,7 @@ static struct conn *
>  conn_lookup(struct conntrack *ct, const struct conn_key *key, long long now)
>  {
>  struct conn_lookup_ctx ctx;
> +memset(, 0, sizeof ctx);
>  ctx.conn = NULL;
>  ctx.key = *key;
>  ctx.hash = conn_key_hash(key, ct->hash_basis);

How does this help?  Looking at conn_key_hash it seems to only use those
defined sections of the struct (ie: it doesn't walk the raw memory, it
pulls the fields it needs by assignment).  conn_key_cmp also compares
named fields.

> @@ -896,6 +897,7 @@ conn_not_found(struct conntrack *ct, struct dp_packet 
> *pkt,
>  
>  if (nat_action_info) {
>  nc->nat_info = xmemdup(nat_action_info, sizeof *nc->nat_info);
> +memset(conn_for_un_nat_copy, 0, sizeof *conn_for_un_nat_copy);

Was there an observable bug related to the pad bits here?  I didn't walk
this path deep enough, but in conntrack.c I didn't see any related
memcmp() calls.

>  if (alg_exp) {
>  if (alg_exp->nat_rpl_dst) {
> @@ -934,8 +936,6 @@ conn_not_found(struct conntrack *ct, struct dp_packet 
> *pkt,
>  ct_rwlock_unlock(>resources_lock);
>  }
>  conn_for_un_nat_copy->conn_type = CT_CONN_TYPE_UN_NAT;
> -conn_for_un_nat_copy->nat_info = NULL;
> -conn_for_un_nat_copy->alg = NULL;

If this was needed here before, isn't it still needed now?  There are a
interrim assignments from 'nc', and I think that won't be changed by
doing a memset() (ie: does this still cause a double free if you drop it?).

>  nat_packet(pkt, nc, ctx->icmp_related);
>  }
>  hmap_insert(>buckets[bucket].connections, >node, ctx->hash);
> @@ -1262,6 +1262,7 @@ process_one(struct conntrack *ct, struct dp_packet *pkt,
>   ct->hash_basis,
>   alg_src_ip_wc(ct_alg_ctl));
>  if (alg_exp) {
> +memset(_exp_entry, 0, sizeof alg_exp_entry);
>  alg_exp_entry = *alg_exp;
>  alg_exp = _exp_entry;
>  }
> @@ -2024,7 +2025,9 @@ conn_key_hash(const struct conn_key *key, uint32_t 
> basis)
>  static void
>  conn_key_reverse(struct conn_key *key)
>  {
> -struct ct_endpoint tmp = key->src;
> +struct ct_endpoint tmp;
> +memset(, 0, sizeof tmp);
> +tmp = key->src;

I don't understand the reason to clear the pad bits of tmp here - you
only use the named fields and they should be of the same size (and if
not, the compiler should be performing integer widening / truncation
properly).  Did I miss something?

>  key->src = key->dst;
>  key->dst = tmp;
>  }
> @@ -2614,7 +2617,9 @@ static struct alg_exp_node *
>  expectation_lookup(struct hmap *alg_expectations, const struct conn_key *key,
> uint32_t basis, bool src_ip_wc)
>  {
> -struct conn_key check_key = *key;
> +struct conn_key check_key;
> +memset(_key, 0, sizeof check_key);
> +check_key = *key;
>  check_key.src.port = ALG_WC_SRC_PORT;
>  
>  if (src_ip_wc) {

Again, conn_key_hash and conn_key_cmp should be correct, no?
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [patch v2] conntrack: Fix possible uninitialized memory.

2019-02-01 Thread Darrell Ball
There are a few cases where padding may be undefined according to
the C standard.  Practically, it seems implementations don't have issue,
but it is better to be safe. The code paths modified are not hot ones.

Found by inspection.

Signed-off-by: Darrell Ball 
---

v2: Found another one; will double check for others later.

 lib/conntrack.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/lib/conntrack.c b/lib/conntrack.c
index e1f4041..e7033a8 100644
--- a/lib/conntrack.c
+++ b/lib/conntrack.c
@@ -747,6 +747,7 @@ static struct conn *
 conn_lookup(struct conntrack *ct, const struct conn_key *key, long long now)
 {
 struct conn_lookup_ctx ctx;
+memset(, 0, sizeof ctx);
 ctx.conn = NULL;
 ctx.key = *key;
 ctx.hash = conn_key_hash(key, ct->hash_basis);
@@ -896,6 +897,7 @@ conn_not_found(struct conntrack *ct, struct dp_packet *pkt,
 
 if (nat_action_info) {
 nc->nat_info = xmemdup(nat_action_info, sizeof *nc->nat_info);
+memset(conn_for_un_nat_copy, 0, sizeof *conn_for_un_nat_copy);
 
 if (alg_exp) {
 if (alg_exp->nat_rpl_dst) {
@@ -934,8 +936,6 @@ conn_not_found(struct conntrack *ct, struct dp_packet *pkt,
 ct_rwlock_unlock(>resources_lock);
 }
 conn_for_un_nat_copy->conn_type = CT_CONN_TYPE_UN_NAT;
-conn_for_un_nat_copy->nat_info = NULL;
-conn_for_un_nat_copy->alg = NULL;
 nat_packet(pkt, nc, ctx->icmp_related);
 }
 hmap_insert(>buckets[bucket].connections, >node, ctx->hash);
@@ -1262,6 +1262,7 @@ process_one(struct conntrack *ct, struct dp_packet *pkt,
  ct->hash_basis,
  alg_src_ip_wc(ct_alg_ctl));
 if (alg_exp) {
+memset(_exp_entry, 0, sizeof alg_exp_entry);
 alg_exp_entry = *alg_exp;
 alg_exp = _exp_entry;
 }
@@ -2024,7 +2025,9 @@ conn_key_hash(const struct conn_key *key, uint32_t basis)
 static void
 conn_key_reverse(struct conn_key *key)
 {
-struct ct_endpoint tmp = key->src;
+struct ct_endpoint tmp;
+memset(, 0, sizeof tmp);
+tmp = key->src;
 key->src = key->dst;
 key->dst = tmp;
 }
@@ -2614,7 +2617,9 @@ static struct alg_exp_node *
 expectation_lookup(struct hmap *alg_expectations, const struct conn_key *key,
uint32_t basis, bool src_ip_wc)
 {
-struct conn_key check_key = *key;
+struct conn_key check_key;
+memset(_key, 0, sizeof check_key);
+check_key = *key;
 check_key.src.port = ALG_WC_SRC_PORT;
 
 if (src_ip_wc) {
-- 
1.9.1

___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev