From patchwork Tue Apr 12 09:44:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arturo Borrero X-Patchwork-Id: 609327 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 3qkhq21WCYz9sBc for ; Tue, 12 Apr 2016 19:44:30 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932314AbcDLJo3 (ORCPT ); Tue, 12 Apr 2016 05:44:29 -0400 Received: from smtp3.cica.es ([150.214.5.190]:46220 "EHLO smtp.cica.es" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932110AbcDLJo2 (ORCPT ); Tue, 12 Apr 2016 05:44:28 -0400 Received: from localhost (unknown [127.0.0.1]) by smtp.cica.es (Postfix) with ESMTP id 86A3651F2A3; Tue, 12 Apr 2016 09:44:25 +0000 (UTC) X-Virus-Scanned: amavisd-new at cica.es Received: from smtp.cica.es ([127.0.0.1]) by localhost (mail.cica.es [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id EUOyWP-juPAi; Tue, 12 Apr 2016 11:44:19 +0200 (CEST) Received: from nfdev2.cica.es (nfdev2.cica.es [IPv6:2a00:9ac0:c1ca:31::221]) by smtp.cica.es (Postfix) with ESMTP id ACD6851F284; Tue, 12 Apr 2016 11:44:18 +0200 (CEST) Subject: [nft PATCH v3] src/evaluate.c: improve rule management checks From: Arturo Borrero Gonzalez To: netfilter-devel@vger.kernel.org Cc: pablo@netfilter.org Date: Tue, 12 Apr 2016 11:44:17 +0200 Message-ID: <146045423317.18092.10497374259960545713.stgit@nfdev2.cica.es> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org Improve checks (and error reporting) for basic rule management operations. This includes a fix for netfilter bug #965. Netfilter bug: http://bugzilla.netfilter.org/show_bug.cgi?id=965 Reported-by: Jesper Sander Lindgren Suggested-by: Pablo Neira Ayuso Signed-off-by: Arturo Borrero Gonzalez --- v3: refreshed error messages with Pablo's suggestions src/evaluate.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) -- 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 --git a/src/evaluate.c b/src/evaluate.c index 473f014..d9ac854 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -65,6 +65,12 @@ static int __fmtstring(4, 5) __stmt_binary_error(struct eval_ctx *ctx, __stmt_binary_error(ctx, &(s1)->location, NULL, fmt, ## args) #define cmd_error(ctx, fmt, args...) \ __stmt_binary_error(ctx, &(ctx->cmd)->location, NULL, fmt, ## args) +#define handle_error(ctx, fmt, args...) \ + __stmt_binary_error(ctx, &ctx->cmd->handle.handle.location, NULL, fmt, ## args) +#define position_error(ctx, fmt, args...) \ + __stmt_binary_error(ctx, &ctx->cmd->handle.position.location, NULL, fmt, ## args) +#define handle_position_error(ctx, fmt, args...) \ + __stmt_binary_error(ctx, &ctx->cmd->handle.handle.location, &ctx->cmd->handle.position.location, fmt, ## args) static int __fmtstring(3, 4) set_error(struct eval_ctx *ctx, const struct set *set, @@ -2160,11 +2166,68 @@ static int set_evaluate(struct eval_ctx *ctx, struct set *set) return 0; } +static int rule_evaluate_cmd(struct eval_ctx *ctx) +{ + struct handle *handle = &ctx->cmd->handle; + + /* allowed: + * - insert [position] (no handle) + * - add [position] (no handle) + * - replace (no position) + * - delete (no position) + */ + + switch (ctx->cmd->op) { + case CMD_INSERT: + if (handle->handle.id && handle->position.id) + return handle_position_error(ctx, "use only `position'" + " instead"); + + if (handle->handle.id) + return handle_error(ctx, "use `position' instead"); + break; + case CMD_ADD: + if (handle->handle.id && handle->position.id) + return handle_position_error(ctx, "use only `position'" + " instead"); + + if (handle->handle.id) + return handle_error(ctx, "use `position' instead"); + + break; + case CMD_REPLACE: + if (handle->handle.id && handle->position.id) + return handle_position_error(ctx, "use only `handle' " + "instead"); + if (handle->position.id) + return position_error(ctx, "use `handle' instead"); + if (!handle->handle.id) + return cmd_error(ctx, "missing `handle'"); + break; + case CMD_DELETE: + if (handle->handle.id && handle->position.id) + return handle_position_error(ctx, "use only `handle' " + "instead"); + if (handle->position.id) + return position_error(ctx, "use `handle' instead"); + if (!handle->handle.id) + return cmd_error(ctx, "missing `handle'"); + break; + default: + BUG("unkown command type %u\n", ctx->cmd->op); + } + + return 0; +} + static int rule_evaluate(struct eval_ctx *ctx, struct rule *rule) { struct stmt *stmt, *tstmt = NULL; struct error_record *erec; + if (rule_evaluate_cmd(ctx) < 0) + return -1; + proto_ctx_init(&ctx->pctx, rule->handle.family); memset(&ctx->ectx, 0, sizeof(ctx->ectx)); @@ -2345,8 +2408,11 @@ static int cmd_evaluate_delete(struct eval_ctx *ctx, struct cmd *cmd) return ret; return setelem_evaluate(ctx, &cmd->expr); - case CMD_OBJ_SET: case CMD_OBJ_RULE: + if (rule_evaluate_cmd(ctx) < 0) + return -1; + /* fall through */ + case CMD_OBJ_SET: case CMD_OBJ_CHAIN: case CMD_OBJ_TABLE: return 0;