From: Pablo Neira Ayuso <pablo@netfilter.org>
To: Patrick McHardy <kaber@trash.net>
Cc: eric@regit.org, netfilter-devel@vger.kernel.org
Subject: Re: datatype: fix crash if wrong integer type is passed
Date: Fri, 10 Jan 2014 10:52:47 +0100 [thread overview]
Message-ID: <20140110095247.GA4159@localhost> (raw)
In-Reply-To: <20140110080425.GA3799@macbook.localnet>
On Fri, Jan 10, 2014 at 08:04:25AM +0000, Patrick McHardy wrote:
> I'm going through older commits in nftables that I didn't review at the
> time and I'm wondering about this one:
>
> commit a320531e78f1bcb12b24da048f34592771392a9a
> Author: Pablo Neira Ayuso <pablo@netfilter.org>
> Date: Wed Jul 24 15:14:22 2013 +0200
>
> datatype: fix crash if wrong integer type is passed
>
> Eric Leblond reported that this command:
>
> nft add rule ip6 filter input position 4 meta protocol icmpv6 accept
>
> crashes nft. The problem is that 'icmpv6' is wrong there, as
> meta protocol is expecting an ethernet protocol, that can be
> expressed as an hexadecimal.
>
> Now this command displays the following error:
>
> <cmdline>:1:52-57: Error: This is not a valid Ethernet protocol
> add rule ip6 filter input position 4 meta protocol icmpv6 accept
> ^^^^^^
> We have generic type checks so I don't want to add special ones (with
> different error messages) for special cases.
>
> Additionally I don't see the error, reverting that patch and executing
> the mentioned rule produces:
>
> <cmdline>:1:52-57: Error: datatype mismatch, expected Ethernet protocol, expression has type Internet protocol
> add rule ip6 filter input position 4 meta protocol icmpv6 accept
> ~~~~~~~~~~~~~ ^^^^^^
>
> Looking at the bugzilla entry, the bug report states:
>
> BUG: invalid input descriptor type 538976288
> nft: src/erec.c:100: erec_print: Assertion `0' failed.
> Abandon
>
> So the problem wasn't related to data types at all but simply due to
> some bug in error reporting. I'll queue up a revert in my tree.
static int expr_evaluate_symbol(struct eval_ctx *ctx, struct expr **expr)
{
struct error_record *erec;
struct symbol *sym;
struct set *set;
struct expr *new; <------- note this is not initialized
switch ((*expr)->symtype) {
case SYMBOL_VALUE:
(*expr)->dtype = ctx->ectx.dtype;
erec = symbol_parse(*expr, &new); <---- passed here
if (erec != NULL) {
erec_queue(erec, ctx->msgs);
return -1;
}
break;
...
}
expr_free(*expr);
*expr = new; <--------- if symbol_parse() returns NULL.
this is set to an invalid memory position.
return expr_evaluate(ctx, expr);
}
Let's see symbol_parse():
struct error_record *symbol_parse(const struct expr *sym,
struct expr **res)
{
const struct datatype *dtype = sym->dtype;
assert(sym->ops->type == EXPR_SYMBOL);
if (dtype == NULL)
return error(&sym->location, "No symbol type information");
do {
if (dtype->parse != NULL)
return dtype->parse(sym, res); <-----
....
}
And now integer_type_parse(), which is the datatype that is called
(note that code below assumes that this patch is reverted):
static struct error_record *integer_type_parse(const struct expr *sym,
struct expr **res)
{
mpz_t v;
int len;
mpz_init(v);
if (gmp_sscanf(sym->identifier, "%Zu%n", v, &len) != 1 ||
(int)strlen(sym->identifier) != len) {
mpz_clear(v);
if (sym->dtype != &integer_type)
return NULL; <-----
So integer_type_parse() returns NULL, note that **res is left
uninitialized.
Going back to expr_evaluate_symbol(), since NULL is returned, it
assumes that an expression has been allocated.
I guess this doesn't crash all the time as we're relying on an
uninitialized memory area and we can argue that the fix may not be
optimal, but I really think this is fixing something.
next prev parent reply other threads:[~2014-01-10 9:52 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-01-10 8:04 datatype: fix crash if wrong integer type is passed Patrick McHardy
2014-01-10 9:52 ` Pablo Neira Ayuso [this message]
2014-01-10 10:02 ` Patrick McHardy
2014-01-10 10:15 ` Pablo Neira Ayuso
2014-01-10 11:13 ` Patrick McHardy
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=20140110095247.GA4159@localhost \
--to=pablo@netfilter.org \
--cc=eric@regit.org \
--cc=kaber@trash.net \
--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.