Commit 31f8441c authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

netfilter: nf_tables: atomic allocation in set notifications from rcu callback

Use GFP_ATOMIC allocations when sending removal notifications of
anonymous sets from rcu callback context. Sleeping in that context
is illegal.
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 4fefee57
...@@ -2191,7 +2191,7 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx, ...@@ -2191,7 +2191,7 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
static int nf_tables_set_notify(const struct nft_ctx *ctx, static int nf_tables_set_notify(const struct nft_ctx *ctx,
const struct nft_set *set, const struct nft_set *set,
int event) int event, gfp_t gfp_flags)
{ {
struct sk_buff *skb; struct sk_buff *skb;
u32 portid = ctx->portid; u32 portid = ctx->portid;
...@@ -2202,7 +2202,7 @@ static int nf_tables_set_notify(const struct nft_ctx *ctx, ...@@ -2202,7 +2202,7 @@ static int nf_tables_set_notify(const struct nft_ctx *ctx,
return 0; return 0;
err = -ENOBUFS; err = -ENOBUFS;
skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); skb = nlmsg_new(NLMSG_GOODSIZE, gfp_flags);
if (skb == NULL) if (skb == NULL)
goto err; goto err;
...@@ -2213,7 +2213,7 @@ static int nf_tables_set_notify(const struct nft_ctx *ctx, ...@@ -2213,7 +2213,7 @@ static int nf_tables_set_notify(const struct nft_ctx *ctx,
} }
err = nfnetlink_send(skb, ctx->net, portid, NFNLGRP_NFTABLES, err = nfnetlink_send(skb, ctx->net, portid, NFNLGRP_NFTABLES,
ctx->report, GFP_KERNEL); ctx->report, gfp_flags);
err: err:
if (err < 0) if (err < 0)
nfnetlink_set_err(ctx->net, portid, NFNLGRP_NFTABLES, err); nfnetlink_set_err(ctx->net, portid, NFNLGRP_NFTABLES, err);
...@@ -2613,7 +2613,7 @@ static void nft_set_destroy(struct nft_set *set) ...@@ -2613,7 +2613,7 @@ static void nft_set_destroy(struct nft_set *set)
static void nf_tables_set_destroy(const struct nft_ctx *ctx, struct nft_set *set) static void nf_tables_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
{ {
list_del(&set->list); list_del(&set->list);
nf_tables_set_notify(ctx, set, NFT_MSG_DELSET); nf_tables_set_notify(ctx, set, NFT_MSG_DELSET, GFP_ATOMIC);
nft_set_destroy(set); nft_set_destroy(set);
} }
...@@ -3409,12 +3409,12 @@ static int nf_tables_commit(struct sk_buff *skb) ...@@ -3409,12 +3409,12 @@ static int nf_tables_commit(struct sk_buff *skb)
trans->ctx.table->use--; trans->ctx.table->use--;
nf_tables_set_notify(&trans->ctx, nft_trans_set(trans), nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
NFT_MSG_NEWSET); NFT_MSG_NEWSET, GFP_KERNEL);
nft_trans_destroy(trans); nft_trans_destroy(trans);
break; break;
case NFT_MSG_DELSET: case NFT_MSG_DELSET:
nf_tables_set_notify(&trans->ctx, nft_trans_set(trans), nf_tables_set_notify(&trans->ctx, nft_trans_set(trans),
NFT_MSG_DELSET); NFT_MSG_DELSET, GFP_KERNEL);
break; break;
case NFT_MSG_NEWSETELEM: case NFT_MSG_NEWSETELEM:
nf_tables_setelem_notify(&trans->ctx, nf_tables_setelem_notify(&trans->ctx,
......
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