Re: [PATCH 6.8 046/273] netfilter: nf_tables: reject table flag and netdev basechain updates

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

 



On Mon, Apr 08, 2024 at 02:55:21PM +0200, Greg Kroah-Hartman wrote:
> 6.8-stable review patch.  If anyone has any objections, please let me know.
> 
> ------------------
> 
> From: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
> 
> [ Upstream commit 1e1fb6f00f52812277963365d9bd835b9b0ea4e0 ]
> 
> 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: b9703ed44ffb ("netfilter: nf_tables: support for adding new devices to an existing netdev chain")
> Fixes: 7d937b107108f ("netfilter: nf_tables: support for deleting devices in an existing netdev chain")
> Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
> Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
> ---
>  net/netfilter/nf_tables_api.c | 31 ++++++++++++++++++++++++++++++-
>  1 file changed, 30 insertions(+), 1 deletion(-)
> 
> diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
> index 00288b31f734c..db233965631bb 100644
> --- a/net/netfilter/nf_tables_api.c
> +++ b/net/netfilter/nf_tables_api.c
> @@ -1198,6 +1198,25 @@ static void nf_tables_table_disable(struct net *net, struct nft_table *table)
>  #define __NFT_TABLE_F_UPDATE		(__NFT_TABLE_F_WAS_DORMANT | \
>  					 __NFT_TABLE_F_WAS_AWAKEN)
>  
> +static bool nft_table_pending_update(const struct nft_ctx *ctx)
> +{
> +	struct nftables_pernet *nft_net = nft_pernet(ctx->net);
> +	struct nft_trans *trans;
> +
> +	if (ctx->table->flags & __NFT_TABLE_F_UPDATE)
> +		return true;
> +
> +	list_for_each_entry(trans, &nft_net->commit_list, list) {
> +		if ((trans->msg_type == NFT_MSG_NEWCHAIN ||
                ^.........................................^

Remove this, only update is narrowed down.

Thanks.

> +		     trans->msg_type == NFT_MSG_DELCHAIN) &&
> +		    trans->ctx.table == ctx->table &&
> +		    nft_trans_chain_update(trans))
> +			return true;
> +	}
> +
> +	return false;
> +}
> +
>  static int nf_tables_updtable(struct nft_ctx *ctx)
>  {
>  	struct nft_trans *trans;
> @@ -1221,7 +1240,7 @@ static int nf_tables_updtable(struct nft_ctx *ctx)
>  		return -EOPNOTSUPP;
>  
>  	/* No dormant off/on/off/on games in single transaction */
> -	if (ctx->table->flags & __NFT_TABLE_F_UPDATE)
> +	if (nft_table_pending_update(ctx))
>  		return -EINVAL;
>  
>  	trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE,
> @@ -2619,6 +2638,13 @@ static int nf_tables_updchain(struct nft_ctx *ctx, u8 genmask, u8 policy,
>  		}
>  	}
>  
> +	if (table->flags & __NFT_TABLE_F_UPDATE &&
> +	    !list_empty(&hook.list)) {
> +		NL_SET_BAD_ATTR(extack, attr);
> +		err = -EOPNOTSUPP;
> +		goto err_hooks;
> +	}
> +
>  	if (!(table->flags & NFT_TABLE_F_DORMANT) &&
>  	    nft_is_base_chain(chain) &&
>  	    !list_empty(&hook.list)) {
> @@ -2848,6 +2874,9 @@ static int nft_delchain_hook(struct nft_ctx *ctx,
>  	struct nft_trans *trans;
>  	int err;
>  
> +	if (ctx->table->flags & __NFT_TABLE_F_UPDATE)
> +		return -EOPNOTSUPP;
> +
>  	err = nft_chain_parse_hook(ctx->net, basechain, nla, &chain_hook,
>  				   ctx->family, chain->flags, extack);
>  	if (err < 0)
> -- 
> 2.43.0
> 
> 
> 




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux