From patchwork Sat Oct 11 14:11:10 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alvaro Neira X-Patchwork-Id: 398852 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 108361400B6 for ; Sun, 12 Oct 2014 01:11:11 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752137AbaJKOLA (ORCPT ); Sat, 11 Oct 2014 10:11:00 -0400 Received: from mail-wg0-f41.google.com ([74.125.82.41]:46394 "EHLO mail-wg0-f41.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751592AbaJKOK7 (ORCPT ); Sat, 11 Oct 2014 10:10:59 -0400 Received: by mail-wg0-f41.google.com with SMTP id b13so5848500wgh.12 for ; Sat, 11 Oct 2014 07:10:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=OpCaVqV+L86nb6abpkHrUzmzxZcm46EcQm7T23s6V8c=; b=v13SKHN7C7VnZYO7iiSo0UYn3HUSyChS6JzpladnYD3rCK9u5Da5l7eBkTt8aHSXLP NgOOFfeNFSgEZhnzOH3fLnItdoXBet9VhDJcS+0inl5TLx1SwfF0AxIxwBn2GiJbQzHU PWhoWhJJGspzRCj4I8r6Kih+2yhQZ5uEKNFGmTPzc96DG7blxNJemkyhPFLwzNKUHMQ6 wD4V3akZa/I7/onxIbOip8jM7K7GRnuWdAiaWjBqpBgjrFgNBZW7bIUWopF2Zz+70Kr0 SXDWkS8JMBleWrqKLgehjil5iDLRTWxKUfW1oEuC3hDNAlu4aN/YS57srQr12xAY+mWJ Q7RQ== X-Received: by 10.180.75.229 with SMTP id f5mr10190186wiw.81.1413036657678; Sat, 11 Oct 2014 07:10:57 -0700 (PDT) Received: from localhost.localdomain (85.136.70.56.dyn.user.ono.com. [85.136.70.56]) by mx.google.com with ESMTPSA id ey6sm5817177wib.16.2014.10.11.07.10.56 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 11 Oct 2014 07:10:57 -0700 (PDT) From: Alvaro Neira Ayuso To: netfilter-devel@vger.kernel.org Cc: kaber@trash.net Subject: [nft PATCH 1/3] evaluate: fix a crash if we specify ether type or meta nfproto in reject Date: Sat, 11 Oct 2014 16:11:10 +0200 Message-Id: <1413036673-23022-1-git-send-email-alvaroneay@gmail.com> X-Mailer: git-send-email 1.7.10.4 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org If we use a rule: nft add rule bridge filter input \ ether type ip reject with icmp type host-unreachable or this: nft add rule inet filter input \ meta nfproto ipv4 reject with icmp type host-unreachable we have a segfault because we add a network dependency when we already have network context. Signed-off-by: Alvaro Neira Ayuso --- src/evaluate.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/src/evaluate.c b/src/evaluate.c index 83ef749..3e4471e 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -1204,6 +1205,9 @@ static int stmt_reject_gen_dependency(struct eval_ctx *ctx, struct stmt *stmt, static int stmt_evaluate_reject_family(struct eval_ctx *ctx, struct stmt *stmt, struct expr *expr) { + const struct proto_desc *desc, *base; + int protocol; + switch (ctx->pctx.family) { case NFPROTO_ARP: return stmt_error(ctx, stmt, "cannot use reject with arp"); @@ -1224,8 +1228,53 @@ static int stmt_evaluate_reject_family(struct eval_ctx *ctx, struct stmt *stmt, break; } break; - case NFPROTO_INET: case NFPROTO_BRIDGE: + base = ctx->pctx.protocol[PROTO_BASE_LL_HDR].desc; + desc = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; + if (desc != NULL) { + protocol = proto_find_num(base, desc); + switch (protocol) { + case __constant_htons(ETH_P_IP): + if (NFPROTO_IPV4 == stmt->reject.family) + break; + case __constant_htons(ETH_P_IPV6): + if (NFPROTO_IPV6 == stmt->reject.family) + break; + return stmt_error(ctx, stmt, + "conflicting protocols specified: ip vs ip6"); + default: + return stmt_error(ctx, stmt, + "cannot reject this ether type"); + } + break; + } + if (stmt->reject.type == NFT_REJECT_ICMPX_UNREACH) + break; + if (stmt_reject_gen_dependency(ctx, stmt, expr) < 0) + return -1; + break; + case NFPROTO_INET: + base = ctx->pctx.protocol[PROTO_BASE_LL_HDR].desc; + desc = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc; + if (desc != NULL) { + protocol = proto_find_num(base, desc); + switch (protocol) { + case NFPROTO_IPV4: + if (stmt->reject.family == NFPROTO_IPV4) + break; + return stmt_error(ctx, stmt, + "conflicting protocols specified: ip vs ip6"); + break; + case NFPROTO_IPV6: + if (stmt->reject.family == NFPROTO_IPV6) + break; + return stmt_error(ctx, stmt, + "conflicting protocols specified: ip vs ip6"); + default: + BUG("unsupported family"); + } + break; + } if (stmt->reject.type == NFT_REJECT_ICMPX_UNREACH) break; if (stmt_reject_gen_dependency(ctx, stmt, expr) < 0)