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

netfilter: nft_ct: fix unpaired nf_connlabels_get/put call

We only get nf_connlabels if the user add ct label set expr successfully,
but we will also put nf_connlabels if the user delete ct lable get expr.
This is mismathced, and will cause ct label expr cannot work properly.

Also, if we init something fail, we should put nf_connlabels back.
Otherwise, we may waste to alloc the memory that will never be used.
Signed-off-by: default avatarLiping Zhang <liping.zhang@spreadtrum.com>
Acked-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent f4dc7771
...@@ -366,6 +366,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx, ...@@ -366,6 +366,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
const struct nlattr * const tb[]) const struct nlattr * const tb[])
{ {
struct nft_ct *priv = nft_expr_priv(expr); struct nft_ct *priv = nft_expr_priv(expr);
bool label_got = false;
unsigned int len; unsigned int len;
int err; int err;
...@@ -384,6 +385,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx, ...@@ -384,6 +385,7 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
err = nf_connlabels_get(ctx->net, (len * BITS_PER_BYTE) - 1); err = nf_connlabels_get(ctx->net, (len * BITS_PER_BYTE) - 1);
if (err) if (err)
return err; return err;
label_got = true;
break; break;
#endif #endif
default: default:
...@@ -393,17 +395,28 @@ static int nft_ct_set_init(const struct nft_ctx *ctx, ...@@ -393,17 +395,28 @@ static int nft_ct_set_init(const struct nft_ctx *ctx,
priv->sreg = nft_parse_register(tb[NFTA_CT_SREG]); priv->sreg = nft_parse_register(tb[NFTA_CT_SREG]);
err = nft_validate_register_load(priv->sreg, len); err = nft_validate_register_load(priv->sreg, len);
if (err < 0) if (err < 0)
return err; goto err1;
err = nft_ct_l3proto_try_module_get(ctx->afi->family); err = nft_ct_l3proto_try_module_get(ctx->afi->family);
if (err < 0) if (err < 0)
return err; goto err1;
return 0; return 0;
err1:
if (label_got)
nf_connlabels_put(ctx->net);
return err;
}
static void nft_ct_get_destroy(const struct nft_ctx *ctx,
const struct nft_expr *expr)
{
nft_ct_l3proto_module_put(ctx->afi->family);
} }
static void nft_ct_destroy(const struct nft_ctx *ctx, static void nft_ct_set_destroy(const struct nft_ctx *ctx,
const struct nft_expr *expr) const struct nft_expr *expr)
{ {
struct nft_ct *priv = nft_expr_priv(expr); struct nft_ct *priv = nft_expr_priv(expr);
...@@ -475,7 +488,7 @@ static const struct nft_expr_ops nft_ct_get_ops = { ...@@ -475,7 +488,7 @@ static const struct nft_expr_ops nft_ct_get_ops = {
.size = NFT_EXPR_SIZE(sizeof(struct nft_ct)), .size = NFT_EXPR_SIZE(sizeof(struct nft_ct)),
.eval = nft_ct_get_eval, .eval = nft_ct_get_eval,
.init = nft_ct_get_init, .init = nft_ct_get_init,
.destroy = nft_ct_destroy, .destroy = nft_ct_get_destroy,
.dump = nft_ct_get_dump, .dump = nft_ct_get_dump,
}; };
...@@ -484,7 +497,7 @@ static const struct nft_expr_ops nft_ct_set_ops = { ...@@ -484,7 +497,7 @@ static const struct nft_expr_ops nft_ct_set_ops = {
.size = NFT_EXPR_SIZE(sizeof(struct nft_ct)), .size = NFT_EXPR_SIZE(sizeof(struct nft_ct)),
.eval = nft_ct_set_eval, .eval = nft_ct_set_eval,
.init = nft_ct_set_init, .init = nft_ct_set_init,
.destroy = nft_ct_destroy, .destroy = nft_ct_set_destroy,
.dump = nft_ct_set_dump, .dump = nft_ct_set_dump,
}; };
......
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