Skip to content

Commit bc45063

Browse files
committed
netfilter: nf_tables: honor NLM_F_CREATE and NLM_F_EXCL in event notification
jira VULN-429 Include the NLM_F_CREATE and NLM_F_EXCL flags in netlink event notifications, otherwise userspace cannot distiguish between create and add commands. Fixes: 9651851 ("netfilter: add nftables") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> (cherry picked from commit 6fb721c) Signed-off-by: Greg Rose <g.v.rose@ciq.com>
1 parent 5ec93ad commit bc45063

File tree

3 files changed

+41
-16
lines changed

3 files changed

+41
-16
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,8 +1167,8 @@ struct nft_object *nft_obj_lookup(const struct net *net,
11671167
u8 genmask);
11681168

11691169
void nft_obj_notify(struct net *net, const struct nft_table *table,
1170-
struct nft_object *obj, u32 portid, u32 seq,
1171-
int event, int family, int report, gfp_t gfp);
1170+
struct nft_object *obj, u32 portid, u32 seq, int event,
1171+
u16 flags, int family, int report, gfp_t gfp);
11721172

11731173
/**
11741174
* struct nft_object_type - stateful object type

net/netfilter/nf_tables_api.c

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,7 @@ static void nft_notify_enqueue(struct sk_buff *skb, bool report,
760760
static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
761761
{
762762
struct sk_buff *skb;
763+
u16 flags = 0;
763764
int err;
764765

765766
if (!ctx->report &&
@@ -770,8 +771,11 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
770771
if (skb == NULL)
771772
goto err;
772773

774+
if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
775+
flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
776+
773777
err = nf_tables_fill_table_info(skb, ctx->net, ctx->portid, ctx->seq,
774-
event, 0, ctx->family, ctx->table);
778+
event, flags, ctx->family, ctx->table);
775779
if (err < 0) {
776780
kfree_skb(skb);
777781
goto err;
@@ -1493,6 +1497,7 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
14931497
static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
14941498
{
14951499
struct sk_buff *skb;
1500+
u16 flags = 0;
14961501
int err;
14971502

14981503
if (!ctx->report &&
@@ -1503,8 +1508,11 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
15031508
if (skb == NULL)
15041509
goto err;
15051510

1511+
if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
1512+
flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
1513+
15061514
err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq,
1507-
event, 0, ctx->family, ctx->table,
1515+
event, flags, ctx->family, ctx->table,
15081516
ctx->chain);
15091517
if (err < 0) {
15101518
kfree_skb(skb);
@@ -2767,6 +2775,7 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx,
27672775
const struct nft_rule *rule, int event)
27682776
{
27692777
struct sk_buff *skb;
2778+
u16 flags = 0;
27702779
int err;
27712780

27722781
if (!ctx->report &&
@@ -2777,8 +2786,11 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx,
27772786
if (skb == NULL)
27782787
goto err;
27792788

2789+
if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
2790+
flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
2791+
27802792
err = nf_tables_fill_rule_info(skb, ctx->net, ctx->portid, ctx->seq,
2781-
event, 0, ctx->family, ctx->table,
2793+
event, flags, ctx->family, ctx->table,
27822794
ctx->chain, rule, NULL);
27832795
if (err < 0) {
27842796
kfree_skb(skb);
@@ -3810,8 +3822,9 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx,
38103822
const struct nft_set *set, int event,
38113823
gfp_t gfp_flags)
38123824
{
3813-
struct sk_buff *skb;
38143825
u32 portid = ctx->portid;
3826+
struct sk_buff *skb;
3827+
u16 flags = 0;
38153828
int err;
38163829

38173830
if (!ctx->report &&
@@ -3822,7 +3835,10 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx,
38223835
if (skb == NULL)
38233836
goto err;
38243837

3825-
err = nf_tables_fill_set(skb, ctx, set, event, 0);
3838+
if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
3839+
flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
3840+
3841+
err = nf_tables_fill_set(skb, ctx, set, event, flags);
38263842
if (err < 0) {
38273843
kfree_skb(skb);
38283844
goto err;
@@ -5011,11 +5027,12 @@ static int nf_tables_getsetelem(struct net *net, struct sock *nlsk,
50115027
static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
50125028
const struct nft_set *set,
50135029
const struct nft_set_elem *elem,
5014-
int event, u16 flags)
5030+
int event)
50155031
{
50165032
struct net *net = ctx->net;
50175033
u32 portid = ctx->portid;
50185034
struct sk_buff *skb;
5035+
u16 flags = 0;
50195036
int err;
50205037

50215038
if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
@@ -5025,6 +5042,9 @@ static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
50255042
if (skb == NULL)
50265043
goto err;
50275044

5045+
if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
5046+
flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
5047+
50285048
err = nf_tables_fill_setelem_info(skb, ctx, 0, portid, event, flags,
50295049
set, elem);
50305050
if (err < 0) {
@@ -6490,7 +6510,7 @@ static int nf_tables_delobj(struct net *net, struct sock *nlsk,
64906510

64916511
void nft_obj_notify(struct net *net, const struct nft_table *table,
64926512
struct nft_object *obj, u32 portid, u32 seq, int event,
6493-
int family, int report, gfp_t gfp)
6513+
u16 flags, int family, int report, gfp_t gfp)
64946514
{
64956515
struct sk_buff *skb;
64966516
int err;
@@ -6514,8 +6534,9 @@ void nft_obj_notify(struct net *net, const struct nft_table *table,
65146534
if (skb == NULL)
65156535
goto err;
65166536

6517-
err = nf_tables_fill_obj_info(skb, net, portid, seq, event, 0, family,
6518-
table, obj, false);
6537+
err = nf_tables_fill_obj_info(skb, net, portid, seq, event,
6538+
flags & (NLM_F_CREATE | NLM_F_EXCL),
6539+
family, table, obj, false);
65196540
if (err < 0) {
65206541
kfree_skb(skb);
65216542
goto err;
@@ -6532,7 +6553,7 @@ static void nf_tables_obj_notify(const struct nft_ctx *ctx,
65326553
struct nft_object *obj, int event)
65336554
{
65346555
nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event,
6535-
ctx->family, ctx->report, GFP_KERNEL);
6556+
ctx->flags, ctx->family, ctx->report, GFP_KERNEL);
65366557
}
65376558

65386559
/*
@@ -7146,6 +7167,7 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
71467167
int event)
71477168
{
71487169
struct sk_buff *skb;
7170+
u16 flags = 0;
71497171
int err;
71507172

71517173
if (!ctx->report &&
@@ -7156,8 +7178,11 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
71567178
if (skb == NULL)
71577179
goto err;
71587180

7181+
if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL))
7182+
flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL);
7183+
71597184
err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid,
7160-
ctx->seq, event, 0,
7185+
ctx->seq, event, flags,
71617186
ctx->family, flowtable);
71627187
if (err < 0) {
71637188
kfree_skb(skb);
@@ -7997,15 +8022,15 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
79978022
te->set->ops->activate(net, te->set, &te->elem);
79988023
nf_tables_setelem_notify(&trans->ctx, te->set,
79998024
&te->elem,
8000-
NFT_MSG_NEWSETELEM, 0);
8025+
NFT_MSG_NEWSETELEM);
80018026
nft_trans_destroy(trans);
80028027
break;
80038028
case NFT_MSG_DELSETELEM:
80048029
te = (struct nft_trans_elem *)trans->data;
80058030

80068031
nf_tables_setelem_notify(&trans->ctx, te->set,
80078032
&te->elem,
8008-
NFT_MSG_DELSETELEM, 0);
8033+
NFT_MSG_DELSETELEM);
80098034
te->set->ops->remove(net, te->set, &te->elem);
80108035
atomic_dec(&te->set->nelems);
80118036
te->set->ndeact--;

net/netfilter/nft_quota.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ static void nft_quota_obj_eval(struct nft_object *obj,
6363
if (overquota &&
6464
!test_and_set_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags))
6565
nft_obj_notify(nft_net(pkt), obj->key.table, obj, 0, 0,
66-
NFT_MSG_NEWOBJ, nft_pf(pkt), 0, GFP_ATOMIC);
66+
NFT_MSG_NEWOBJ, 0, nft_pf(pkt), 0, GFP_ATOMIC);
6767
}
6868

6969
static int nft_quota_do_init(const struct nlattr * const tb[],

0 commit comments

Comments
 (0)