Re: [PATCH] segtree: bail out on concatenations

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

 



On Fri, Apr 03, 2020 at 02:03:51PM +0200, Pablo Neira Ayuso wrote:
> On Thu, Apr 02, 2020 at 11:49:41PM +0200, Pablo Neira Ayuso wrote:
> > This patch adds a lazy check to validate that the first element is not a
> > concatenation. The segtree code does not support for concatenations,
> > bail out with EOPNOTSUPP.
> >
> >  # nft add element x y { 10.0.0.0/8 . 192.168.1.3-192.168.1.9 . 1024-65535 }
> >  Error: Could not process rule: Operation not supported
> >  add element x y { 10.0.0.0/8 . 192.168.1.3-192.168.1.9 . 1024-65535 }
> >  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >
> > Otherwise, the segtree code barfs with:
> >
> >  BUG: invalid range expression type concat
> 
> Hm.
> 
> I'm afraid this patch is not enough, the following ruleset crashes
> in old kernels with recent nft:
> 
> flush ruleset
> 
> table inet filter {
>         set test {
>                 type ipv4_addr . ipv4_addr . inet_service
>                 flags interval,timeout
>                 elements = { 1.1.1.1 . 2.2.2.2 . 30 ,
>                              2.2.2.2 . 3.3.3.3 . 40 ,
>                              3.3.3.3 . 4.4.4.4 . 50 }
>         }
> 
>         chain output {
>                 type filter hook output priority 0; policy accept;
>                 ip saddr . ip daddr . tcp dport @test counter
>         }
> }
> 
> Old kernel obviously does not support for concatenation with intervals.
> 
> I think Stefano's NFT_SET_CONCAT flag needs to be restored in the
> kernel (see attached patch) to deal with old kernel properly.
> 
> On set creation, old kernels bail out since they do not know what to
> do with this patch.

... with this flag. *sigh*

> Then, the next problem is that the kernel says -EINVAL in this case,
> this error code is bad. It should only be used for malformed messages,
> if NFT_SET_CONCAT is set on and kernel does not support this, it
> should instead just report EOPNOTSUPP (see the second patch in this
> email). I'm also updating the error code for the object maps since
> there might be a need to introduce new objects in the future.
> 
> Thanks.

> diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
> index 30f2a87270dc..4565456c0ef4 100644
> --- a/include/uapi/linux/netfilter/nf_tables.h
> +++ b/include/uapi/linux/netfilter/nf_tables.h
> @@ -276,6 +276,7 @@ enum nft_rule_compat_attributes {
>   * @NFT_SET_TIMEOUT: set uses timeouts
>   * @NFT_SET_EVAL: set can be updated from the evaluation path
>   * @NFT_SET_OBJECT: set contains stateful objects
> + * @NFT_SET_CONCAT: set contains a concatenation
>   */
>  enum nft_set_flags {
>  	NFT_SET_ANONYMOUS		= 0x1,
> @@ -285,6 +286,7 @@ enum nft_set_flags {
>  	NFT_SET_TIMEOUT			= 0x10,
>  	NFT_SET_EVAL			= 0x20,
>  	NFT_SET_OBJECT			= 0x40,
> +	NFT_SET_CONCAT			= 0x80,
>  };
>  
>  /**
> diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
> index d0ab5ffa1e2c..235762b91dd4 100644
> --- a/net/netfilter/nf_tables_api.c
> +++ b/net/netfilter/nf_tables_api.c
> @@ -3961,7 +3961,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
>  		if (flags & ~(NFT_SET_ANONYMOUS | NFT_SET_CONSTANT |
>  			      NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
>  			      NFT_SET_MAP | NFT_SET_EVAL |
> -			      NFT_SET_OBJECT))
> +			      NFT_SET_OBJECT | NFT_SET_CONCAT))
>  			return -EINVAL;
>  		/* Only one of these operations is supported */
>  		if ((flags & (NFT_SET_MAP | NFT_SET_OBJECT)) ==
> -- 
> 2.11.0
> 

> diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
> index d0ab5ffa1e2c..63e38ac1c0f8 100644
> --- a/net/netfilter/nf_tables_api.c
> +++ b/net/netfilter/nf_tables_api.c
> @@ -3962,7 +3962,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
>  			      NFT_SET_INTERVAL | NFT_SET_TIMEOUT |
>  			      NFT_SET_MAP | NFT_SET_EVAL |
>  			      NFT_SET_OBJECT | NFT_SET_CONCAT))
> -			return -EINVAL;
> +			return -EOPNOTSUPP;
>  		/* Only one of these operations is supported */
>  		if ((flags & (NFT_SET_MAP | NFT_SET_OBJECT)) ==
>  			     (NFT_SET_MAP | NFT_SET_OBJECT))
> @@ -4000,7 +4000,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
>  		objtype = ntohl(nla_get_be32(nla[NFTA_SET_OBJ_TYPE]));
>  		if (objtype == NFT_OBJECT_UNSPEC ||
>  		    objtype > NFT_OBJECT_MAX)
> -			return -EINVAL;
> +			return -EOPNOTSUPP;
>  	} else if (flags & NFT_SET_OBJECT)
>  		return -EINVAL;
>  	else
> -- 
> 2.11.0
> 




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

  Powered by Linux