stable fixes for 4.19
Subsystems (2)
Pablo Neira Ayuso
maintainercover stable fixes for 4.19
Hi Greg, Sasha,
This is a batch of -stable backport fixes for 4.19. This batch includes dependency patches which are not currently in the 4.19 branch.
The following list shows the backported patches, I am using original commit IDs for reference:
1) 4f16d25c68ec ("netfilter: nftables: add nft_parse_register_load() and use it")
2) 345023b0db31 ("netfilter: nftables: add nft_parse_register_store() and use it")
3) 08a01c11a5bb ("netfilter: nftables: statify nft_parse_register()")
4) 6e1acfa387b9 ("netfilter: nf_tables: validate registers coming from userspace.")
5) 20a1452c3542 ("netfilter: nf_tables: add nft_setelem_parse_key()")
6) fdb9c405e35b ("netfilter: nf_tables: allow up to 64 bytes in the set element data area")
7) 7e6bc1f6cabc ("netfilter: nf_tables: stricter validation of element data")
8) 5a2f3dc31811 ("netfilter: nf_tables: validate NFTA_SET_ELEM_OBJREF based on NFT_SET_OBJECT flag")
9) 36d5b2913219 ("netfilter: nf_tables: do not allow RULE_ID to refer to another chain")
Patches #1, #2, #3, #5, #6 are dependencies.
Please apply,
Thanks,
Pablo Neira Ayuso (9):
netfilter: nftables: add nft_parse_register_load() and use it
netfilter: nftables: add nft_parse_register_store() and use it
netfilter: nftables: statify nft_parse_register()
netfilter: nf_tables: validate registers coming from userspace.
netfilter: nf_tables: add nft_setelem_parse_key()
netfilter: nf_tables: allow up to 64 bytes in the set element data area
netfilter: nf_tables: stricter validation of element data
netfilter: nf_tables: validate NFTA_SET_ELEM_OBJREF based on NFT_SET_OBJECT flag
netfilter: nf_tables: do not allow RULE_ID to refer to another chain
include/net/netfilter/nf_tables.h | 15 +- include/net/netfilter/nf_tables_core.h | 9 +- include/net/netfilter/nft_fib.h | 2 +- include/net/netfilter/nft_masq.h | 4 +- include/net/netfilter/nft_redir.h | 4 +- net/ipv4/netfilter/nft_dup_ipv4.c | 18 +- net/ipv6/netfilter/nft_dup_ipv6.c | 18 +- net/netfilter/nf_tables_api.c | 228 ++++++++++++++++--------- net/netfilter/nft_bitwise.c | 14 +- net/netfilter/nft_byteorder.c | 14 +- net/netfilter/nft_cmp.c | 8 +- net/netfilter/nft_ct.c | 12 +- net/netfilter/nft_dup_netdev.c | 6 +- net/netfilter/nft_dynset.c | 12 +- net/netfilter/nft_exthdr.c | 14 +- net/netfilter/nft_fib.c | 5 +- net/netfilter/nft_fwd_netdev.c | 18 +- net/netfilter/nft_hash.c | 25 ++- net/netfilter/nft_immediate.c | 6 +- net/netfilter/nft_lookup.c | 14 +- net/netfilter/nft_masq.c | 14 +- net/netfilter/nft_meta.c | 12 +- net/netfilter/nft_nat.c | 35 ++-- net/netfilter/nft_numgen.c | 15 +- net/netfilter/nft_objref.c | 6 +- net/netfilter/nft_osf.c | 8 +- net/netfilter/nft_payload.c | 10 +- net/netfilter/nft_queue.c | 12 +- net/netfilter/nft_range.c | 6 +- net/netfilter/nft_redir.c | 14 +- net/netfilter/nft_rt.c | 7 +- net/netfilter/nft_socket.c | 7 +- net/netfilter/nft_tproxy.c | 14 +- net/netfilter/nft_tunnel.c | 8 +- 34 files changed, 328 insertions(+), 286 deletions(-)
Signature · 1 line
2.30.2
Pablo Neira Ayuso
maintainerPATCH 1/9 netfilter: nftables: add nft_parse_register_load() and use it
[ 4f16d25c68ec844299a4df6ecbb0234eaf88a935 ]
This new function combines the netlink register attribute parser and the load validation function.
This update requires to replace:
enum nft_registers sreg:8;
in many of the expression private areas otherwise compiler complains with:
error: cannot take address of bit-field ‘sreg’
when passing the register field as reference.
--- include/net/netfilter/nf_tables.h | 2 +- include/net/netfilter/nf_tables_core.h | 5 ++-- include/net/netfilter/nft_masq.h | 4 +-- include/net/netfilter/nft_redir.h | 4 +-- net/ipv4/netfilter/nft_dup_ipv4.c | 18 ++++++------- net/ipv6/netfilter/nft_dup_ipv6.c | 18 ++++++------- net/netfilter/nf_tables_api.c | 18 +++++++++++-- net/netfilter/nft_bitwise.c | 6 ++--- net/netfilter/nft_byteorder.c | 6 ++--- net/netfilter/nft_cmp.c | 8 +++--- net/netfilter/nft_ct.c | 5 ++-- net/netfilter/nft_dup_netdev.c | 6 ++--- net/netfilter/nft_dynset.c | 12 ++++----- net/netfilter/nft_exthdr.c | 6 ++--- net/netfilter/nft_fwd_netdev.c | 18 ++++++------- net/netfilter/nft_hash.c | 10 +++++--- net/netfilter/nft_lookup.c | 6 ++--- net/netfilter/nft_masq.c | 14 ++++------- net/netfilter/nft_meta.c | 5 ++-- net/netfilter/nft_nat.c | 35 +++++++++++--------------- net/netfilter/nft_objref.c | 6 ++--- net/netfilter/nft_payload.c | 4 +-- net/netfilter/nft_queue.c | 12 ++++----- net/netfilter/nft_range.c | 6 ++--- net/netfilter/nft_redir.c | 14 ++++------- net/netfilter/nft_tproxy.c | 14 +++++------ 26 files changed, 130 insertions(+), 132 deletions(-)
include/net/netfilter/nf_tables.h +1 -1
@@ -194,7 +194,7 @@ int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest);unsigned int nft_parse_register (const struct nlattr *attr);int nft_dump_register (struct sk_buff *skb,unsigned int attr,unsigned int reg); -int nft_validate_register_load (enum nft_registers reg,unsigned int len); +int nft_parse_register_load (const struct nlattr *attr,u8 *sreg,u32 len); int nft_validate_register_store(const struct nft_ctx *ctx, enum nft_registers reg, const struct nft_data *data,
include/net/netfilter/nf_tables_core.h +3 -2
@@ -21,7 +21,8 @@ void nf_tables_core_module_exit(void);struct nft_cmp_fast_expr {u32 data; -enum nft_registers sreg:8 ; +u32 mask; +u8 sreg;u8 len; };
@@ -54,7 +55,7 @@ struct nft_payload_set { enum nft_payload_bases base:8;u8 offset;u8 len; - enum nft_registers sreg:8; +u8 sreg;u8 csum_type;u8 csum_offset;u8 csum_flags;
include/net/netfilter/nft_masq.h +2 -2
@@ -4,8 +4,8 @@struct nft_masq {u32 flags; -enum nft_registers sreg_proto_min:8 ; -enum nft_registers sreg_proto_max:8 ; +u8 sreg_proto_min; +u8 sreg_proto_max; };extern const struct nla_policy nft_masq_policy[];
include/net/netfilter/nft_redir.h +2 -2
@@ -3,8 +3,8 @@#define _NFT_REDIR_H_struct nft_redir { -enum nft_registers sreg_proto_min:8 ; -enum nft_registers sreg_proto_max:8 ; +u8 sreg_proto_min; +u8 sreg_proto_max;u16 flags; };
net/ipv4/netfilter/nft_dup_ipv4.c +9 -9
@@ -16,8 +16,8 @@#include <net/netfilter/ipv4/nf_dup_ipv4.h> struct nft_dup_ipv4 { -enum nft_registers sreg_addr:8 ; -enum nft_registers sreg_dev:8 ; +u8 sreg_addr; +u8 sreg_dev; }; static void nft_dup_ipv4_eval(const struct nft_expr *expr,
@@ -43,16 +43,16 @@ static int nft_dup_ipv4_init(const struct nft_ctx *ctx,if (tb[NFTA_DUP_SREG_ADDR ] ==NULL )return -EINVAL ; - priv->sreg_addr =nft_parse_register (tb[NFTA_DUP_SREG_ADDR ]); - err =nft_validate_register_load (priv->sreg_addr,sizeof (struct in_addr )); + err =nft_parse_register_load (tb[NFTA_DUP_SREG_ADDR ], &priv->sreg_addr, +sizeof (struct in_addr ));if (err <0 )return err; -if (tb[NFTA_DUP_SREG_DEV ] !=NULL ) { - priv->sreg_dev =nft_parse_register (tb[NFTA_DUP_SREG_DEV ]); -return nft_validate_register_load (priv->sreg_dev,sizeof (int )); - } -return 0 ; +if (tb[NFTA_DUP_SREG_DEV ]) + err =nft_parse_register_load (tb[NFTA_DUP_SREG_DEV ], + &priv->sreg_dev,sizeof (int )); + +return err; }static int nft_dup_ipv4_dump (struct sk_buff *skb,const struct nft_expr *expr)
net/ipv6/netfilter/nft_dup_ipv6.c +9 -9
@@ -16,8 +16,8 @@#include <net/netfilter/ipv6/nf_dup_ipv6.h> struct nft_dup_ipv6 { -enum nft_registers sreg_addr:8 ; -enum nft_registers sreg_dev:8 ; +u8 sreg_addr; +u8 sreg_dev; }; static void nft_dup_ipv6_eval(const struct nft_expr *expr,
@@ -41,16 +41,16 @@ static int nft_dup_ipv6_init(const struct nft_ctx *ctx,if (tb[NFTA_DUP_SREG_ADDR ] ==NULL )return -EINVAL ; - priv->sreg_addr =nft_parse_register (tb[NFTA_DUP_SREG_ADDR ]); - err =nft_validate_register_load (priv->sreg_addr,sizeof (struct in6_addr )); + err =nft_parse_register_load (tb[NFTA_DUP_SREG_ADDR ], &priv->sreg_addr, +sizeof (struct in6_addr ));if (err <0 )return err; -if (tb[NFTA_DUP_SREG_DEV ] !=NULL ) { - priv->sreg_dev =nft_parse_register (tb[NFTA_DUP_SREG_DEV ]); -return nft_validate_register_load (priv->sreg_dev,sizeof (int )); - } -return 0 ; +if (tb[NFTA_DUP_SREG_DEV ]) + err =nft_parse_register_load (tb[NFTA_DUP_SREG_DEV ], + &priv->sreg_dev,sizeof (int )); + +return err; }static int nft_dup_ipv6_dump (struct sk_buff *skb,const struct nft_expr *expr)
net/netfilter/nf_tables_api.c +16 -2
@@ -7018,7 +7018,7 @@ EXPORT_SYMBOL_GPL(nft_dump_register);* Validate that the input register is one of the general purpose * registers and that the length of the load is within the bounds. */ -int nft_validate_register_load (enum nft_registers reg,unsigned int len) +static int nft_validate_register_load (enum nft_registers reg,unsigned int len) {if (reg <NFT_REG_1 *NFT_REG_SIZE /NFT_REG32_SIZE )return -EINVAL ;
@@ -7029,7 +7029,21 @@ int nft_validate_register_load(enum nft_registers reg, unsigned int len)return 0 ; } -EXPORT_SYMBOL_GPL (nft_validate_register_load); + +int nft_parse_register_load (const struct nlattr *attr,u8 *sreg,u32 len) +{ +u32 reg; +int err; + + reg =nft_parse_register (attr); + err =nft_validate_register_load (reg, len); +if (err <0 ) +return err; + + *sreg = reg; +return 0 ; +} +EXPORT_SYMBOL_GPL (nft_parse_register_load);/** * nft_validate_register_store - validate an expressions' register store
net/netfilter/nft_bitwise.c +3 -3
@@ -18,7 +18,7 @@#include <net/netfilter/nf_tables.h> struct nft_bitwise { -enum nft_registers sreg:8 ; +u8 sreg;enum nft_registers dreg:8 ;u8 len;struct nft_data mask;
@@ -68,8 +68,8 @@ static int nft_bitwise_init(const struct nft_ctx *ctx, priv->len = len; - priv->sreg =nft_parse_register (tb[NFTA_BITWISE_SREG ]); - err =nft_validate_register_load (priv->sreg, priv->len); + err =nft_parse_register_load (tb[NFTA_BITWISE_SREG ], &priv->sreg, + priv->len);if (err <0 )return err;
net/netfilter/nft_byteorder.c +3 -3
@@ -19,7 +19,7 @@#include <net/netfilter/nf_tables.h> struct nft_byteorder { -enum nft_registers sreg:8 ; +u8 sreg;enum nft_registers dreg:8 ;enum nft_byteorder_ops op:8 ;u8 len;
@@ -133,14 +133,14 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,return -EINVAL ; } - priv->sreg =nft_parse_register (tb[NFTA_BYTEORDER_SREG ]); err =nft_parse_u32_check (tb[NFTA_BYTEORDER_LEN ],U8_MAX , &len);if (err <0 )return err; priv->len = len; - err =nft_validate_register_load (priv->sreg, priv->len); + err =nft_parse_register_load (tb[NFTA_BYTEORDER_SREG ], &priv->sreg, + priv->len);if (err <0 )return err;
net/netfilter/nft_cmp.c +3 -5
@@ -19,7 +19,7 @@struct nft_cmp_expr {struct nft_data data; -enum nft_registers sreg:8 ; +u8 sreg;u8 len;enum nft_cmp_ops op:8 ; };
@@ -88,8 +88,7 @@ static int nft_cmp_init(const struct nft_ctx *ctx, const struct nft_expr *expr,return err; } - priv->sreg =nft_parse_register (tb[NFTA_CMP_SREG ]); - err =nft_validate_register_load (priv->sreg, desc.len); + err =nft_parse_register_load (tb[NFTA_CMP_SREG ], &priv->sreg, desc.len);if (err <0 )return err;
@@ -139,8 +138,7 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx,if (err <0 )return err; - priv->sreg =nft_parse_register (tb[NFTA_CMP_SREG ]); - err =nft_validate_register_load (priv->sreg, desc.len); + err =nft_parse_register_load (tb[NFTA_CMP_SREG ], &priv->sreg, desc.len);if (err <0 )return err;
net/netfilter/nft_ct.c +2 -3
@@ -30,7 +30,7 @@ struct nft_ct { enum ip_conntrack_dir dir:8;union {enum nft_registers dreg:8 ; -enum nft_registers sreg:8 ; +u8 sreg; }; };
@@ -581,8 +581,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx, } } - priv->sreg =nft_parse_register (tb[NFTA_CT_SREG ]); - err =nft_validate_register_load (priv->sreg, len); + err =nft_parse_register_load (tb[NFTA_CT_SREG ], &priv->sreg, len);if (err <0 ) goto err1;
net/netfilter/nft_dup_netdev.c +3 -3
@@ -16,7 +16,7 @@#include <net/netfilter/nf_dup_netdev.h> struct nft_dup_netdev { -enum nft_registers sreg_dev:8 ; +u8 sreg_dev; }; static void nft_dup_netdev_eval(const struct nft_expr *expr,
@@ -42,8 +42,8 @@ static int nft_dup_netdev_init(const struct nft_ctx *ctx,if (tb[NFTA_DUP_SREG_DEV ] ==NULL )return -EINVAL ; - priv->sreg_dev =nft_parse_register (tb[NFTA_DUP_SREG_DEV ]); -return nft_validate_register_load (priv->sreg_dev,sizeof (int )); +return nft_parse_register_load (tb[NFTA_DUP_SREG_DEV ], &priv->sreg_dev, +sizeof (int )); }static const struct nft_expr_ops nft_dup_netdev_ingress_ops;
net/netfilter/nft_dynset.c +6 -6
@@ -20,8 +20,8 @@ struct nft_dynset {struct nft_set *set;struct nft_set_ext_tmpl tmpl; enum nft_dynset_ops op:8; - enum nft_registers sreg_key:8; - enum nft_registers sreg_data:8; +u8 sreg_key; +u8 sreg_data;bool invert;u64 timeout;struct nft_expr *expr;
@@ -166,8 +166,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx, tb[NFTA_DYNSET_TIMEOUT]))); } - priv->sreg_key =nft_parse_register (tb[NFTA_DYNSET_SREG_KEY ]); - err =nft_validate_register_load (priv->sreg_key, set->klen); + err =nft_parse_register_load (tb[NFTA_DYNSET_SREG_KEY ], &priv->sreg_key, + set->klen);if (err <0 )return err;
@@ -177,8 +177,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx,if (set->dtype ==NFT_DATA_VERDICT )return -EOPNOTSUPP ; - priv->sreg_data =nft_parse_register (tb[NFTA_DYNSET_SREG_DATA ]); - err =nft_validate_register_load (priv->sreg_data, set->dlen); + err =nft_parse_register_load (tb[NFTA_DYNSET_SREG_DATA ], + &priv->sreg_data, set->dlen);if (err <0 )return err; }else if (set->flags &NFT_SET_MAP )
net/netfilter/nft_exthdr.c +3 -3
@@ -23,7 +23,7 @@ struct nft_exthdr {u8 len;u8 op; enum nft_registers dreg:8; - enum nft_registers sreg:8; +u8 sreg;u8 flags; };
@@ -308,11 +308,11 @@ static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx, priv->type =nla_get_u8 (tb[NFTA_EXTHDR_TYPE ]); priv->offset = offset; priv->len = len; - priv->sreg =nft_parse_register (tb[NFTA_EXTHDR_SREG ]); priv->flags = flags; priv->op = op; -return nft_validate_register_load (priv->sreg, priv->len); +return nft_parse_register_load (tb[NFTA_EXTHDR_SREG ], &priv->sreg, + priv->len); }static int nft_exthdr_dump_common (struct sk_buff *skb,const struct nft_exthdr *priv)
net/netfilter/nft_fwd_netdev.c +9 -9
@@ -20,7 +20,7 @@#include <net/ip.h> struct nft_fwd_netdev { -enum nft_registers sreg_dev:8 ; +u8 sreg_dev; }; static void nft_fwd_netdev_eval(const struct nft_expr *expr,
@@ -49,8 +49,8 @@ static int nft_fwd_netdev_init(const struct nft_ctx *ctx,if (tb[NFTA_FWD_SREG_DEV ] ==NULL )return -EINVAL ; - priv->sreg_dev =nft_parse_register (tb[NFTA_FWD_SREG_DEV ]); -return nft_validate_register_load (priv->sreg_dev,sizeof (int )); +return nft_parse_register_load (tb[NFTA_FWD_SREG_DEV ], &priv->sreg_dev, +sizeof (int )); }static const struct nft_expr_ops nft_fwd_netdev_ingress_ops;
@@ -69,8 +69,8 @@ static int nft_fwd_netdev_dump(struct sk_buff *skb, const struct nft_expr *expr) }struct nft_fwd_neigh { -enum nft_registers sreg_dev:8 ; -enum nft_registers sreg_addr:8 ; +u8 sreg_dev; +u8 sreg_addr;u8 nfproto; };
@@ -148,8 +148,6 @@ static int nft_fwd_neigh_init(const struct nft_ctx *ctx, !tb[NFTA_FWD_NFPROTO])return -EINVAL ; - priv->sreg_dev =nft_parse_register (tb[NFTA_FWD_SREG_DEV ]); - priv->sreg_addr =nft_parse_register (tb[NFTA_FWD_SREG_ADDR ]); priv->nfproto =ntohl (nla_get_be32 (tb[NFTA_FWD_NFPROTO ]));switch (priv->nfproto) {
@@ -163,11 +161,13 @@ static int nft_fwd_neigh_init(const struct nft_ctx *ctx,return -EOPNOTSUPP ; } - err =nft_validate_register_load (priv->sreg_dev,sizeof (int )); + err =nft_parse_register_load (tb[NFTA_FWD_SREG_DEV ], &priv->sreg_dev, +sizeof (int ));if (err <0 )return err; -return nft_validate_register_load (priv->sreg_addr, addr_len); +return nft_parse_register_load (tb[NFTA_FWD_SREG_ADDR ], &priv->sreg_addr, + addr_len); }static const struct nft_expr_ops nft_fwd_netdev_ingress_ops;
net/netfilter/nft_hash.c +6 -4
@@ -18,7 +18,7 @@#include <linux/jhash.h> struct nft_jhash { -enum nft_registers sreg:8 ; +u8 sreg;enum nft_registers dreg:8 ;u8 len;bool autogen_seed:1 ;
@@ -136,7 +136,6 @@ static int nft_jhash_init(const struct nft_ctx *ctx,if (tb[NFTA_HASH_OFFSET ]) priv->offset =ntohl (nla_get_be32 (tb[NFTA_HASH_OFFSET ])); - priv->sreg =nft_parse_register (tb[NFTA_HASH_SREG ]); priv->dreg =nft_parse_register (tb[NFTA_HASH_DREG ]); err =nft_parse_u32_check (tb[NFTA_HASH_LEN ],U8_MAX , &len);
@@ -147,6 +146,10 @@ static int nft_jhash_init(const struct nft_ctx *ctx, priv->len = len; + err =nft_parse_register_load (tb[NFTA_HASH_SREG ], &priv->sreg, len); +if (err <0 ) +return err; + priv->modulus =ntohl (nla_get_be32 (tb[NFTA_HASH_MODULUS ]));if (priv->modulus <1 )return -ERANGE ;
@@ -161,8 +164,7 @@ static int nft_jhash_init(const struct nft_ctx *ctx,get_random_bytes (&priv->seed,sizeof (priv->seed)); } -return nft_validate_register_load (priv->sreg, len) && -nft_validate_register_store (ctx, priv->dreg,NULL , +return nft_validate_register_store (ctx, priv->dreg,NULL ,NFT_DATA_VALUE ,sizeof (u32)); }
net/netfilter/nft_lookup.c +3 -3
@@ -20,7 +20,7 @@struct nft_lookup {struct nft_set *set; -enum nft_registers sreg:8 ; +u8 sreg;enum nft_registers dreg:8 ;bool invert;struct nft_set_binding binding;
@@ -76,8 +76,8 @@ static int nft_lookup_init(const struct nft_ctx *ctx,if (IS_ERR (set))return PTR_ERR (set); - priv->sreg =nft_parse_register (tb[NFTA_LOOKUP_SREG ]); - err =nft_validate_register_load (priv->sreg, set->klen); + err =nft_parse_register_load (tb[NFTA_LOOKUP_SREG ], &priv->sreg, + set->klen);if (err <0 )return err;
net/netfilter/nft_masq.c +5 -9
@@ -53,19 +53,15 @@ int nft_masq_init(const struct nft_ctx *ctx, }if (tb[NFTA_MASQ_REG_PROTO_MIN ]) { - priv->sreg_proto_min = -nft_parse_register (tb[NFTA_MASQ_REG_PROTO_MIN ]); - - err =nft_validate_register_load (priv->sreg_proto_min, plen); + err =nft_parse_register_load (tb[NFTA_MASQ_REG_PROTO_MIN ], + &priv->sreg_proto_min, plen);if (err <0 )return err;if (tb[NFTA_MASQ_REG_PROTO_MAX ]) { - priv->sreg_proto_max = -nft_parse_register (tb[NFTA_MASQ_REG_PROTO_MAX ]); - - err =nft_validate_register_load (priv->sreg_proto_max, - plen); + err =nft_parse_register_load (tb[NFTA_MASQ_REG_PROTO_MAX ], + &priv->sreg_proto_max, + plen);if (err <0 )return err; }else {
net/netfilter/nft_meta.c +2 -3
@@ -31,7 +31,7 @@ struct nft_meta { enum nft_meta_keys key:8;union {enum nft_registers dreg:8 ; -enum nft_registers sreg:8 ; +u8 sreg; }; };
@@ -448,8 +448,7 @@ static int nft_meta_set_init(const struct nft_ctx *ctx,return -EOPNOTSUPP ; } - priv->sreg =nft_parse_register (tb[NFTA_META_SREG ]); - err =nft_validate_register_load (priv->sreg, len); + err =nft_parse_register_load (tb[NFTA_META_SREG ], &priv->sreg, len);if (err <0 )return err;
net/netfilter/nft_nat.c +14 -21
@@ -27,10 +27,10 @@#include <net/ip.h> struct nft_nat { -enum nft_registers sreg_addr_min:8 ; -enum nft_registers sreg_addr_max:8 ; -enum nft_registers sreg_proto_min:8 ; -enum nft_registers sreg_proto_max:8 ; +u8 sreg_addr_min; +u8 sreg_addr_max; +u8 sreg_proto_min; +u8 sreg_proto_max;enum nf_nat_manip_type type:8 ;u8 family;u16 flags;
@@ -160,18 +160,15 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, priv->family = family;if (tb[NFTA_NAT_REG_ADDR_MIN ]) { - priv->sreg_addr_min = -nft_parse_register (tb[NFTA_NAT_REG_ADDR_MIN ]); - err =nft_validate_register_load (priv->sreg_addr_min, alen); + err =nft_parse_register_load (tb[NFTA_NAT_REG_ADDR_MIN ], + &priv->sreg_addr_min, alen);if (err <0 )return err;if (tb[NFTA_NAT_REG_ADDR_MAX ]) { - priv->sreg_addr_max = -nft_parse_register (tb[NFTA_NAT_REG_ADDR_MAX ]); - - err =nft_validate_register_load (priv->sreg_addr_max, - alen); + err =nft_parse_register_load (tb[NFTA_NAT_REG_ADDR_MAX ], + &priv->sreg_addr_max, + alen);if (err <0 )return err; }else {
@@ -181,19 +178,15 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);if (tb[NFTA_NAT_REG_PROTO_MIN ]) { - priv->sreg_proto_min = -nft_parse_register (tb[NFTA_NAT_REG_PROTO_MIN ]); - - err =nft_validate_register_load (priv->sreg_proto_min, plen); + err =nft_parse_register_load (tb[NFTA_NAT_REG_PROTO_MIN ], + &priv->sreg_proto_min, plen);if (err <0 )return err;if (tb[NFTA_NAT_REG_PROTO_MAX ]) { - priv->sreg_proto_max = -nft_parse_register (tb[NFTA_NAT_REG_PROTO_MAX ]); - - err =nft_validate_register_load (priv->sreg_proto_max, - plen); + err =nft_parse_register_load (tb[NFTA_NAT_REG_PROTO_MAX ], + &priv->sreg_proto_max, + plen);if (err <0 )return err; }else {
net/netfilter/nft_objref.c +3 -3
@@ -97,7 +97,7 @@ static const struct nft_expr_ops nft_objref_ops = {struct nft_objref_map {struct nft_set *set; -enum nft_registers sreg:8 ; +u8 sreg;struct nft_set_binding binding; };
@@ -139,8 +139,8 @@ static int nft_objref_map_init(const struct nft_ctx *ctx,if (!(set->flags &NFT_SET_OBJECT ))return -EINVAL ; - priv->sreg =nft_parse_register (tb[NFTA_OBJREF_SET_SREG ]); - err =nft_validate_register_load (priv->sreg, set->klen); + err =nft_parse_register_load (tb[NFTA_OBJREF_SET_SREG ], &priv->sreg, + set->klen);if (err <0 )return err;
net/netfilter/nft_payload.c +2 -2
@@ -338,7 +338,6 @@ static int nft_payload_set_init(const struct nft_ctx *ctx, priv->base =ntohl (nla_get_be32 (tb[NFTA_PAYLOAD_BASE ])); priv->offset =ntohl (nla_get_be32 (tb[NFTA_PAYLOAD_OFFSET ])); priv->len =ntohl (nla_get_be32 (tb[NFTA_PAYLOAD_LEN ])); - priv->sreg =nft_parse_register (tb[NFTA_PAYLOAD_SREG ]);if (tb[NFTA_PAYLOAD_CSUM_TYPE ]) csum_type =ntohl (nla_get_be32 (tb[NFTA_PAYLOAD_CSUM_TYPE ]));
@@ -369,7 +368,8 @@ static int nft_payload_set_init(const struct nft_ctx *ctx, } priv->csum_type = csum_type; -return nft_validate_register_load (priv->sreg, priv->len); +return nft_parse_register_load (tb[NFTA_PAYLOAD_SREG ], &priv->sreg, + priv->len); }static int nft_payload_set_dump (struct sk_buff *skb,const struct nft_expr *expr)
net/netfilter/nft_queue.c +6 -6
@@ -22,10 +22,10 @@static u32 jhash_initval__read_mostly ;struct nft_queue { -enum nft_registers sreg_qnum:8 ; -u16 queuenum; -u16 queues_total; -u16 flags; +u8 sreg_qnum; +u16 queuenum; +u16 queues_total; +u16 flags; }; static void nft_queue_eval(const struct nft_expr *expr,
@@ -114,8 +114,8 @@ static int nft_queue_sreg_init(const struct nft_ctx *ctx,struct nft_queue *priv =nft_expr_priv (expr);int err; - priv->sreg_qnum =nft_parse_register (tb[NFTA_QUEUE_SREG_QNUM ]); - err =nft_validate_register_load (priv->sreg_qnum,sizeof (u32)); + err =nft_parse_register_load (tb[NFTA_QUEUE_SREG_QNUM ], + &priv->sreg_qnum,sizeof (u32));if (err <0 )return err;
net/netfilter/nft_range.c +3 -3
@@ -18,7 +18,7 @@struct nft_range_expr {struct nft_data data_from;struct nft_data data_to; -enum nft_registers sreg:8 ; +u8 sreg;u8 len;enum nft_range_ops op:8 ; };
@@ -90,8 +90,8 @@ static int nft_range_init(const struct nft_ctx *ctx, const struct nft_expr *expr goto err2; } - priv->sreg =nft_parse_register (tb[NFTA_RANGE_SREG ]); - err =nft_validate_register_load (priv->sreg, desc_from.len); + err =nft_parse_register_load (tb[NFTA_RANGE_SREG ], &priv->sreg, + desc_from.len);if (err <0 ) goto err2;
net/netfilter/nft_redir.c +5 -9
@@ -49,19 +49,15 @@ int nft_redir_init(const struct nft_ctx *ctx, plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);if (tb[NFTA_REDIR_REG_PROTO_MIN ]) { - priv->sreg_proto_min = -nft_parse_register (tb[NFTA_REDIR_REG_PROTO_MIN ]); - - err =nft_validate_register_load (priv->sreg_proto_min, plen); + err =nft_parse_register_load (tb[NFTA_REDIR_REG_PROTO_MIN ], + &priv->sreg_proto_min, plen);if (err <0 )return err;if (tb[NFTA_REDIR_REG_PROTO_MAX ]) { - priv->sreg_proto_max = -nft_parse_register (tb[NFTA_REDIR_REG_PROTO_MAX ]); - - err =nft_validate_register_load (priv->sreg_proto_max, - plen); + err =nft_parse_register_load (tb[NFTA_REDIR_REG_PROTO_MAX ], + &priv->sreg_proto_max, + plen);if (err <0 )return err; }else {
net/netfilter/nft_tproxy.c +7 -7
@@ -13,9 +13,9 @@#endif struct nft_tproxy { -enum nft_registers sreg_addr:8 ; -enum nft_registers sreg_port:8 ; -u8 family; +u8 sreg_addr; +u8 sreg_port; +u8 family; }; static void nft_tproxy_eval_v4(const struct nft_expr *expr,
@@ -254,15 +254,15 @@ static int nft_tproxy_init(const struct nft_ctx *ctx, }if (tb[NFTA_TPROXY_REG_ADDR ]) { - priv->sreg_addr =nft_parse_register (tb[NFTA_TPROXY_REG_ADDR ]); - err =nft_validate_register_load (priv->sreg_addr, alen); + err =nft_parse_register_load (tb[NFTA_TPROXY_REG_ADDR ], + &priv->sreg_addr, alen);if (err <0 )return err; }if (tb[NFTA_TPROXY_REG_PORT ]) { - priv->sreg_port =nft_parse_register (tb[NFTA_TPROXY_REG_PORT ]); - err =nft_validate_register_load (priv->sreg_port,sizeof (u16)); + err =nft_parse_register_load (tb[NFTA_TPROXY_REG_PORT ], + &priv->sreg_port,sizeof (u16));if (err <0 )return err; }
Signature · 1 line
2.30.2
Pablo Neira Ayuso
maintainerPATCH 2/9 netfilter: nftables: add nft_parse_register_store() and use it
In reply to Pablo Neira Ayuso[ 345023b0db315648ccc3c1a36aee88304a8b4d91 ]
This new function combines the netlink register attribute parser and the store validation function.
This update requires to replace:
enum nft_registers dreg:8;
in many of the expression private areas otherwise compiler complains with:
error: cannot take address of bit-field ‘dreg’
when passing the register field as reference.
--- include/net/netfilter/nf_tables.h | 8 +++--- include/net/netfilter/nf_tables_core.h | 4 +-- include/net/netfilter/nft_fib.h | 2 +- net/netfilter/nf_tables_api.c | 34 ++++++++++++++++++++++---- net/netfilter/nft_bitwise.c | 8 +++--- net/netfilter/nft_byteorder.c | 8 +++--- net/netfilter/nft_ct.c | 7 +++--- net/netfilter/nft_exthdr.c | 8 +++--- net/netfilter/nft_fib.c | 5 ++-- net/netfilter/nft_hash.c | 17 ++++++------- net/netfilter/nft_immediate.c | 6 ++--- net/netfilter/nft_lookup.c | 8 +++--- net/netfilter/nft_meta.c | 7 +++--- net/netfilter/nft_numgen.c | 15 +++++------- net/netfilter/nft_osf.c | 8 +++--- net/netfilter/nft_payload.c | 6 ++--- net/netfilter/nft_rt.c | 7 +++--- net/netfilter/nft_socket.c | 7 +++--- net/netfilter/nft_tunnel.c | 8 +++--- 19 files changed, 92 insertions(+), 81 deletions(-)
include/net/netfilter/nf_tables.h +4 -4
@@ -195,10 +195,10 @@ unsigned int nft_parse_register(const struct nlattr *attr);int nft_dump_register (struct sk_buff *skb,unsigned int attr,unsigned int reg);int nft_parse_register_load (const struct nlattr *attr,u8 *sreg,u32 len); -int nft_validate_register_store (const struct nft_ctx *ctx, -enum nft_registers reg, -const struct nft_data *data, -enum nft_data_types type,unsigned int len); +int nft_parse_register_store (const struct nft_ctx *ctx, +const struct nlattr *attr,u8 *dreg, +const struct nft_data *data, +enum nft_data_types type,unsigned int len);/** * struct nft_userdata - user defined data associated with an object
include/net/netfilter/nf_tables_core.h +2 -2
@@ -28,7 +28,7 @@ struct nft_cmp_fast_expr {struct nft_immediate_expr {struct nft_data data; -enum nft_registers dreg:8 ; +u8 dreg;u8 dlen; };
@@ -48,7 +48,7 @@ struct nft_payload { enum nft_payload_bases base:8;u8 offset;u8 len; - enum nft_registers dreg:8; +u8 dreg; };struct nft_payload_set {
include/net/netfilter/nft_fib.h +1 -1
@@ -3,7 +3,7 @@#define _NFT_FIB_H_struct nft_fib { -enum nft_registers dreg:8 ; +u8 dreg;u8 result;u32 flags; };
net/netfilter/nf_tables_api.c +29 -5
@@ -3687,6 +3687,12 @@ static int nf_tables_delset(struct net *net, struct sock *nlsk,return nft_delset (&ctx, set); } +static int nft_validate_register_store (const struct nft_ctx *ctx, +enum nft_registers reg, +const struct nft_data *data, +enum nft_data_types type, +unsigned int len); + static int nf_tables_bind_check_setelem(const struct nft_ctx *ctx, struct nft_set *set, const struct nft_set_iter *iter,
@@ -7059,10 +7065,11 @@ EXPORT_SYMBOL_GPL(nft_parse_register_load);* A value of NULL for the data means that its runtime gathered * data. */ -int nft_validate_register_store (const struct nft_ctx *ctx, -enum nft_registers reg, -const struct nft_data *data, -enum nft_data_types type,unsigned int len) +static int nft_validate_register_store (const struct nft_ctx *ctx, +enum nft_registers reg, +const struct nft_data *data, +enum nft_data_types type, +unsigned int len) {int err;
@@ -7094,7 +7101,24 @@ int nft_validate_register_store(const struct nft_ctx *ctx,return 0 ; } } -EXPORT_SYMBOL_GPL (nft_validate_register_store); + +int nft_parse_register_store (const struct nft_ctx *ctx, +const struct nlattr *attr,u8 *dreg, +const struct nft_data *data, +enum nft_data_types type,unsigned int len) +{ +int err; +u32 reg; + + reg =nft_parse_register (attr); + err =nft_validate_register_store (ctx, reg, data, type, len); +if (err <0 ) +return err; + + *dreg = reg; +return 0 ; +} +EXPORT_SYMBOL_GPL (nft_parse_register_store);static const struct nla_policy nft_verdict_policy[NFTA_VERDICT_MAX +1 ] = { [NFTA_VERDICT_CODE ] = { .type =NLA_U32 },
net/netfilter/nft_bitwise.c +4 -4
@@ -19,7 +19,7 @@struct nft_bitwise {u8 sreg; -enum nft_registers dreg:8 ; +u8 dreg;u8 len;struct nft_data mask;struct nft_data xor;
@@ -73,9 +73,9 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,if (err <0 )return err; - priv->dreg =nft_parse_register (tb[NFTA_BITWISE_DREG ]); - err =nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , priv->len); + err =nft_parse_register_store (ctx, tb[NFTA_BITWISE_DREG ], + &priv->dreg,NULL ,NFT_DATA_VALUE , + priv->len);if (err <0 )return err;
net/netfilter/nft_byteorder.c +4 -4
@@ -20,7 +20,7 @@struct nft_byteorder {u8 sreg; -enum nft_registers dreg:8 ; +u8 dreg;enum nft_byteorder_ops op:8 ;u8 len;u8 size;
@@ -144,9 +144,9 @@ static int nft_byteorder_init(const struct nft_ctx *ctx,if (err <0 )return err; - priv->dreg =nft_parse_register (tb[NFTA_BYTEORDER_DREG ]); -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , priv->len); +return nft_parse_register_store (ctx, tb[NFTA_BYTEORDER_DREG ], + &priv->dreg,NULL ,NFT_DATA_VALUE , + priv->len); }static int nft_byteorder_dump (struct sk_buff *skb,const struct nft_expr *expr)
net/netfilter/nft_ct.c +3 -4
@@ -29,7 +29,7 @@ struct nft_ct { enum nft_ct_keys key:8; enum ip_conntrack_dir dir:8;union { -enum nft_registers dreg:8 ; +u8 dreg;u8 sreg; }; };
@@ -486,9 +486,8 @@ static int nft_ct_get_init(const struct nft_ctx *ctx, } } - priv->dreg =nft_parse_register (tb[NFTA_CT_DREG ]); - err =nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , len); + err =nft_parse_register_store (ctx, tb[NFTA_CT_DREG ], &priv->dreg,NULL , +NFT_DATA_VALUE , len);if (err <0 )return err;
net/netfilter/nft_exthdr.c +4 -4
@@ -22,7 +22,7 @@ struct nft_exthdr {u8 offset;u8 len;u8 op; - enum nft_registers dreg:8; +u8 dreg;u8 sreg;u8 flags; };
@@ -258,12 +258,12 @@ static int nft_exthdr_init(const struct nft_ctx *ctx, priv->type =nla_get_u8 (tb[NFTA_EXTHDR_TYPE ]); priv->offset = offset; priv->len = len; - priv->dreg =nft_parse_register (tb[NFTA_EXTHDR_DREG ]); priv->flags = flags; priv->op = op; -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , priv->len); +return nft_parse_register_store (ctx, tb[NFTA_EXTHDR_DREG ], + &priv->dreg,NULL ,NFT_DATA_VALUE , + priv->len); } static int nft_exthdr_tcp_set_init(const struct nft_ctx *ctx,
net/netfilter/nft_fib.c +2 -3
@@ -88,7 +88,6 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,return -EINVAL ; priv->result =ntohl (nla_get_be32 (tb[NFTA_FIB_RESULT ])); - priv->dreg =nft_parse_register (tb[NFTA_FIB_DREG ]);switch (priv->result) {case NFT_FIB_RESULT_OIF :
@@ -108,8 +107,8 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,return -EINVAL ; } - err =nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , len); + err =nft_parse_register_store (ctx, tb[NFTA_FIB_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE , len);if (err <0 )return err;
net/netfilter/nft_hash.c +7 -10
@@ -19,7 +19,7 @@struct nft_jhash {u8 sreg; -enum nft_registers dreg:8 ; +u8 dreg;u8 len;bool autogen_seed:1 ;u32 modulus;
@@ -65,7 +65,7 @@ static void nft_jhash_map_eval(const struct nft_expr *expr, }struct nft_symhash { -enum nft_registers dreg:8 ; +u8 dreg;u32 modulus;u32 offset;struct nft_set *map;
@@ -136,8 +136,6 @@ static int nft_jhash_init(const struct nft_ctx *ctx,if (tb[NFTA_HASH_OFFSET ]) priv->offset =ntohl (nla_get_be32 (tb[NFTA_HASH_OFFSET ])); - priv->dreg =nft_parse_register (tb[NFTA_HASH_DREG ]); - err =nft_parse_u32_check (tb[NFTA_HASH_LEN ],U8_MAX , &len);if (err <0 )return err;
@@ -164,8 +162,8 @@ static int nft_jhash_init(const struct nft_ctx *ctx,get_random_bytes (&priv->seed,sizeof (priv->seed)); } -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE ,sizeof (u32)); +return nft_parse_register_store (ctx, tb[NFTA_HASH_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE ,sizeof (u32)); } static int nft_jhash_map_init(const struct nft_ctx *ctx,
@@ -195,8 +193,6 @@ static int nft_symhash_init(const struct nft_ctx *ctx,if (tb[NFTA_HASH_OFFSET ]) priv->offset =ntohl (nla_get_be32 (tb[NFTA_HASH_OFFSET ])); - priv->dreg =nft_parse_register (tb[NFTA_HASH_DREG ]); - priv->modulus =ntohl (nla_get_be32 (tb[NFTA_HASH_MODULUS ]));if (priv->modulus <1 )return -ERANGE ;
@@ -204,8 +200,9 @@ static int nft_symhash_init(const struct nft_ctx *ctx,if (priv->offset + priv->modulus -1 < priv->offset)return -EOVERFLOW ; -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE ,sizeof (u32)); +return nft_parse_register_store (ctx, tb[NFTA_HASH_DREG ], + &priv->dreg,NULL ,NFT_DATA_VALUE , +sizeof (u32)); } static int nft_symhash_map_init(const struct nft_ctx *ctx,
net/netfilter/nft_immediate.c +3 -3
@@ -50,9 +50,9 @@ static int nft_immediate_init(const struct nft_ctx *ctx, priv->dlen = desc.len; - priv->dreg =nft_parse_register (tb[NFTA_IMMEDIATE_DREG ]); - err =nft_validate_register_store (ctx, priv->dreg, &priv->data, - desc.type, desc.len); + err =nft_parse_register_store (ctx, tb[NFTA_IMMEDIATE_DREG ], + &priv->dreg, &priv->data, desc.type, + desc.len);if (err <0 ) goto err1;
net/netfilter/nft_lookup.c +4 -4
@@ -21,7 +21,7 @@struct nft_lookup {struct nft_set *set;u8 sreg; -enum nft_registers dreg:8 ; +u8 dreg;bool invert;struct nft_set_binding binding; };
@@ -100,9 +100,9 @@ static int nft_lookup_init(const struct nft_ctx *ctx,if (!(set->flags &NFT_SET_MAP ))return -EINVAL ; - priv->dreg =nft_parse_register (tb[NFTA_LOOKUP_DREG ]); - err =nft_validate_register_store (ctx, priv->dreg,NULL , - set->dtype, set->dlen); + err =nft_parse_register_store (ctx, tb[NFTA_LOOKUP_DREG ], + &priv->dreg,NULL , set->dtype, + set->dlen);if (err <0 )return err; }else if (set->flags &NFT_SET_MAP )
net/netfilter/nft_meta.c +3 -4
@@ -30,7 +30,7 @@struct nft_meta {enum nft_meta_keys key:8 ;union { -enum nft_registers dreg:8 ; +u8 dreg;u8 sreg; }; };
@@ -358,9 +358,8 @@ static int nft_meta_get_init(const struct nft_ctx *ctx,return -EOPNOTSUPP ; } - priv->dreg =nft_parse_register (tb[NFTA_META_DREG ]); -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , len); +return nft_parse_register_store (ctx, tb[NFTA_META_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE , len); } static int nft_meta_get_validate(const struct nft_ctx *ctx,
net/netfilter/nft_numgen.c +6 -9
@@ -20,7 +20,7 @@ static DEFINE_PER_CPU(struct rnd_state, nft_numgen_prandom_state);struct nft_ng_inc { -enum nft_registers dreg:8 ; +u8 dreg;u32 modulus;atomic_t counter;u32 offset;
@@ -70,11 +70,10 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx,if (priv->offset + priv->modulus -1 < priv->offset)return -EOVERFLOW ; - priv->dreg =nft_parse_register (tb[NFTA_NG_DREG ]);atomic_set (&priv->counter, priv->modulus -1 ); -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE ,sizeof (u32)); +return nft_parse_register_store (ctx, tb[NFTA_NG_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE ,sizeof (u32)); } static int nft_ng_dump(struct sk_buff *skb, enum nft_registers dreg,
@@ -104,7 +103,7 @@ static int nft_ng_inc_dump(struct sk_buff *skb, const struct nft_expr *expr) }struct nft_ng_random { -enum nft_registers dreg:8 ; +u8 dreg;u32 modulus;u32 offset; };
@@ -144,10 +143,8 @@ static int nft_ng_random_init(const struct nft_ctx *ctx,prandom_init_once (&nft_numgen_prandom_state); - priv->dreg =nft_parse_register (tb[NFTA_NG_DREG ]); - -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE ,sizeof (u32)); +return nft_parse_register_store (ctx, tb[NFTA_NG_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE ,sizeof (u32)); }static int nft_ng_random_dump (struct sk_buff *skb,const struct nft_expr *expr)
net/netfilter/nft_osf.c +4 -4
@@ -5,7 +5,7 @@#include <linux/netfilter/nfnetlink_osf.h> struct nft_osf { -enum nft_registers dreg:8 ; +u8 dreg; };static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX +1 ] = {
@@ -55,9 +55,9 @@ static int nft_osf_init(const struct nft_ctx *ctx,if (!tb[NFTA_OSF_DREG ])return -EINVAL ; - priv->dreg =nft_parse_register (tb[NFTA_OSF_DREG ]); - err =nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE ,NFT_OSF_MAXGENRELEN ); + err =nft_parse_register_store (ctx, tb[NFTA_OSF_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE , +NFT_OSF_MAXGENRELEN );if (err <0 )return err;
net/netfilter/nft_payload.c +3 -3
@@ -135,10 +135,10 @@ static int nft_payload_init(const struct nft_ctx *ctx, priv->base =ntohl (nla_get_be32 (tb[NFTA_PAYLOAD_BASE ])); priv->offset =ntohl (nla_get_be32 (tb[NFTA_PAYLOAD_OFFSET ])); priv->len =ntohl (nla_get_be32 (tb[NFTA_PAYLOAD_LEN ])); - priv->dreg =nft_parse_register (tb[NFTA_PAYLOAD_DREG ]); -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , priv->len); +return nft_parse_register_store (ctx, tb[NFTA_PAYLOAD_DREG ], + &priv->dreg,NULL ,NFT_DATA_VALUE , + priv->len); }static int nft_payload_dump (struct sk_buff *skb,const struct nft_expr *expr)
net/netfilter/nft_rt.c +3 -4
@@ -18,7 +18,7 @@struct nft_rt {enum nft_rt_keys key:8 ; -enum nft_registers dreg:8 ; +u8 dreg; };static u16 get_tcpmss (const struct nft_pktinfo *pkt,const struct dst_entry *skbdst)
@@ -134,9 +134,8 @@ static int nft_rt_get_init(const struct nft_ctx *ctx,return -EOPNOTSUPP ; } - priv->dreg =nft_parse_register (tb[NFTA_RT_DREG ]); -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , len); +return nft_parse_register_store (ctx, tb[NFTA_RT_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE , len); } static int nft_rt_get_dump(struct sk_buff *skb,
net/netfilter/nft_socket.c +3 -4
@@ -10,7 +10,7 @@struct nft_socket {enum nft_socket_keys key:8 ;union { -enum nft_registers dreg:8 ; +u8 dreg; }; };
@@ -119,9 +119,8 @@ static int nft_socket_init(const struct nft_ctx *ctx,return -EOPNOTSUPP ; } - priv->dreg =nft_parse_register (tb[NFTA_SOCKET_DREG ]); -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , len); +return nft_parse_register_store (ctx, tb[NFTA_SOCKET_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE , len); } static int nft_socket_dump(struct sk_buff *skb,
net/netfilter/nft_tunnel.c +3 -5
@@ -14,7 +14,7 @@struct nft_tunnel {enum nft_tunnel_keys key:8 ; -enum nft_registers dreg:8 ; +u8 dreg; }; static void nft_tunnel_get_eval(const struct nft_expr *expr,
@@ -72,10 +72,8 @@ static int nft_tunnel_get_init(const struct nft_ctx *ctx,return -EOPNOTSUPP ; } - priv->dreg =nft_parse_register (tb[NFTA_TUNNEL_DREG ]); - -return nft_validate_register_store (ctx, priv->dreg,NULL , -NFT_DATA_VALUE , len); +return nft_parse_register_store (ctx, tb[NFTA_TUNNEL_DREG ], &priv->dreg, +NULL ,NFT_DATA_VALUE , len); } static int nft_tunnel_get_dump(struct sk_buff *skb,
Signature · 1 line
2.30.2
Pablo Neira Ayuso
maintainerPATCH 3/9 netfilter: nftables: statify nft_parse_register()
In reply to Pablo Neira Ayuso[ 08a01c11a5bb3de9b0a9c9b2685867e50eda9910 ]
This function is not used anymore by any extension, statify it.
--- include/net/netfilter/nf_tables.h | 1 - net/netfilter/nf_tables_api.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-)
include/net/netfilter/nf_tables.h +0 -1
@@ -191,7 +191,6 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type) }int nft_parse_u32_check (const struct nlattr *attr,int max,u32 *dest); -unsigned int nft_parse_register (const struct nlattr *attr);int nft_dump_register (struct sk_buff *skb,unsigned int attr,unsigned int reg);int nft_parse_register_load (const struct nlattr *attr,u8 *sreg,u32 len);
net/netfilter/nf_tables_api.c +1 -2
@@ -6979,7 +6979,7 @@ EXPORT_SYMBOL_GPL(nft_parse_u32_check);* Registers used to be 128 bit wide, these register numbers will be * mapped to the corresponding 32 bit register numbers. */ -unsigned int nft_parse_register (const struct nlattr *attr) +static unsigned int nft_parse_register (const struct nlattr *attr) {unsigned int reg;
@@ -6991,7 +6991,6 @@ unsigned int nft_parse_register(const struct nlattr *attr)return reg +NFT_REG_SIZE /NFT_REG32_SIZE -NFT_REG32_00 ; } } -EXPORT_SYMBOL_GPL (nft_parse_register);/** * nft_dump_register - dump a register value to a netlink attribute
Signature · 1 line
2.30.2
Pablo Neira Ayuso
maintainerPATCH 4/9 netfilter: nf_tables: validate registers coming from userspace.
In reply to Pablo Neira Ayuso[ 6e1acfa387b9ff82cfc7db8cc3b6959221a95851 ]
Bail out in case userspace uses unsupported registers.
--- net/netfilter/nf_tables_api.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-)
net/netfilter/nf_tables_api.c +17 -14
@@ -6970,26 +6970,23 @@ int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest) }EXPORT_SYMBOL_GPL (nft_parse_u32_check); -/** -* nft_parse_register - parse a register value from a netlink attribute -* -* @attr: netlink attribute -* -* Parse and translate a register value from a netlink attribute. -* Registers used to be 128 bit wide, these register numbers will be -* mapped to the corresponding 32 bit register numbers. -*/ -static unsigned int nft_parse_register (const struct nlattr *attr) +static int nft_parse_register (const struct nlattr *attr,u32 *preg) {unsigned int reg; reg =ntohl (nla_get_be32 (attr));switch (reg) { case NFT_REG_VERDICT...NFT_REG_4: -return reg *NFT_REG_SIZE /NFT_REG32_SIZE ; + *preg = reg *NFT_REG_SIZE /NFT_REG32_SIZE ; +break ; + case NFT_REG32_00...NFT_REG32_15: + *preg = reg +NFT_REG_SIZE /NFT_REG32_SIZE -NFT_REG32_00 ; +break ;default : -return reg +NFT_REG_SIZE /NFT_REG32_SIZE -NFT_REG32_00 ; +return -ERANGE ; } + +return 0 ; }/**
@@ -7040,7 +7037,10 @@ int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len)u32 reg;int err; - reg =nft_parse_register (attr); + err =nft_parse_register (attr, ®); +if (err <0 ) +return err; + err =nft_validate_register_load (reg, len);if (err <0 )return err;
@@ -7109,7 +7109,10 @@ int nft_parse_register_store(const struct nft_ctx *ctx,int err;u32 reg; - reg =nft_parse_register (attr); + err =nft_parse_register (attr, ®); +if (err <0 ) +return err; + err =nft_validate_register_store (ctx, reg, data, type, len);if (err <0 )return err;
Signature · 1 line
2.30.2
Pablo Neira Ayuso
maintainerPATCH 5/9 netfilter: nf_tables: add nft_setelem_parse_key()
In reply to Pablo Neira Ayuso[ 20a1452c35425b2cef76f21f8395ef069dfddfa9 ]
Add helper function to parse the set element key netlink attribute.
v4: No changes
v3: New patch
[sbrivio: refactor error paths and labels; use NFT_DATA_VALUE_MAXLEN
instead of sizeof(*key) in helper, value can be longer than that; rebase]
--- net/netfilter/nf_tables_api.c | 91 +++++++++++++++++------------------ 1 file changed, 45 insertions(+), 46 deletions(-)
net/netfilter/nf_tables_api.c +45 -46
@@ -4128,11 +4128,28 @@ static int nft_setelem_parse_flags(const struct nft_set *set,return 0 ; } +static int nft_setelem_parse_key (struct nft_ctx *ctx,struct nft_set *set, +struct nft_data *key,struct nlattr *attr) +{ +struct nft_data_desc desc; +int err; + + err =nft_data_init (ctx, key,NFT_DATA_VALUE_MAXLEN , &desc, attr); +if (err <0 ) +return err; + +if (desc.type !=NFT_DATA_VALUE || desc.len != set->klen) { +nft_data_release (key, desc.type); +return -EINVAL ; + } + +return 0 ; +} +static int nft_get_set_elem (struct nft_ctx *ctx,struct nft_set *set,const struct nlattr *attr) {struct nlattr *nla[NFTA_SET_ELEM_MAX +1 ]; -struct nft_data_desc desc;struct nft_set_elem elem;struct sk_buff *skb;uint32_t flags =0 ;
@@ -4151,17 +4168,11 @@ static int nft_get_set_elem(struct nft_ctx *ctx, struct nft_set *set,if (err <0 )return err; - err =nft_data_init (ctx, &elem.key.val,sizeof (elem.key), &desc, - nla[NFTA_SET_ELEM_KEY ]); + err =nft_setelem_parse_key (ctx, set, &elem.key.val, + nla[NFTA_SET_ELEM_KEY ]);if (err <0 )return err; - err = -EINVAL ; -if (desc.type !=NFT_DATA_VALUE || desc.len != set->klen) { -nft_data_release (&elem.key.val, desc.type); -return err; - } - priv = set->ops->get (ctx->net, set, &elem, flags);if (IS_ERR (priv))return PTR_ERR (priv);
@@ -4352,13 +4363,13 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, {struct nlattr *nla[NFTA_SET_ELEM_MAX +1 ];u8 genmask =nft_genmask_next (ctx->net); -struct nft_data_desc d1, d2;struct nft_set_ext_tmpl tmpl;struct nft_set_ext *ext, *ext2;struct nft_set_elem elem;struct nft_set_binding *binding;struct nft_object *obj =NULL ;struct nft_userdata *udata; +struct nft_data_desc desc;struct nft_data data;enum nft_registers dreg;struct nft_trans *trans;
@@ -4413,15 +4424,12 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, timeout = set->timeout; } - err =nft_data_init (ctx, &elem.key.val,sizeof (elem.key), &d1, - nla[NFTA_SET_ELEM_KEY ]); + err =nft_setelem_parse_key (ctx, set, &elem.key.val, + nla[NFTA_SET_ELEM_KEY ]);if (err <0 ) goto err1; - err = -EINVAL ; -if (d1.type !=NFT_DATA_VALUE || d1.len != set->klen) - goto err2; -nft_set_ext_add_length (&tmpl,NFT_SET_EXT_KEY , d1.len); +nft_set_ext_add_length (&tmpl,NFT_SET_EXT_KEY , set->klen);if (timeout >0 ) {nft_set_ext_add (&tmpl,NFT_SET_EXT_EXPIRATION );if (timeout != set->timeout)
@@ -4443,13 +4451,13 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, }if (nla[NFTA_SET_ELEM_DATA ] !=NULL ) { - err =nft_data_init (ctx, &data,sizeof (data), &d2, + err =nft_data_init (ctx, &data,sizeof (data), &desc, nla[NFTA_SET_ELEM_DATA ]);if (err <0 ) goto err2; err = -EINVAL ; -if (set->dtype !=NFT_DATA_VERDICT && d2.len != set->dlen) +if (set->dtype !=NFT_DATA_VERDICT && desc.len != set->dlen) goto err3; dreg =nft_type_to_reg (set->dtype);
@@ -4466,18 +4474,18 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, err =nft_validate_register_store (&bind_ctx, dreg, &data, - d2.type, d2.len); + desc.type, desc.len);if (err <0 ) goto err3; -if (d2.type ==NFT_DATA_VERDICT && +if (desc.type ==NFT_DATA_VERDICT && (data.verdict.code ==NFT_GOTO || data.verdict.code ==NFT_JUMP ))nft_validate_state_update (ctx->net,NFT_VALIDATE_NEED ); } -nft_set_ext_add_length (&tmpl,NFT_SET_EXT_DATA , d2.len); +nft_set_ext_add_length (&tmpl,NFT_SET_EXT_DATA , desc.len); }/* The full maximum length of userdata can exceed the maximum
@@ -4560,9 +4568,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,kfree (elem.priv); err3:if (nla[NFTA_SET_ELEM_DATA ] !=NULL ) -nft_data_release (&data, d2.type); +nft_data_release (&data, desc.type); err2: -nft_data_release (&elem.key.val, d1.type); +nft_data_release (&elem.key.val,NFT_DATA_VALUE ); err1:return err; }
@@ -4658,7 +4666,6 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, {struct nlattr *nla[NFTA_SET_ELEM_MAX +1 ];struct nft_set_ext_tmpl tmpl; -struct nft_data_desc desc;struct nft_set_elem elem;struct nft_set_ext *ext;struct nft_trans *trans;
@@ -4669,11 +4676,10 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, err =nla_parse_nested (nla,NFTA_SET_ELEM_MAX , attr, nft_set_elem_policy,NULL );if (err <0 ) - goto err1; +return err; - err = -EINVAL ;if (nla[NFTA_SET_ELEM_KEY ] ==NULL ) - goto err1; +return -EINVAL ;nft_set_ext_prepare (&tmpl);
@@ -4683,37 +4689,31 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,if (flags !=0 )nft_set_ext_add (&tmpl,NFT_SET_EXT_FLAGS ); - err =nft_data_init (ctx, &elem.key.val,sizeof (elem.key), &desc, - nla[NFTA_SET_ELEM_KEY ]); + err =nft_setelem_parse_key (ctx, set, &elem.key.val, + nla[NFTA_SET_ELEM_KEY ]);if (err <0 ) - goto err1; - - err = -EINVAL ; -if (desc.type !=NFT_DATA_VALUE || desc.len != set->klen) - goto err2; +return err; -nft_set_ext_add_length (&tmpl,NFT_SET_EXT_KEY , desc.len); +nft_set_ext_add_length (&tmpl,NFT_SET_EXT_KEY , set->klen); err = -ENOMEM ; elem.priv =nft_set_elem_init (set, &tmpl, elem.key.val.data,NULL ,0 ,GFP_KERNEL );if (elem.priv ==NULL ) - goto err2; + goto fail_elem; ext =nft_set_elem_ext (set, elem.priv);if (flags) *nft_set_ext_flags (ext) = flags; trans =nft_trans_elem_alloc (ctx,NFT_MSG_DELSETELEM , set); -if (trans ==NULL ) { - err = -ENOMEM ; - goto err3; - } +if (trans ==NULL ) + goto fail_trans; priv = set->ops->deactivate (ctx->net, set, &elem);if (priv ==NULL ) { err = -ENOENT ; - goto err4; + goto fail_ops; }kfree (elem.priv); elem.priv = priv;
@@ -4724,13 +4724,12 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,list_add_tail (&trans->list, &ctx->net->nft.commit_list);return 0 ; -err4: +fail_ops:kfree (trans); -err3: +fail_trans:kfree (elem.priv); -err2: -nft_data_release (&elem.key.val, desc.type); -err1: +fail_elem: +nft_data_release (&elem.key.val,NFT_DATA_VALUE );return err; }
Signature · 1 line
2.30.2
Pablo Neira Ayuso
maintainerPATCH 6/9 netfilter: nf_tables: allow up to 64 bytes in the set element data area
In reply to Pablo Neira Ayuso[ fdb9c405e35bdc6e305b9b4e20ebc141ed14fc81 ]
So far, the set elements could store up to 128-bits in the data area.
--- include/net/netfilter/nf_tables.h | 4 ++++ net/netfilter/nf_tables_api.c | 39 +++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 12 deletions(-)
include/net/netfilter/nf_tables.h +4 -0
@@ -225,6 +225,10 @@ struct nft_set_elem {u32 buf[NFT_DATA_VALUE_MAXLEN /sizeof (u32)];struct nft_data val; } key; +union { +u32 buf[NFT_DATA_VALUE_MAXLEN /sizeof (u32)]; +struct nft_data val; + } data;void *priv; };
net/netfilter/nf_tables_api.c +27 -12
@@ -4146,6 +4146,25 @@ static int nft_setelem_parse_key(struct nft_ctx *ctx, struct nft_set *set,return 0 ; } +static int nft_setelem_parse_data (struct nft_ctx *ctx,struct nft_set *set, +struct nft_data_desc *desc, +struct nft_data *data, +struct nlattr *attr) +{ +int err; + + err =nft_data_init (ctx, data,NFT_DATA_VALUE_MAXLEN , desc, attr); +if (err <0 ) +return err; + +if (desc->type !=NFT_DATA_VERDICT && desc->len != set->dlen) { +nft_data_release (data, desc->type); +return -EINVAL ; + } + +return 0 ; +} +static int nft_get_set_elem (struct nft_ctx *ctx,struct nft_set *set,const struct nlattr *attr) {
@@ -4370,7 +4389,6 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,struct nft_object *obj =NULL ;struct nft_userdata *udata;struct nft_data_desc desc; -struct nft_data data;enum nft_registers dreg;struct nft_trans *trans;u32 flags =0 ;
@@ -4451,15 +4469,11 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, }if (nla[NFTA_SET_ELEM_DATA ] !=NULL ) { - err =nft_data_init (ctx, &data,sizeof (data), &desc, - nla[NFTA_SET_ELEM_DATA ]); + err =nft_setelem_parse_data (ctx, set, &desc, &elem.data.val, + nla[NFTA_SET_ELEM_DATA ]);if (err <0 ) goto err2; - err = -EINVAL ; -if (set->dtype !=NFT_DATA_VERDICT && desc.len != set->dlen) - goto err3; - dreg =nft_type_to_reg (set->dtype);list_for_each_entry (binding, &set->bindings, list) { struct nft_ctx bind_ctx = {
@@ -4473,14 +4487,14 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,continue ; err =nft_validate_register_store (&bind_ctx, dreg, - &data, + &elem.data.val, desc.type, desc.len);if (err <0 ) goto err3;if (desc.type ==NFT_DATA_VERDICT && - (data.verdict.code ==NFT_GOTO || - data.verdict.code ==NFT_JUMP )) + (elem.data.val.verdict.code ==NFT_GOTO || + elem.data.val.verdict.code ==NFT_JUMP ))nft_validate_state_update (ctx->net,NFT_VALIDATE_NEED ); }
@@ -4501,7 +4515,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, } err = -ENOMEM ; - elem.priv =nft_set_elem_init (set, &tmpl, elem.key.val.data, data.data, + elem.priv =nft_set_elem_init (set, &tmpl, elem.key.val.data, + elem.data.val.data, timeout,GFP_KERNEL );if (elem.priv ==NULL ) goto err3;
@@ -4568,7 +4583,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,kfree (elem.priv); err3:if (nla[NFTA_SET_ELEM_DATA ] !=NULL ) -nft_data_release (&data, desc.type); +nft_data_release (&elem.data.val, desc.type); err2:nft_data_release (&elem.key.val,NFT_DATA_VALUE ); err1:
Signature · 1 line
2.30.2
Pablo Neira Ayuso
maintainerPATCH 7/9 netfilter: nf_tables: stricter validation of element data
In reply to Pablo Neira Ayuso[ 7e6bc1f6cabcd30aba0b11219d8e01b952eacbb6 ]
Make sure element data type and length do not mismatch the one specified by the set declaration.
--- net/netfilter/nf_tables_api.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
net/netfilter/nf_tables_api.c +8 -1
@@ -4151,13 +4151,20 @@ static int nft_setelem_parse_data(struct nft_ctx *ctx, struct nft_set *set,struct nft_data *data, struct nlattr *attr) { + u32 dtype;int err; err =nft_data_init (ctx, data,NFT_DATA_VALUE_MAXLEN , desc, attr);if (err <0 )return err; -if (desc->type !=NFT_DATA_VERDICT && desc->len != set->dlen) { +if (set->dtype ==NFT_DATA_VERDICT ) + dtype =NFT_DATA_VERDICT ; +else + dtype =NFT_DATA_VALUE ; + +if (dtype != desc->type || + set->dlen != desc->len) {nft_data_release (data, desc->type);return -EINVAL ; }
Signature · 1 line
2.30.2
Pablo Neira Ayuso
maintainerPATCH 8/9 netfilter: nf_tables: validate NFTA_SET_ELEM_OBJREF based on NFT_SET_OBJECT flag
In reply to Pablo Neira Ayuso[ 5a2f3dc31811e93be15522d9eb13ed61460b76c8 ]
If the NFTA_SET_ELEM_OBJREF netlink attribute is present and NFT_SET_OBJECT flag is set on, report EINVAL.
Move existing sanity check earlier to validate that NFT_SET_OBJECT requires NFTA_SET_ELEM_OBJREF.
--- net/netfilter/nf_tables_api.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
net/netfilter/nf_tables_api.c +9 -4
@@ -4428,6 +4428,15 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,return -EINVAL ; } +if (set->flags &NFT_SET_OBJECT ) { +if (!nla[NFTA_SET_ELEM_OBJREF ] && + !(flags &NFT_SET_ELEM_INTERVAL_END )) +return -EINVAL ; + }else { +if (nla[NFTA_SET_ELEM_OBJREF ]) +return -EINVAL ; + } + if ((flags & NFT_SET_ELEM_INTERVAL_END) && (nla[NFTA_SET_ELEM_DATA] || nla[NFTA_SET_ELEM_OBJREF] ||
@@ -4462,10 +4471,6 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, }if (nla[NFTA_SET_ELEM_OBJREF ] !=NULL ) { -if (!(set->flags &NFT_SET_OBJECT )) { - err = -EINVAL ; - goto err2; - } obj =nft_obj_lookup (ctx->table, nla[NFTA_SET_ELEM_OBJREF ], set->objtype, genmask);if (IS_ERR (obj)) {
Signature · 1 line
2.30.2
Pablo Neira Ayuso
maintainerPATCH 9/9 netfilter: nf_tables: do not allow RULE_ID to refer to another chain
In reply to Pablo Neira Ayuso[ 36d5b2913219ac853908b0f1c664345e04313856 ]
When doing lookups for rules on the same batch by using its ID, a rule from a different chain can be used. If a rule is added to a chain but tries to be positioned next to a rule from a different chain, it will be linked to chain2, but the use counter on chain1 would be the one to be incremented.
When looking for rules by ID, use the chain that was used for the lookup by name. The chain used in the context copied to the transaction needs to match that same chain. That way, struct nft_rule does not need to get enlarged with another member.
--- net/netfilter/nf_tables_api.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
net/netfilter/nf_tables_api.c +3 -1
@@ -2769,6 +2769,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk, }static struct nft_rule *nft_rule_lookup_byid (const struct net *net, +const struct nft_chain *chain,const struct nlattr *nla) {u32 id =ntohl (nla_get_be32 (nla));
@@ -2778,6 +2779,7 @@ static struct nft_rule *nft_rule_lookup_byid(const struct net *net,struct nft_rule *rule =nft_trans_rule (trans);if (trans->msg_type ==NFT_MSG_NEWRULE && + trans->ctx.chain == chain && id ==nft_trans_rule_id (trans))return rule; }
@@ -2824,7 +2826,7 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk, err =nft_delrule (&ctx, rule); }else if (nla[NFTA_RULE_ID ]) { - rule =nft_rule_lookup_byid (net, nla[NFTA_RULE_ID ]); + rule =nft_rule_lookup_byid (net, chain, nla[NFTA_RULE_ID ]);if (IS_ERR (rule)) {NL_SET_BAD_ATTR (extack, nla[NFTA_RULE_ID ]);return PTR_ERR (rule);
Signature · 1 line
2.30.2