From patchwork Tue May 20 09:20:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pablo Neira Ayuso X-Patchwork-Id: 2087913 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=netfilter.org header.i=@netfilter.org header.a=rsa-sha256 header.s=2025 header.b=a6jsu1sh; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.a=rsa-sha256 header.s=2025 header.b=a6jsu1sh; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2604:1380:45d1:ec00::1; helo=ny.mirrors.kernel.org; envelope-from=netfilter-devel+bounces-7163-incoming=patchwork.ozlabs.org@vger.kernel.org; receiver=patchwork.ozlabs.org) Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org [IPv6:2604:1380:45d1:ec00::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4b1pvK4HFtz1yDs for ; Tue, 20 May 2025 19:21:01 +1000 (AEST) Received: from smtp.subspace.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 54C3B4A6EE0 for ; Tue, 20 May 2025 09:21:11 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 76C17268FE0; Tue, 20 May 2025 09:20:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b="a6jsu1sh"; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b="a6jsu1sh" X-Original-To: netfilter-devel@vger.kernel.org Received: from mail.netfilter.org (mail.netfilter.org [217.70.190.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4BCC0268FDC for ; Tue, 20 May 2025 09:20:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.190.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747732840; cv=none; b=bFZYRxRW6ShA2MdxMW2evmqUN2cxDI4ogj3AWM5jzFzj6cNglEfhoO8AfOYBC7zGZdJMdZluMVzFmKYuf468+lpuo6+JWtFy58bB0KOAwlcZRYot6T6wncI8pyaks5mqyc7Us/wo5WJgZ0i35Qrp2nxMI92N59pGb2COsO1iN24= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747732840; c=relaxed/simple; bh=mEPc92pNyNTFwKhFE+C5fccdzYtlzQTdGiSLhdeX9Ts=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=k3HpD2uNcUcV77FRm/bUkRfLcwuZhNiIv2HJ0vyLzRuNGgE9q0DkYFC4rY0H33T3I0O3N7gcPoPRTng6nAE5YsQFseuihZYSi7yPjC2LYSz2GW1qh5aUTWADfbWnNnmKNMslfm5IbXyDEWH9BEcRjuOQX0TCFjatC1Ggt1Mettk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=netfilter.org; spf=pass smtp.mailfrom=netfilter.org; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b=a6jsu1sh; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b=a6jsu1sh; arc=none smtp.client-ip=217.70.190.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=netfilter.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=netfilter.org Received: by mail.netfilter.org (Postfix, from userid 109) id E4B286026C; Tue, 20 May 2025 11:20:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netfilter.org; s=2025; t=1747732833; bh=vsoot1rVzdvDpGZuA7MWUlKOEENVmcfygSxDimIRyqU=; h=From:To:Subject:Date:From; b=a6jsu1shOzLRW1cF/PM729ZcKg4S5imMfXqxq5eDQcgTQ69CAf5WXA4QznRcvmsDw 7eaChF8I98r9+ZsIq84N9NuKVZNElx6GwGKfqotQn3YC6jTZ87a6MHb5rCELdwdTk/ R4WdvDupfIfO80kdkJ8KJP6atalYISTnyl4MMXhNX6HZcHwOMVl/VTYpS0Gaucffxt jLleJiJujC3/UmE9ckd94m2hXrjgwoDPBG8g9MFw+6qc0lfZOoJ3AXm4gwFC07t4rw 4tek/g20T+zHDqyER3/L6YkrCbySVxeFQPKRz3C/wGjZAsHLDXVN9YuZPOzQAwD4xf 7V2se39lj+Gpg== X-Spam-Level: Received: from localhost.localdomain (mail-agni [217.70.190.124]) by mail.netfilter.org (Postfix) with ESMTPSA id 7D73660269 for ; Tue, 20 May 2025 11:20:33 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netfilter.org; s=2025; t=1747732833; bh=vsoot1rVzdvDpGZuA7MWUlKOEENVmcfygSxDimIRyqU=; h=From:To:Subject:Date:From; b=a6jsu1shOzLRW1cF/PM729ZcKg4S5imMfXqxq5eDQcgTQ69CAf5WXA4QznRcvmsDw 7eaChF8I98r9+ZsIq84N9NuKVZNElx6GwGKfqotQn3YC6jTZ87a6MHb5rCELdwdTk/ R4WdvDupfIfO80kdkJ8KJP6atalYISTnyl4MMXhNX6HZcHwOMVl/VTYpS0Gaucffxt jLleJiJujC3/UmE9ckd94m2hXrjgwoDPBG8g9MFw+6qc0lfZOoJ3AXm4gwFC07t4rw 4tek/g20T+zHDqyER3/L6YkrCbySVxeFQPKRz3C/wGjZAsHLDXVN9YuZPOzQAwD4xf 7V2se39lj+Gpg== From: Pablo Neira Ayuso To: netfilter-devel@vger.kernel.org Subject: [PATCH nf-next,v2 1/2] netfilter: nf_tables: honor EINTR in ruleset validation from commit/abort path Date: Tue, 20 May 2025 11:20:28 +0200 Message-Id: <20250520092029.190588-1-pablo@netfilter.org> X-Mailer: git-send-email 2.30.2 Precedence: bulk X-Mailing-List: netfilter-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Do not return EAGAIN to replay the transaction if table validation reports EINTR. Abort the transaction and report EINTR error instead. Fixes: 169384fbe851 ("netfilter: nf_tables: allow loop termination for pending fatal signal") Signed-off-by: Pablo Neira Ayuso Acked-by: Florian Westphal --- v2: fix check for EINTR (Phil Sutter) net/netfilter/nf_tables_api.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index b28f6730e26d..b57ef8f4834f 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -9885,6 +9885,7 @@ static int nf_tables_validate(struct net *net) { struct nftables_pernet *nft_net = nft_pernet(net); struct nft_table *table; + int err; list_for_each_entry(table, &nft_net->tables, list) { switch (table->validate_state) { @@ -9894,15 +9895,24 @@ static int nf_tables_validate(struct net *net) nft_validate_state_update(table, NFT_VALIDATE_DO); fallthrough; case NFT_VALIDATE_DO: - if (nft_table_validate(net, table) < 0) - return -EAGAIN; + err = nft_table_validate(net, table); + if (err < 0) { + if (err == -EINTR) + goto err_eintr; + return -EAGAIN; + } nft_validate_state_update(table, NFT_VALIDATE_SKIP); break; } } return 0; +err_eintr: + list_for_each_entry(table, &nft_net->tables, list) + nft_validate_state_update(table, NFT_VALIDATE_SKIP); + + return -EINTR; } /* a drop policy has to be deferred until all rules have been activated, @@ -10710,7 +10720,11 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) } /* 0. Validate ruleset, otherwise roll back for error reporting. */ - if (nf_tables_validate(net) < 0) { + err = nf_tables_validate(net); + if (err < 0) { + if (err == -EINTR) + return -EINTR; + nft_net->validate_state = NFT_VALIDATE_DO; return -EAGAIN; } @@ -11054,9 +11068,11 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) }; int err = 0; - if (action == NFNL_ABORT_VALIDATE && - nf_tables_validate(net) < 0) - err = -EAGAIN; + if (action == NFNL_ABORT_VALIDATE) { + err = nf_tables_validate(net); + if (err < 0 && err != -EINTR) + err = -EAGAIN; + } list_for_each_entry_safe_reverse(trans, next, &nft_net->commit_list, list) { From patchwork Tue May 20 09:20:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pablo Neira Ayuso X-Patchwork-Id: 2087912 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=netfilter.org header.i=@netfilter.org header.a=rsa-sha256 header.s=2025 header.b=jHFvCOC1; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.a=rsa-sha256 header.s=2025 header.b=jHFvCOC1; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2604:1380:4601:e00::3; helo=am.mirrors.kernel.org; envelope-from=netfilter-devel+bounces-7164-incoming=patchwork.ozlabs.org@vger.kernel.org; receiver=patchwork.ozlabs.org) Received: from am.mirrors.kernel.org (am.mirrors.kernel.org [IPv6:2604:1380:4601:e00::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4b1pvH3B0Hz1yDK for ; Tue, 20 May 2025 19:20:59 +1000 (AEST) Received: from smtp.subspace.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id DA71E189E15C for ; Tue, 20 May 2025 09:21:25 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D1AA0267B99; Tue, 20 May 2025 09:20:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b="jHFvCOC1"; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b="jHFvCOC1" X-Original-To: netfilter-devel@vger.kernel.org Received: from mail.netfilter.org (mail.netfilter.org [217.70.190.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6FAEC264A9F for ; Tue, 20 May 2025 09:20:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.190.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747732840; cv=none; b=M9iZclucVrFvX3Y0u3neKhiPWGtpYR8eAK6ZGkUeF/CrZExRf6ZvuzSZj1a24hb+gNjE2eaOoSiHeWccRKegHIb4JXD2f0Ozc9UJd3dKUchUDU5OStQbtHC7Y1Uv0fifblxt0PMxQElq+rXGjmjCe6CaOdVJjlr/6ulUc9uVymM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1747732840; c=relaxed/simple; bh=ICD2NDZWHI7yMi24bbnr2LismWLhWfIBqHm2sLHvCnk=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=UBdnr24FlIqpRK6jceZl9ICvFOAVoXrKgMfICwPgu3npo9JaZw00oB/14T3lYk8++teB0j3KB/5neXbjNvzQ86sapPTOFm/6nCRcKMsu4cG+dTZF2SC36NhOJdKZZTjM8ZbNG2yDp8FmvIkcmXzuux5eYJWH4BkBXCGWEjFIwgE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=netfilter.org; spf=pass smtp.mailfrom=netfilter.org; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b=jHFvCOC1; dkim=pass (2048-bit key) header.d=netfilter.org header.i=@netfilter.org header.b=jHFvCOC1; arc=none smtp.client-ip=217.70.190.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=netfilter.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=netfilter.org Received: by mail.netfilter.org (Postfix, from userid 109) id 6CF1C6026E; Tue, 20 May 2025 11:20:35 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netfilter.org; s=2025; t=1747732835; bh=/xrJ+J1ebCmsGajBVQQg8sNu8Fi8pqieHiIWnzAJ9ZM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=jHFvCOC1AdE6RxvV6mfa7Pps5cKxLU3+GJyYOETOuY+YSg6x1O7dqnEFxIwkSYKpn uxeVHzakzUV5e1MMb/fVN45PzG4+SeABHtAddJpzzBqPa2fKGjmkaiFZDOzgp0TRPS ifRIanJDbE8BZ5lXfYbEWiFklHOauZ/5IC8/b54559bg9u4SBaucaoUEokvhILDk1m +ufkrwN7oBZTNIgBr9Ik77+A2gl1c80KqH/7Yp9c0Mb3NBccJ8ioKTXJBW70pNy9rz gn6ocbVZTeJkFu+vsS80H7a6zvsR1qDxLDrEgfPYRia80T5xCwwDsI7WL2t+b2c70S xUL/t+FNeRIqg== X-Spam-Level: Received: from localhost.localdomain (mail-agni [217.70.190.124]) by mail.netfilter.org (Postfix) with ESMTPSA id E6B5C60269 for ; Tue, 20 May 2025 11:20:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netfilter.org; s=2025; t=1747732835; bh=/xrJ+J1ebCmsGajBVQQg8sNu8Fi8pqieHiIWnzAJ9ZM=; h=From:To:Subject:Date:In-Reply-To:References:From; b=jHFvCOC1AdE6RxvV6mfa7Pps5cKxLU3+GJyYOETOuY+YSg6x1O7dqnEFxIwkSYKpn uxeVHzakzUV5e1MMb/fVN45PzG4+SeABHtAddJpzzBqPa2fKGjmkaiFZDOzgp0TRPS ifRIanJDbE8BZ5lXfYbEWiFklHOauZ/5IC8/b54559bg9u4SBaucaoUEokvhILDk1m +ufkrwN7oBZTNIgBr9Ik77+A2gl1c80KqH/7Yp9c0Mb3NBccJ8ioKTXJBW70pNy9rz gn6ocbVZTeJkFu+vsS80H7a6zvsR1qDxLDrEgfPYRia80T5xCwwDsI7WL2t+b2c70S xUL/t+FNeRIqg== From: Pablo Neira Ayuso To: netfilter-devel@vger.kernel.org Subject: [PATCH nf-next,v2 2/2] netfilter: nf_tables: honor validation state in preparation phase Date: Tue, 20 May 2025 11:20:29 +0200 Message-Id: <20250520092029.190588-2-pablo@netfilter.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20250520092029.190588-1-pablo@netfilter.org> References: <20250520092029.190588-1-pablo@netfilter.org> Precedence: bulk X-Mailing-List: netfilter-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 There are three states for table validation: - SKIP, this is the initial state, skip validation from the preparation phase and the commit/abort path. - NEED, this state is entered from the preparation phase, to validate the table from the commit/abort path. In case that validation fails, this enters the DO state and the transaction is replayed. - DO, this state validates updates incremental from the preparation step for error reporting. Currently the NEED state is set on if: - A new rule contains expressions that require validation, this includes jump/goto chain. - A new set element with jump/goto chain. However, there are two issues: - Validation is performed incrementally with new rules and elements regardless the states. This patch updates the logic to perform the validation only in the DO state. - Reset validate state in case the transaction is finally aborted with with NFNL_ABORT_NONE. Otherwise, the next batch can observe the DO state and it performs the validation incrementally. Fixes: a654de8fdc18 ("netfilter: nf_tables: fix chain dependency validation") Signed-off-by: Pablo Neira Ayuso Reviewed-by: Florian Westphal --- v2: no changes net/netfilter/nf_tables_api.c | 50 ++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index b57ef8f4834f..8ef9abac4579 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -3997,16 +3997,8 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r nf_tables_rule_destroy(ctx, rule); } -/** nft_chain_validate - loop detection and hook validation - * - * @ctx: context containing call depth and base chain - * @chain: chain to validate - * - * Walk through the rules of the given chain and chase all jumps/gotos - * and set lookups until either the jump limit is hit or all reachable - * chains have been validated. - */ -int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) +static int __nft_chain_validate(const struct nft_ctx *ctx, + const struct nft_chain *chain) { struct nft_expr *expr, *last; struct nft_rule *rule; @@ -4037,6 +4029,30 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) return 0; } + +/** nft_chain_validate - loop detection and hook validation + * + * @ctx: context containing call depth and base chain + * @chain: chain to validate + * + * Walk through the rules of the given chain and chase all jumps/gotos and set + * lookups until either the jump limit is hit or all reachable chains have been + * validated. + * + * This function is called from preparation phase: initial state is SKIP which + * means that validation can be skipped entirely. However, in case of a new rule + * or set element needs validation, then the NEED state is entered and the + * validation is performed from the commit/abort phase. In case this fails, the + * transaction is aborted and it is replayed in the DO validation state, then + * incremental validation is performed for error reporting. + */ +int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) +{ + if (ctx->table->validate_state != NFT_VALIDATE_DO) + return 0; + + return __nft_chain_validate(ctx, chain); +} EXPORT_SYMBOL_GPL(nft_chain_validate); static int nft_table_validate(struct net *net, const struct nft_table *table) @@ -4044,6 +4060,7 @@ static int nft_table_validate(struct net *net, const struct nft_table *table) struct nft_chain *chain; struct nft_ctx ctx = { .net = net, + .table = (struct nft_table *)table, .family = table->family, }; int err; @@ -4053,7 +4070,7 @@ static int nft_table_validate(struct net *net, const struct nft_table *table) continue; ctx.chain = chain; - err = nft_chain_validate(&ctx, chain); + err = __nft_chain_validate(&ctx, chain); if (err < 0) return err; @@ -11063,15 +11080,24 @@ static int __nf_tables_abort(struct net *net, enum nfnl_abort_action action) struct nft_trans *trans, *next; LIST_HEAD(set_update_list); struct nft_trans_elem *te; + struct nft_table *table; struct nft_ctx ctx = { .net = net, }; int err = 0; - if (action == NFNL_ABORT_VALIDATE) { + switch (action) { + case NFNL_ABORT_NONE: + list_for_each_entry(table, &nft_net->tables, list) + nft_validate_state_update(table, NFT_VALIDATE_SKIP); + break; + case NFNL_ABORT_AUTOLOAD: + break; + case NFNL_ABORT_VALIDATE: err = nf_tables_validate(net); if (err < 0 && err != -EINTR) err = -EAGAIN; + break; } list_for_each_entry_safe_reverse(trans, next, &nft_net->commit_list,