提交 89e1f6d2 编写于 作者: L Liping Zhang 提交者: Pablo Neira Ayuso

netfilter: nft_reject: restrict to INPUT/FORWARD/OUTPUT

After I add the nft rule "nft add rule filter prerouting reject
with tcp reset", kernel panic happened on my system:
  NULL pointer dereference at ...
  IP: [<ffffffff81b9db2f>] nf_send_reset+0xaf/0x400
  Call Trace:
  [<ffffffff81b9da80>] ? nf_reject_ip_tcphdr_get+0x160/0x160
  [<ffffffffa0928061>] nft_reject_ipv4_eval+0x61/0xb0 [nft_reject_ipv4]
  [<ffffffffa08e836a>] nft_do_chain+0x1fa/0x890 [nf_tables]
  [<ffffffffa08e8170>] ? __nft_trace_packet+0x170/0x170 [nf_tables]
  [<ffffffffa06e0900>] ? nf_ct_invert_tuple+0xb0/0xc0 [nf_conntrack]
  [<ffffffffa07224d4>] ? nf_nat_setup_info+0x5d4/0x650 [nf_nat]
  [...]

Because in the PREROUTING chain, routing information is not exist,
then we will dereference the NULL pointer and oops happen.

So we restrict reject expression to INPUT, FORWARD and OUTPUT chain.
This is consistent with iptables REJECT target.
Signed-off-by: NLiping Zhang <liping.zhang@spreadtrum.com>
Signed-off-by: NPablo Neira Ayuso <pablo@netfilter.org>
上级 51af96b5
...@@ -8,6 +8,10 @@ struct nft_reject { ...@@ -8,6 +8,10 @@ struct nft_reject {
extern const struct nla_policy nft_reject_policy[]; extern const struct nla_policy nft_reject_policy[];
int nft_reject_validate(const struct nft_ctx *ctx,
const struct nft_expr *expr,
const struct nft_data **data);
int nft_reject_init(const struct nft_ctx *ctx, int nft_reject_init(const struct nft_ctx *ctx,
const struct nft_expr *expr, const struct nft_expr *expr,
const struct nlattr * const tb[]); const struct nlattr * const tb[]);
......
...@@ -46,6 +46,7 @@ static const struct nft_expr_ops nft_reject_ipv4_ops = { ...@@ -46,6 +46,7 @@ static const struct nft_expr_ops nft_reject_ipv4_ops = {
.eval = nft_reject_ipv4_eval, .eval = nft_reject_ipv4_eval,
.init = nft_reject_init, .init = nft_reject_init,
.dump = nft_reject_dump, .dump = nft_reject_dump,
.validate = nft_reject_validate,
}; };
static struct nft_expr_type nft_reject_ipv4_type __read_mostly = { static struct nft_expr_type nft_reject_ipv4_type __read_mostly = {
......
...@@ -47,6 +47,7 @@ static const struct nft_expr_ops nft_reject_ipv6_ops = { ...@@ -47,6 +47,7 @@ static const struct nft_expr_ops nft_reject_ipv6_ops = {
.eval = nft_reject_ipv6_eval, .eval = nft_reject_ipv6_eval,
.init = nft_reject_init, .init = nft_reject_init,
.dump = nft_reject_dump, .dump = nft_reject_dump,
.validate = nft_reject_validate,
}; };
static struct nft_expr_type nft_reject_ipv6_type __read_mostly = { static struct nft_expr_type nft_reject_ipv6_type __read_mostly = {
......
...@@ -26,11 +26,27 @@ const struct nla_policy nft_reject_policy[NFTA_REJECT_MAX + 1] = { ...@@ -26,11 +26,27 @@ const struct nla_policy nft_reject_policy[NFTA_REJECT_MAX + 1] = {
}; };
EXPORT_SYMBOL_GPL(nft_reject_policy); EXPORT_SYMBOL_GPL(nft_reject_policy);
int nft_reject_validate(const struct nft_ctx *ctx,
const struct nft_expr *expr,
const struct nft_data **data)
{
return nft_chain_validate_hooks(ctx->chain,
(1 << NF_INET_LOCAL_IN) |
(1 << NF_INET_FORWARD) |
(1 << NF_INET_LOCAL_OUT));
}
EXPORT_SYMBOL_GPL(nft_reject_validate);
int nft_reject_init(const struct nft_ctx *ctx, int nft_reject_init(const struct nft_ctx *ctx,
const struct nft_expr *expr, const struct nft_expr *expr,
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,7 +66,11 @@ static int nft_reject_inet_init(const struct nft_ctx *ctx, ...@@ -66,7 +66,11 @@ 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; int icmp_code, 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;
...@@ -124,6 +128,7 @@ static const struct nft_expr_ops nft_reject_inet_ops = { ...@@ -124,6 +128,7 @@ static const struct nft_expr_ops nft_reject_inet_ops = {
.eval = nft_reject_inet_eval, .eval = nft_reject_inet_eval,
.init = nft_reject_inet_init, .init = nft_reject_inet_init,
.dump = nft_reject_inet_dump, .dump = nft_reject_inet_dump,
.validate = nft_reject_validate,
}; };
static struct nft_expr_type nft_reject_inet_type __read_mostly = { static struct nft_expr_type nft_reject_inet_type __read_mostly = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册