diff mbox

[nft,v2,4/4] evaluate: Avoid undefined behaviour in concat_subtype_id()

Message ID 1472578792-2991-5-git-send-email-phil@nwl.cc
State Accepted
Delegated to: Pablo Neira
Headers show

Commit Message

Phil Sutter Aug. 30, 2016, 5:39 p.m. UTC
For the left side of a concat expression, dtype is NULL and therefore
off is 0. In that case the code expects to get a datatype of
TYPE_INVALID, but this is fragile as the output of concat_subtype_id()
is undefined for n > 32 / TYPE_BITS.

To fix this, call datatype_lookup() directly passing the expected
TYPE_INVALID as argument if off is 0.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
Changes since v1:
- Understood (and reproduced) when the situation causing the undefined
  behaviour happens.
- Understood what the code is supposed to do in that situation.
- Based on the information at hand, implemented a solution which avoids
  undefined behaviour.
---
 src/evaluate.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

Pablo Neira Ayuso Sept. 5, 2016, 5:09 p.m. UTC | #1
On Tue, Aug 30, 2016 at 07:39:52PM +0200, Phil Sutter wrote:
> For the left side of a concat expression, dtype is NULL and therefore
> off is 0. In that case the code expects to get a datatype of
> TYPE_INVALID, but this is fragile as the output of concat_subtype_id()
> is undefined for n > 32 / TYPE_BITS.
> 
> To fix this, call datatype_lookup() directly passing the expected
> TYPE_INVALID as argument if off is 0.

Also applied, thanks!
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/src/evaluate.c b/src/evaluate.c
index 194a03495b5fd..c1ee6b1929551 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -962,7 +962,10 @@  static int expr_evaluate_concat(struct eval_ctx *ctx, struct expr **expr)
 						 "expressions",
 						 i->dtype->name);
 
-		tmp = concat_subtype_lookup(type, --off);
+		if (dtype == NULL)
+			tmp = datatype_lookup(TYPE_INVALID);
+		else
+			tmp = concat_subtype_lookup(type, --off);
 		expr_set_context(&ctx->ectx, tmp, tmp->size);
 
 		if (list_member_evaluate(ctx, &i) < 0)