diff mbox

[nft] netlink_delinearize: fix use-after-free

Message ID 1448622765-2519-1-git-send-email-pablo@netfilter.org
State Changes Requested
Delegated to: Pablo Neira
Headers show

Commit Message

Pablo Neira Ayuso Nov. 27, 2015, 11:12 a.m. UTC
We have to clone the payload expression before attaching it to the lhs
of the relational expression, this payload expression is located at the
lhs of the binary operation that is released thereafter.

Fixes: 39f15c2 ("nft: support listing expressions that use non-byte header fields")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 src/netlink_delinearize.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Comments

Patrick McHardy Nov. 27, 2015, 11:18 a.m. UTC | #1
On 27.11, Pablo Neira Ayuso wrote:
> We have to clone the payload expression before attaching it to the lhs
> of the relational expression, this payload expression is located at the
> lhs of the binary operation that is released thereafter.

If we the other reference is released expr_get() is sufficient.

> 
> Fixes: 39f15c2 ("nft: support listing expressions that use non-byte header fields")
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
>  src/netlink_delinearize.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
> index b119027..1ab8f43 100644
> --- a/src/netlink_delinearize.c
> +++ b/src/netlink_delinearize.c
> @@ -1217,8 +1217,8 @@ static void relational_binop_postprocess(struct rule_pp_ctx *ctx, struct expr *e
>  	} else if (binop->op == OP_AND &&
>  		   binop->left->ops->type == EXPR_PAYLOAD &&
>  		   binop->right->ops->type == EXPR_VALUE) {
> -		struct expr *payload = expr->left->left;
> -		struct expr *mask = expr->left->right;
> +		struct expr *payload = binop->left;
> +		struct expr *mask = binop->right;
>  
>  		/*
>  		 * This *might* be a payload match testing header fields that
> @@ -1266,7 +1266,7 @@ static void relational_binop_postprocess(struct rule_pp_ctx *ctx, struct expr *e
>  			assert(expr->left->ops->type == EXPR_BINOP);
>  
>  			assert(binop->left == payload);
> -			expr->left = payload;
> +			expr->left = expr_clone(payload);
>  			expr_free(binop);
>  		}
>  	}
> -- 
> 2.1.4
> 
--
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/netlink_delinearize.c b/src/netlink_delinearize.c
index b119027..1ab8f43 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -1217,8 +1217,8 @@  static void relational_binop_postprocess(struct rule_pp_ctx *ctx, struct expr *e
 	} else if (binop->op == OP_AND &&
 		   binop->left->ops->type == EXPR_PAYLOAD &&
 		   binop->right->ops->type == EXPR_VALUE) {
-		struct expr *payload = expr->left->left;
-		struct expr *mask = expr->left->right;
+		struct expr *payload = binop->left;
+		struct expr *mask = binop->right;
 
 		/*
 		 * This *might* be a payload match testing header fields that
@@ -1266,7 +1266,7 @@  static void relational_binop_postprocess(struct rule_pp_ctx *ctx, struct expr *e
 			assert(expr->left->ops->type == EXPR_BINOP);
 
 			assert(binop->left == payload);
-			expr->left = payload;
+			expr->left = expr_clone(payload);
 			expr_free(binop);
 		}
 	}