Commit c56e3956 authored by Liping Zhang's avatar Liping Zhang Committed by Pablo Neira Ayuso

netfilter: nf_tables: validate the expr explicitly after init successfully

When we want to validate the expr's dependency or hooks, we must do two
things to accomplish it. First, write a X_validate callback function
and point ->validate to it. Second, call X_validate in init routine.
This is very common, such as fib, nat, reject expr and so on ...

It is a little ugly, since we will call X_validate in the expr's init
routine, it's better to do it in nf_tables_newexpr. So we can avoid to
do this again and again. After doing this, the second step listed above
is not useful anymore, remove them now.

Patch was tested by nftables/tests/py/nft-test.py and
nftables/tests/shell/run-tests.sh.
Signed-off-by: default avatarLiping Zhang <zlpnobody@gmail.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 74664cf2
...@@ -375,11 +375,7 @@ static int nft_reject_bridge_init(const struct nft_ctx *ctx, ...@@ -375,11 +375,7 @@ static int nft_reject_bridge_init(const struct nft_ctx *ctx,
const struct nlattr * const tb[]) const struct nlattr * const tb[])
{ {
struct nft_reject *priv = nft_expr_priv(expr); struct nft_reject *priv = nft_expr_priv(expr);
int icmp_code, err; int icmp_code;
err = nft_reject_bridge_validate(ctx, expr, NULL);
if (err < 0)
return err;
if (tb[NFTA_REJECT_TYPE] == NULL) if (tb[NFTA_REJECT_TYPE] == NULL)
return -EINVAL; return -EINVAL;
......
...@@ -1772,8 +1772,19 @@ static int nf_tables_newexpr(const struct nft_ctx *ctx, ...@@ -1772,8 +1772,19 @@ static int nf_tables_newexpr(const struct nft_ctx *ctx,
goto err1; goto err1;
} }
if (ops->validate) {
const struct nft_data *data = NULL;
err = ops->validate(ctx, expr, &data);
if (err < 0)
goto err2;
}
return 0; return 0;
err2:
if (ops->destroy)
ops->destroy(ctx, expr);
err1: err1:
expr->ops = NULL; expr->ops = NULL;
return err; return err;
......
...@@ -230,10 +230,6 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, ...@@ -230,10 +230,6 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
union nft_entry e = {}; union nft_entry e = {};
int ret; int ret;
ret = nft_compat_chain_validate_dependency(target->table, ctx->chain);
if (ret < 0)
goto err;
target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info); target_compat_from_user(target, nla_data(tb[NFTA_TARGET_INFO]), info);
if (ctx->nla[NFTA_RULE_COMPAT]) { if (ctx->nla[NFTA_RULE_COMPAT]) {
...@@ -419,10 +415,6 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr, ...@@ -419,10 +415,6 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
union nft_entry e = {}; union nft_entry e = {};
int ret; int ret;
ret = nft_compat_chain_validate_dependency(match->table, ctx->chain);
if (ret < 0)
goto err;
match_compat_from_user(match, nla_data(tb[NFTA_MATCH_INFO]), info); match_compat_from_user(match, nla_data(tb[NFTA_MATCH_INFO]), info);
if (ctx->nla[NFTA_RULE_COMPAT]) { if (ctx->nla[NFTA_RULE_COMPAT]) {
......
...@@ -112,7 +112,7 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr, ...@@ -112,7 +112,7 @@ int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
if (err < 0) if (err < 0)
return err; return err;
return nft_fib_validate(ctx, expr, NULL); return 0;
} }
EXPORT_SYMBOL_GPL(nft_fib_init); EXPORT_SYMBOL_GPL(nft_fib_init);
......
...@@ -46,10 +46,6 @@ int nft_masq_init(const struct nft_ctx *ctx, ...@@ -46,10 +46,6 @@ int nft_masq_init(const struct nft_ctx *ctx,
struct nft_masq *priv = nft_expr_priv(expr); struct nft_masq *priv = nft_expr_priv(expr);
int err; int err;
err = nft_masq_validate(ctx, expr, NULL);
if (err)
return err;
if (tb[NFTA_MASQ_FLAGS]) { if (tb[NFTA_MASQ_FLAGS]) {
priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS])); priv->flags = ntohl(nla_get_be32(tb[NFTA_MASQ_FLAGS]));
if (priv->flags & ~NF_NAT_RANGE_MASK) if (priv->flags & ~NF_NAT_RANGE_MASK)
......
...@@ -370,10 +370,6 @@ int nft_meta_set_init(const struct nft_ctx *ctx, ...@@ -370,10 +370,6 @@ int nft_meta_set_init(const struct nft_ctx *ctx,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
err = nft_meta_set_validate(ctx, expr, NULL);
if (err < 0)
return err;
priv->sreg = nft_parse_register(tb[NFTA_META_SREG]); priv->sreg = nft_parse_register(tb[NFTA_META_SREG]);
err = nft_validate_register_load(priv->sreg, len); err = nft_validate_register_load(priv->sreg, len);
if (err < 0) if (err < 0)
......
...@@ -138,10 +138,6 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, ...@@ -138,10 +138,6 @@ static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
return -EINVAL; return -EINVAL;
} }
err = nft_nat_validate(ctx, expr, NULL);
if (err < 0)
return err;
if (tb[NFTA_NAT_FAMILY] == NULL) if (tb[NFTA_NAT_FAMILY] == NULL)
return -EINVAL; return -EINVAL;
......
...@@ -47,10 +47,6 @@ int nft_redir_init(const struct nft_ctx *ctx, ...@@ -47,10 +47,6 @@ int nft_redir_init(const struct nft_ctx *ctx,
unsigned int plen; unsigned int plen;
int err; int err;
err = nft_redir_validate(ctx, expr, NULL);
if (err < 0)
return err;
plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all); plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all);
if (tb[NFTA_REDIR_REG_PROTO_MIN]) { if (tb[NFTA_REDIR_REG_PROTO_MIN]) {
priv->sreg_proto_min = priv->sreg_proto_min =
......
...@@ -42,11 +42,6 @@ int nft_reject_init(const struct nft_ctx *ctx, ...@@ -42,11 +42,6 @@ int nft_reject_init(const struct nft_ctx *ctx,
const struct nlattr * const tb[]) const struct nlattr * const tb[])
{ {
struct nft_reject *priv = nft_expr_priv(expr); struct nft_reject *priv = nft_expr_priv(expr);
int err;
err = nft_reject_validate(ctx, expr, NULL);
if (err < 0)
return err;
if (tb[NFTA_REJECT_TYPE] == NULL) if (tb[NFTA_REJECT_TYPE] == NULL)
return -EINVAL; return -EINVAL;
......
...@@ -66,11 +66,7 @@ static int nft_reject_inet_init(const struct nft_ctx *ctx, ...@@ -66,11 +66,7 @@ static int nft_reject_inet_init(const struct nft_ctx *ctx,
const struct nlattr * const tb[]) const struct nlattr * const tb[])
{ {
struct nft_reject *priv = nft_expr_priv(expr); struct nft_reject *priv = nft_expr_priv(expr);
int icmp_code, err; int icmp_code;
err = nft_reject_validate(ctx, expr, NULL);
if (err < 0)
return err;
if (tb[NFTA_REJECT_TYPE] == NULL) if (tb[NFTA_REJECT_TYPE] == NULL)
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment