return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1;
 }
 
-int nft_validate_input_register(enum nft_registers reg);
+int nft_validate_register_load(enum nft_registers reg, unsigned int 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);
 
-
 /**
  *     struct nft_userdata - user defined data associated with an object
  *
 
 }
 
 /**
- *     nft_validate_input_register - validate an expressions' input register
+ *     nft_validate_register_load - validate a load from a register
  *
  *     @reg: the register number
+ *     @len: the length of the data
  *
  *     Validate that the input register is one of the general purpose
- *     registers.
+ *     registers and that the length of the load is within the bounds.
  */
-int nft_validate_input_register(enum nft_registers reg)
+int nft_validate_register_load(enum nft_registers reg, unsigned int len)
 {
        if (reg <= NFT_REG_VERDICT)
                return -EINVAL;
        if (reg > NFT_REG_MAX)
                return -ERANGE;
+       if (len == 0)
+               return -EINVAL;
+       if (len > FIELD_SIZEOF(struct nft_data, data))
+               return -ERANGE;
        return 0;
 }
-EXPORT_SYMBOL_GPL(nft_validate_input_register);
+EXPORT_SYMBOL_GPL(nft_validate_register_load);
 
 /**
  *     nft_validate_register_store - validate an expressions' register store
 
            tb[NFTA_BITWISE_XOR] == NULL)
                return -EINVAL;
 
-       priv->len = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
-
+       priv->len  = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN]));
        priv->sreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_SREG]));
-       err = nft_validate_input_register(priv->sreg);
+       err = nft_validate_register_load(priv->sreg, priv->len);
        if (err < 0)
                return err;
 
 
                return -EINVAL;
        }
 
-       priv->len = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
-       if (priv->len == 0 || priv->len > FIELD_SIZEOF(struct nft_data, data))
-               return -EINVAL;
-
        priv->size = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SIZE]));
        switch (priv->size) {
        case 2:
        }
 
        priv->sreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SREG]));
-       err = nft_validate_input_register(priv->sreg);
+       priv->len  = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
+       err = nft_validate_register_load(priv->sreg, priv->len);
        if (err < 0)
                return err;
 
 
        struct nft_data_desc desc;
        int err;
 
-       priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
-       priv->op = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
-
        err = nft_data_init(NULL, &priv->data, &desc, tb[NFTA_CMP_DATA]);
        BUG_ON(err < 0);
 
+       priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
+       err = nft_validate_register_load(priv->sreg, desc.len);
+       if (err < 0)
+               return err;
+
+       priv->op  = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
        priv->len = desc.len;
        return 0;
 }
        u32 mask;
        int err;
 
-       priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
-
        err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]);
        BUG_ON(err < 0);
-       desc.len *= BITS_PER_BYTE;
 
+       priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
+       err = nft_validate_register_load(priv->sreg, desc.len);
+       if (err < 0)
+               return err;
+
+       desc.len *= BITS_PER_BYTE;
        mask = nft_cmp_fast_mask(desc.len);
+
        priv->data = data.data[0] & mask;
        priv->len  = desc.len;
        return 0;
 {
        struct nft_data_desc desc;
        struct nft_data data;
-       enum nft_registers sreg;
        enum nft_cmp_ops op;
        int err;
 
            tb[NFTA_CMP_DATA] == NULL)
                return ERR_PTR(-EINVAL);
 
-       sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG]));
-       err = nft_validate_input_register(sreg);
-       if (err < 0)
-               return ERR_PTR(err);
-
        op = ntohl(nla_get_be32(tb[NFTA_CMP_OP]));
        switch (op) {
        case NFT_CMP_EQ:
 
                           const struct nlattr * const tb[])
 {
        struct nft_ct *priv = nft_expr_priv(expr);
+       unsigned int len;
        int err;
 
        priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
        switch (priv->key) {
 #ifdef CONFIG_NF_CONNTRACK_MARK
        case NFT_CT_MARK:
+               len = FIELD_SIZEOF(struct nf_conn, mark);
                break;
 #endif
        default:
        }
 
        priv->sreg = ntohl(nla_get_be32(tb[NFTA_CT_SREG]));
-       err = nft_validate_input_register(priv->sreg);
+       err = nft_validate_register_load(priv->sreg, len);
        if (err < 0)
                return err;
 
 
        }
 
        priv->sreg_key = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_KEY]));
-       err = nft_validate_input_register(priv->sreg_key);
+       err = nft_validate_register_load(priv->sreg_key, set->klen);;
        if (err < 0)
                return err;
 
                        return -EOPNOTSUPP;
 
                priv->sreg_data = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_DATA]));
-               err = nft_validate_input_register(priv->sreg_data);
+               err = nft_validate_register_load(priv->sreg_data, set->dlen);
                if (err < 0)
                        return err;
        } else if (set->flags & NFT_SET_MAP)
 
        }
 
        priv->sreg = ntohl(nla_get_be32(tb[NFTA_LOOKUP_SREG]));
-       err = nft_validate_input_register(priv->sreg);
+       err = nft_validate_register_load(priv->sreg, set->klen);
        if (err < 0)
                return err;
 
 
                      const struct nlattr * const tb[])
 {
        struct nft_meta *priv = nft_expr_priv(expr);
+       unsigned int len;
        int err;
 
        priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
        switch (priv->key) {
        case NFT_META_MARK:
        case NFT_META_PRIORITY:
+               len = sizeof(u32);
+               break;
        case NFT_META_NFTRACE:
+               len = sizeof(u8);
                break;
        default:
                return -EOPNOTSUPP;
        }
 
        priv->sreg = ntohl(nla_get_be32(tb[NFTA_META_SREG]));
-       err = nft_validate_input_register(priv->sreg);
+       err = nft_validate_register_load(priv->sreg, len);
        if (err < 0)
                return err;
 
 
                        const struct nlattr * const tb[])
 {
        struct nft_nat *priv = nft_expr_priv(expr);
+       unsigned int alen, plen;
        u32 family;
        int err;
 
                return -EINVAL;
 
        family = ntohl(nla_get_be32(tb[NFTA_NAT_FAMILY]));
-       if (family != AF_INET && family != AF_INET6)
-               return -EAFNOSUPPORT;
        if (family != ctx->afi->family)
                return -EOPNOTSUPP;
+
+       switch (family) {
+       case NFPROTO_IPV4:
+               alen = FIELD_SIZEOF(struct nf_nat_range, min_addr.ip);
+               break;
+       case NFPROTO_IPV6:
+               alen = FIELD_SIZEOF(struct nf_nat_range, min_addr.ip6);
+               break;
+       default:
+               return -EAFNOSUPPORT;
+       }
        priv->family = family;
 
        if (tb[NFTA_NAT_REG_ADDR_MIN]) {
                priv->sreg_addr_min =
                        ntohl(nla_get_be32(tb[NFTA_NAT_REG_ADDR_MIN]));
-
-               err = nft_validate_input_register(priv->sreg_addr_min);
+               err = nft_validate_register_load(priv->sreg_addr_min, alen);
                if (err < 0)
                        return err;
 
                        priv->sreg_addr_max =
                                ntohl(nla_get_be32(tb[NFTA_NAT_REG_ADDR_MAX]));
 
-                       err = nft_validate_input_register(priv->sreg_addr_max);
+                       err = nft_validate_register_load(priv->sreg_addr_max,
+                                                        alen);
                        if (err < 0)
                                return err;
                } else {
                }
        }
 
+       plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
        if (tb[NFTA_NAT_REG_PROTO_MIN]) {
                priv->sreg_proto_min =
                        ntohl(nla_get_be32(tb[NFTA_NAT_REG_PROTO_MIN]));
 
-               err = nft_validate_input_register(priv->sreg_proto_min);
+               err = nft_validate_register_load(priv->sreg_proto_min, plen);
                if (err < 0)
                        return err;
 
                        priv->sreg_proto_max =
                                ntohl(nla_get_be32(tb[NFTA_NAT_REG_PROTO_MAX]));
 
-                       err = nft_validate_input_register(priv->sreg_proto_max);
+                       err = nft_validate_register_load(priv->sreg_proto_max,
+                                                        plen);
                        if (err < 0)
                                return err;
                } else {
 
                   const struct nlattr * const tb[])
 {
        struct nft_redir *priv = nft_expr_priv(expr);
+       unsigned int plen;
        int err;
 
        err = nft_redir_validate(ctx, expr, NULL);
        if (err < 0)
                return err;
 
+       plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
        if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
                priv->sreg_proto_min =
                        ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN]));
 
-               err = nft_validate_input_register(priv->sreg_proto_min);
+               err = nft_validate_register_load(priv->sreg_proto_min, plen);
                if (err < 0)
                        return err;
 
                        priv->sreg_proto_max =
                                ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MAX]));
 
-                       err = nft_validate_input_register(priv->sreg_proto_max);
+                       err = nft_validate_register_load(priv->sreg_proto_max,
+                                                        plen);
                        if (err < 0)
                                return err;
                } else {