[PATCH nf-next,v2 1/2] netfilter: nf_tables: honor EINTR in ruleset validation from commit/abort path

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <pablo@xxxxxxxxxxxxx>
---
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) {
-- 
2.30.2





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux