Skip to content

Commit 996a58e

Browse files
committed
netfilter: nf_tables: reject table flag and netdev basechain updates
jira VULN-5118 subsystem-sync netfilter:nf_tables 4.18.0-553.16.1 commit-author Pablo Neira Ayuso <[email protected]> commit 1e1fb6f upstream-diff The upstream diff brings in cruft we don't want, and will be superseded by the next commit but is here to maintain history. netdev basechain updates are stored in the transaction object hook list. When setting on the table dormant flag, it iterates over the existing hooks in the basechain. Thus, skipping the hooks that are being added/deleted in this transaction, which leaves hook registration in inconsistent state. Reject table flag updates in combination with netdev basechain updates in the same batch: - Update table flags and add/delete basechain: Check from basechain update path if there are pending flag updates for this table. - add/delete basechain and update table flags: Iterate over the transaction list to search for basechain updates from the table update path. In both cases, the batch is rejected. Based on suggestion from Florian Westphal. Fixes: b9703ed ("netfilter: nf_tables: support for adding new devices to an existing netdev chain") Fixes: 7d937b1 ("netfilter: nf_tables: support for deleting devices in an existing netdev chain") Signed-off-by: Pablo Neira Ayuso <[email protected]> (cherry picked from commit 1e1fb6f) Signed-off-by: Greg Rose <[email protected]> Conflicts: net/netfilter/nf_tables_api.c
1 parent b0dd05c commit 996a58e

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

net/netfilter/nf_tables_api.c

+19-1
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,24 @@ static void nf_tables_table_disable(struct net *net, struct nft_table *table)
954954
#define __NFT_TABLE_F_UPDATE (__NFT_TABLE_F_WAS_DORMANT | \
955955
__NFT_TABLE_F_WAS_AWAKEN)
956956

957+
static bool nft_table_pending_update(const struct nft_ctx *ctx)
958+
{
959+
struct nft_trans *trans;
960+
961+
if (ctx->table->flags & __NFT_TABLE_F_UPDATE)
962+
return true;
963+
964+
list_for_each_entry(trans, &ctx->net->nft.commit_list, list) {
965+
if ((trans->msg_type == NFT_MSG_NEWCHAIN ||
966+
trans->msg_type == NFT_MSG_DELCHAIN) &&
967+
trans->ctx.table == ctx->table &&
968+
nft_trans_chain_update(trans))
969+
return true;
970+
}
971+
972+
return false;
973+
}
974+
957975
static int nf_tables_updtable(struct nft_ctx *ctx)
958976
{
959977
struct nft_trans *trans;
@@ -971,7 +989,7 @@ static int nf_tables_updtable(struct nft_ctx *ctx)
971989
return 0;
972990

973991
/* No dormant off/on/off/on games in single transaction */
974-
if (ctx->table->flags & __NFT_TABLE_F_UPDATE)
992+
if (nft_table_pending_update(ctx))
975993
return -EINVAL;
976994

977995
trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE,

0 commit comments

Comments
 (0)