All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andreas Greve <andreas.greve@a-greve.de>
To: stephen@networkplumber.org
Cc: netdev@vger.kernel.org, andreas.greve@a-greve.de
Subject: Re: Bug: tc filter show .... raise segfault if more than one rule with action -j MARK exist
Date: Sat, 10 May 2014 11:19:18 +0200	[thread overview]
Message-ID: <536DEF16.6010406@a-greve.de> (raw)
In-Reply-To: <536DED2C.10301@a-greve.de>

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

sorry its to early for me ;)

here the missing attachment.

On 05/10/14 11:11, Andreas Greve wrote:
> Dear Stephen Hemminger, Dear List Members,
>
> this is a corrected/optimized version of the patch
> Thanks to Stephen Hemminger, for giving me the hint to use structure 
> assignment instead of
> memcpy().
>
> Best wishes
>
> Andreas Greve
>
> On 05/08/14 13:48, Andreas Greve wrote:
>> Dear Stephen Hemminger, Dear List Members,
>>
>> the command
>>
>> tc filter show dev eth1 parent ffff:
>>
>> raise a segmentation fault if there are more than one filter rule 
>> with action -j MARK exists.
>>
>> Reason:
>> In print_ipt(...) xtables will be initialzed with a pointer to the 
>> static struct tcipt_globals at xtables_init_all(). Later on the 
>> fields .opts and .options_offset of tcipt_globals are modified. The 
>> call of xtables_free_opts(1) at the end of print_ipt(...) does not 
>> restore the original values of tcipt_globals for the modified fields. 
>> It only frees some allocated memory and sets .opts to NULL. This 
>> leads to a segmentation fault when print_ipt()
>> is called for the next filter rule with action -j MARK.
>>
>> Fix: (patch attached)
>> Cloneing tcipt_globals on the stack as tmp_tcipt_globals and use it 
>> instead of tcipt_globals, so tcipt_globals will be not modified.
>>
>> Tests:
>> I only have done limit tests for this fix ( action -j MARK ) on a 
>> debian wheezy iproute2 package build from source based on 
>> upstream/3.14.0. The system is a little bit special  kernel 
>> 3.12.17-xen on xen-4.4.1-pre.
>>
>>
>> Andreas Henriksson (debian iproute maintainer) give me an other idea 
>> of how to fix this bug by modifying  xtables_free_opts() so that it 
>> sets .opts = .orig_opts instead .opts = NULL. This should avoid 
>> having to duplicate the entire struct each time.
>>
>> I prefer the cloning  because:
>>
>> 1)  In my understanding the variable tcipt_globals is a complex 
>> "constant" that should never be modified. ( Is that right ?)
>>
>> 2) If we want to do the fix in xtables_free_opts we have to change 
>> the struct xtables_globals because we need for all fields .orig 
>> fields I think this will  make all things much more complicated.
>>
>>
>> additional Brainstorms:
>>
>> a ) Perhaps we have to think about of a deep clone of tcipt_globals 
>> to protect the underlaying option array
>> b ) makes cloning of  tcipt_globals sense in  parse_ipt(...)
>> But for this two decisions my understanding of the whole system is 
>> not enough.
>>
>>
>> I hope the Information helps
>>
>> Thanks
>>
>> Best wishes
>>
>>
>> Andreas Greve
>>
>>
>>
>>
>>
>>
>>
>>
>> Andreas Henriksson
>>
>>
>> Stephen Hemminger
>>
>


[-- Attachment #2: 0001-print_ipt-segfault-if-more-then-one-filter-with-acti.patch --]
[-- Type: text/x-patch, Size: 2793 bytes --]

>From fdf33181ade1320a6de79ac57d0f751b571f1dd8 Mon Sep 17 00:00:00 2001
From: Andreas Greve <andreas.greve@a-greve.de>
Date: Sat, 10 May 2014 10:47:01 +0200
Subject: [PATCH] print_ipt: segfault if more then one filter with action -j
 MARK.

BUG: tc filter show ... produce a segmentation fault if more than one
filter rule with action -j MARK exists.

Reason: In print_ipt(...) xtables will be initialzed with a
pointer to the static struct tcipt_globals at xtables_init_all().
Later on the fields .opts and .options_offset of tcipt_globals are
modified. The call of xtables_free_opts(1) at the end of print(...)
does not restore the original values of tcipt_globals for the
modified fields. It only frees some allocated memory and sets
.opts to NULL. This leads to a segmentation fault when print_ipt()
is called for the next filter rule with action -j MARK.

Fix: Cloneing tcipt_globals on the stack as tmp_tcipt_globals and
use it instead of tcipt_globals, so tcipt_globals will be not
modified.

Signed-off-by: Andreas Greve <andreas.greve@a-greve.de>
---
 tc/m_xt.c |   17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/tc/m_xt.c b/tc/m_xt.c
index 27029c1..274df1d 100644
--- a/tc/m_xt.c
+++ b/tc/m_xt.c
@@ -298,7 +298,14 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg)
 	if (arg == NULL)
 		return -1;
 
-	xtables_init_all(&tcipt_globals, NFPROTO_IPV4);
+	/* 
+	   clone tcipt_globals because .opts and .options_offset  will be modified later and not 
+           restored by iptables. If tcipt_globals is not cloned the modification tcipt_globals will 
+           cause a segmentation fault if more than one filter rule  with action -j  exists.
+        */
+	struct xtables_globals tmp_tcipt_globals = tcipt_globals;
+
+	xtables_init_all(&tmp_tcipt_globals, NFPROTO_IPV4);
 	set_lib_dir();
 
 	parse_rtattr_nested(tb, TCA_IPT_MAX, arg);
@@ -333,12 +340,12 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg)
 			}
 
 #if (XTABLES_VERSION_CODE >= 6)
-		opts = xtables_options_xfrm(tcipt_globals.orig_opts,
-					    tcipt_globals.opts,
+		opts = xtables_options_xfrm(tmp_tcipt_globals.orig_opts,
+					    tmp_tcipt_globals.opts,
 					    m->x6_options,
 					    &m->option_offset);
 #else
-		opts = xtables_merge_options(tcipt_globals.opts,
+		opts = xtables_merge_options(tmp_tcipt_globals.opts,
 					     m->extra_opts,
 					     &m->option_offset);
 #endif
@@ -346,7 +353,7 @@ print_ipt(struct action_util *au,FILE * f, struct rtattr *arg)
 		fprintf(stderr, " failed to find aditional options for target %s\n\n", optarg);
 		return -1;
 	} else
-		tcipt_globals.opts = opts;
+		tmp_tcipt_globals.opts = opts;
 		} else {
 			fprintf(stderr, " failed to find target %s\n\n",
 				t->u.user.name);
-- 
1.7.10.4


  reply	other threads:[~2014-05-10  9:19 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-08 11:48 Bug: tc filter show .... raise segfault if more than one rule with action -j MARK exist Andreas Greve
2014-05-09 20:34 ` Stephen Hemminger
2014-05-10  9:11 ` Andreas Greve
2014-05-10  9:19   ` Andreas Greve [this message]
2014-05-13 20:10     ` Stephen Hemminger

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=536DEF16.6010406@a-greve.de \
    --to=andreas.greve@a-greve.de \
    --cc=netdev@vger.kernel.org \
    --cc=stephen@networkplumber.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.