All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiri Popelka <jpopelka@redhat.com>
To: netfilter-devel@vger.kernel.org
Subject: [PATCH] ebtables: Possible problems found by static analysis of code
Date: Tue, 14 Jun 2011 12:32:14 +0200	[thread overview]
Message-ID: <4DF738AE.3060306@redhat.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 520 bytes --]

Hello,

we had analyzed the ebtables-v2.0.9-2 code with Coverity.
Coverity is commercial enterprise level tool for
static analysis (analysis based only on compiling of sources,
not based on running of binary) of the code.

As a result I have the following patches that should fix some possible problems.
There's a respective part(s) of the Coverity error log in each patch.

You could also find this link useful:
https://www.securecoding.cert.org/confluence/display/seccode/Coverity+Prevent

With regards,
Jiri Popelka


[-- Attachment #2: ebtables-v2.0.9-2-Coverity-forward_null.patch --]
[-- Type: text/plain, Size: 1598 bytes --]

Error: FORWARD_NULL
ebtables-v2.0.9-2/communication.c:305: var_compare_op: Comparing "next" to null implies that "next" might be null.
ebtables-v2.0.9-2/communication.c:316: var_deref_op: Dereferencing null variable "next".

Error: FORWARD_NULL
ebtables-v2.0.9-2/communication.c:632: assign_zero: Assigning: "repl->counters" = 0.
ebtables-v2.0.9-2/communication.c:634: var_deref_model: Passing null variable "(char *)repl->counters" to function "fread", which dereferences it.

diff -up ebtables-v2.0.9-2/communication.c.forward_null ebtables-v2.0.9-2/communication.c
--- ebtables-v2.0.9-2/communication.c.forward_null	2010-02-03 22:17:45.000000000 +0100
+++ ebtables-v2.0.9-2/communication.c	2011-06-01 18:20:52.844295103 +0200
@@ -309,6 +309,8 @@ void ebt_deliver_counters(struct ebt_u_r
 			if (chainnr == u_repl->num_chains)
 				break;
 		}
+		if (next == NULL)
+			ebt_print_error("ebt_deliver_counters: next == NULL");
 		if (cc->type == CNT_NORM) {
 			/* 'Normal' rule, meaning we didn't do anything to it
 			 * So, we just copy */
@@ -636,9 +638,9 @@ static int retrieve_from_file(char *file
 	   != repl->entries_size ||
 	   fseek(file, sizeof(struct ebt_replace) + repl->entries_size,
 		 SEEK_SET)
-	   || fread((char *)repl->counters, sizeof(char),
+	   || (repr->counters && fread((char *)repl->counters, sizeof(char),
 	   repl->nentries * sizeof(struct ebt_counter), file)
-	   != repl->nentries * sizeof(struct ebt_counter)) {
+	   != repl->nentries * sizeof(struct ebt_counter))) {
 		ebt_print_error("File %s is corrupt", filename);
 		free(entries);
 		repl->entries = NULL;

[-- Attachment #3: ebtables-v2.0.9-2-Coverity-no_effect.patch --]
[-- Type: text/plain, Size: 1614 bytes --]

Error: NO_EFFECT
ebtables-v2.0.9-2/extensions/ebt_nflog.c:83: unsigned_compare: This less-than-zero comparison of an unsigned value is never true. "i < 0U".
ebtables-v2.0.9-2/extensions/ebt_nflog.c:95: unsigned_compare: This less-than-zero comparison of an unsigned value is never true. "i < 0U".
ebtables-v2.0.9-2/extensions/ebt_nflog.c:107: unsigned_compare: This less-than-zero comparison of an unsigned value is never true. "i < 0U".

diff -up ebtables-v2.0.9-2/extensions/ebt_nflog.c.no_effect ebtables-v2.0.9-2/extensions/ebt_nflog.c
--- ebtables-v2.0.9-2/extensions/ebt_nflog.c.no_effect	2010-02-03 22:17:45.000000000 +0100
+++ ebtables-v2.0.9-2/extensions/ebt_nflog.c	2011-06-01 18:29:41.058691515 +0200
@@ -80,7 +80,7 @@ static int nflog_parse(int c, char **arg
 		i = strtoul(optarg, &end, 10);
 		if (*end != '\0')
 			ebt_print_error2("--nflog-group must be a number!");
-		if (i < 0)
+		if (i == ULONG_MAX)
 			ebt_print_error2("--nflog-group can not be negative");
 		info->group = i;
 		break;
@@ -92,7 +92,7 @@ static int nflog_parse(int c, char **arg
 		i = strtoul(optarg, &end, 10);
 		if (*end != '\0')
 			ebt_print_error2("--nflog-range must be a number!");
-		if (i < 0)
+		if (i == ULONG_MAX)
 			ebt_print_error2("--nflog-range can not be negative");
 		info->len = i;
 		break;
@@ -104,7 +104,7 @@ static int nflog_parse(int c, char **arg
 		i = strtoul(optarg, &end, 10);
 		if (*end != '\0')
 			ebt_print_error2("--nflog-threshold must be a number!");
-		if (i < 0)
+		if (i == ULONG_MAX)
 			ebt_print_error2
 			    ("--nflog-threshold can not be negative");
 		info->threshold = i;

[-- Attachment #4: ebtables-v2.0.9-2-Coverity-overrun_static.patch --]
[-- Type: text/plain, Size: 783 bytes --]

Error: OVERRUN_STATIC
ebtables-v2.0.9-2/communication.c:378: assignment: Assigning: "optlen" = "u_repl->nentries * sizeof (struct ebt_counter) /*16*/ + sizeof (struct ebt_replace) /*120*/".
ebtables-v2.0.9-2/communication.c:387: overrun-buffer-arg: Overrunning struct type struct ebt_replace of size 120 bytes by passing it to a function which indexes it with argument "optlen" at byte position 135.

Error: UNINIT
ebtables-v2.0.9-2/communication.c:288: var_decl: Declaring variable "repl" without initializer.
ebtables-v2.0.9-2/communication.c:387: uninit_use_in_call: Using uninitialized value "repl": field "repl".entries is uninitialized when calling "setsockopt".

I'm not sure whether this is really a problem and how to properly treat it,
so there's actually no patch here :-)

[-- Attachment #5: ebtables-v2.0.9-2-Coverity-resource_leak.patch --]
[-- Type: text/plain, Size: 1625 bytes --]

Error: RESOURCE_LEAK
ebtables-v2.0.9-2/extensions/ebt_among.c:191: alloc_fn: Calling allocation function "new_wormhash".
ebtables-v2.0.9-2/extensions/ebt_among.c:87: alloc_fn: Storage is returned from allocation function "malloc".
ebtables-v2.0.9-2/extensions/ebt_among.c:87: var_assign: Assigning: "result" = "malloc(size)".
ebtables-v2.0.9-2/extensions/ebt_among.c:92: noescape: Variable "result" is not freed or pointed-to in function "memset".
ebtables-v2.0.9-2/extensions/ebt_among.c:94: return_alloc: Returning allocated memory "result".
ebtables-v2.0.9-2/extensions/ebt_among.c:191: var_assign: Assigning: "workcopy" =  storage returned from "new_wormhash(1024)".
ebtables-v2.0.9-2/extensions/ebt_among.c:205: leaked_storage: Variable "workcopy" going out of scope leaks the storage it points to.
ebtables-v2.0.9-2/extensions/ebt_among.c:210: leaked_storage: Variable "workcopy" going out of scope leaks the storage it points to.

diff -up ebtables-v2.0.9-2/extensions/ebt_among.c.resource_leak ebtables-v2.0.9-2/extensions/ebt_among.c
--- ebtables-v2.0.9-2/extensions/ebt_among.c.resource_leak	2010-02-03 22:17:45.000000000 +0100
+++ ebtables-v2.0.9-2/extensions/ebt_among.c	2011-06-01 19:19:46.886113499 +0200
@@ -202,11 +202,13 @@ static struct ebt_mac_wormhash *create_w
 			if (read_until(&pc, ":", token, 2) < 0
 			    || token[0] == 0) {
 				ebt_print_error("MAC parse error: %.20s", anchor);
+				free(workcopy);
 				return NULL;
 			}
 			mac[i] = strtol(token, &endptr, 16);
 			if (*endptr) {
 				ebt_print_error("MAC parse error: %.20s", anchor);
+				free(workcopy);
 				return NULL;
 			}
 			pc++;

[-- Attachment #6: ebtables-v2.0.9-2-Coverity-uninit.patch --]
[-- Type: text/plain, Size: 1157 bytes --]

Error: UNINIT
ebtables-v2.0.9-2/communication.c:59: var_decl: Declaring variable "chain_offsets" without initializer.
ebtables-v2.0.9-2/communication.c:69: alloc_fn: Assigning: "chain_offsets" = "(unsigned int *)malloc(u_repl->num_chains * sizeof (unsigned int) /*4*/)", which is allocated but not initialized.
ebtables-v2.0.9-2/communication.c:169: uninit_use: Using uninitialized value "*chain_offsets".

diff -up ebtables-v2.0.9-2/communication.c.uninit ebtables-v2.0.9-2/communication.c
--- ebtables-v2.0.9-2/communication.c.uninit	2010-02-03 22:17:45.000000000 +0100
+++ ebtables-v2.0.9-2/communication.c	2011-06-01 19:36:52.192295410 +0200
@@ -66,7 +66,10 @@ static struct ebt_replace *translate_use
 	new->nentries = u_repl->nentries;
 	new->num_counters = u_repl->num_counters;
 	new->counters = sparc_cast u_repl->counters;
-	chain_offsets = (unsigned int *)malloc(u_repl->num_chains * sizeof(unsigned int));
+	chain_offsets = (unsigned int *)calloc(u_repl->num_chains, sizeof(unsigned int));
+	if (!chain_offsets)
+		ebt_print_memory();
+	
 	/* Determine size */
 	for (i = 0; i < u_repl->num_chains; i++) {
 		if (!(entries = u_repl->chains[i]))

[-- Attachment #7: ebtables-v2.0.9-2-Coverity-use_after_free.patch --]
[-- Type: text/plain, Size: 590 bytes --]

Error: USE_AFTER_FREE
ebtables-v2.0.9-2/libebtc.c:408: freed_arg: "free" frees "cc".
ebtables-v2.0.9-2/libebtc.c:410: deref_after_free: Dereferencing freed pointer "cc".

diff -up ebtables-v2.0.9-2/libebtc.c.use_after_free ebtables-v2.0.9-2/libebtc.c
--- ebtables-v2.0.9-2/libebtc.c.use_after_free	2010-02-03 22:17:45.000000000 +0100
+++ ebtables-v2.0.9-2/libebtc.c	2011-06-01 19:53:36.764736526 +0200
@@ -407,7 +407,6 @@ void ebt_delete_cc(struct ebt_cntchanges
 		cc->next->prev = cc->prev;
 		free(cc);
 	}
-	cc->type = CNT_DEL;
 }
 
 void ebt_empty_chain(struct ebt_u_entries *entries)

             reply	other threads:[~2011-06-14 10:32 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-14 10:32 Jiri Popelka [this message]
2011-06-15 20:37 ` [PATCH] ebtables: Possible problems found by static analysis of code Bart De Schuymer
2011-06-23 18:51   ` Bart De Schuymer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4DF738AE.3060306@redhat.com \
    --to=jpopelka@redhat.com \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.