stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH -stable,4.14 0/8] more stable fixes for 4.14
@ 2023-05-16 15:15 Pablo Neira Ayuso
  2023-05-16 15:15 ` [PATCH -stable,4.14 1/8] netfilter: nftables: statify nft_parse_register() Pablo Neira Ayuso
                   ` (8 more replies)
  0 siblings, 9 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2023-05-16 15:15 UTC (permalink / raw)
  To: netfilter-devel; +Cc: gregkh, sashal, stable

Hi Greg, Sasha,

This is second round of -stable backport fixes for 4.14. This batch
includes dependency patches which are not currently in the 4.14 branch.

The following list shows the backported patches, I am using original
commit IDs for reference:

1) 08a01c11a5bb ("netfilter: nftables: statify nft_parse_register()")

2) 6e1acfa387b9 ("netfilter: nf_tables: validate registers coming from userspace.")

3) 20a1452c3542 ("netfilter: nf_tables: add nft_setelem_parse_key()")

4) fdb9c405e35b ("netfilter: nf_tables: allow up to 64 bytes in the set element data area")

5) 7e6bc1f6cabc ("netfilter: nf_tables: stricter validation of element data")

6) 215a31f19ded ("netfilter: nft_dynset: do not reject set updates with NFT_SET_EVAL")

7) 36d5b2913219 ("netfilter: nf_tables: do not allow RULE_ID to refer to another chain")

8) 470ee20e069a ("netfilter: nf_tables: do not allow SET_ID to refer to another table")

Patches #1, #3 and #4 are dependencies.

Please, apply.
Thanks.

Pablo Neira Ayuso (8):
  netfilter: nftables: statify nft_parse_register()
  netfilter: nf_tables: validate registers coming from userspace.
  netfilter: nf_tables: add nft_setelem_parse_key()
  netfilter: nf_tables: allow up to 64 bytes in the set element data area
  netfilter: nf_tables: stricter validation of element data
  netfilter: nft_dynset: do not reject set updates with NFT_SET_EVAL
  netfilter: nf_tables: do not allow RULE_ID to refer to another chain
  netfilter: nf_tables: do not allow SET_ID to refer to another table

 include/net/netfilter/nf_tables.h        |   7 +-
 include/uapi/linux/netfilter/nf_tables.h |   2 +-
 net/netfilter/nf_tables_api.c            | 157 ++++++++++++++---------
 net/netfilter/nft_dynset.c               |   4 +-
 4 files changed, 104 insertions(+), 66 deletions(-)

-- 
2.30.2


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH -stable,4.14 1/8] netfilter: nftables: statify nft_parse_register()
  2023-05-16 15:15 [PATCH -stable,4.14 0/8] more stable fixes for 4.14 Pablo Neira Ayuso
@ 2023-05-16 15:15 ` Pablo Neira Ayuso
  2023-05-16 15:16 ` [PATCH -stable,4.14 2/8] netfilter: nf_tables: validate registers coming from userspace Pablo Neira Ayuso
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2023-05-16 15:15 UTC (permalink / raw)
  To: netfilter-devel; +Cc: gregkh, sashal, stable

[ 08a01c11a5bb3de9b0a9c9b2685867e50eda9910 ]

This function is not used anymore by any extension, statify it.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/net/netfilter/nf_tables.h | 1 -
 net/netfilter/nf_tables_api.c     | 3 +--
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index e837bf96c6a3..8397f859ff70 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -195,7 +195,6 @@ static inline enum nft_registers nft_type_to_reg(enum nft_data_types type)
 }
 
 int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest);
-unsigned int nft_parse_register(const struct nlattr *attr);
 int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg);
 
 int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len);
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 3adefb2a625c..95ca28a732c7 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -5624,7 +5624,7 @@ EXPORT_SYMBOL_GPL(nft_parse_u32_check);
  *	Registers used to be 128 bit wide, these register numbers will be
  *	mapped to the corresponding 32 bit register numbers.
  */
-unsigned int nft_parse_register(const struct nlattr *attr)
+static unsigned int nft_parse_register(const struct nlattr *attr)
 {
 	unsigned int reg;
 
@@ -5636,7 +5636,6 @@ unsigned int nft_parse_register(const struct nlattr *attr)
 		return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
 	}
 }
-EXPORT_SYMBOL_GPL(nft_parse_register);
 
 /**
  *	nft_dump_register - dump a register value to a netlink attribute
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH -stable,4.14 2/8] netfilter: nf_tables: validate registers coming from userspace.
  2023-05-16 15:15 [PATCH -stable,4.14 0/8] more stable fixes for 4.14 Pablo Neira Ayuso
  2023-05-16 15:15 ` [PATCH -stable,4.14 1/8] netfilter: nftables: statify nft_parse_register() Pablo Neira Ayuso
@ 2023-05-16 15:16 ` Pablo Neira Ayuso
  2023-05-16 15:16 ` [PATCH -stable,4.14 3/8] netfilter: nf_tables: add nft_setelem_parse_key() Pablo Neira Ayuso
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2023-05-16 15:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: gregkh, sashal, stable

[ 6e1acfa387b9ff82cfc7db8cc3b6959221a95851 ]

Bail out in case userspace uses unsupported registers.

Fixes: 49499c3e6e18 ("netfilter: nf_tables: switch registers to 32 bit addressing")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_tables_api.c | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 95ca28a732c7..404e0484ddd0 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -5615,26 +5615,23 @@ int nft_parse_u32_check(const struct nlattr *attr, int max, u32 *dest)
 }
 EXPORT_SYMBOL_GPL(nft_parse_u32_check);
 
-/**
- *	nft_parse_register - parse a register value from a netlink attribute
- *
- *	@attr: netlink attribute
- *
- *	Parse and translate a register value from a netlink attribute.
- *	Registers used to be 128 bit wide, these register numbers will be
- *	mapped to the corresponding 32 bit register numbers.
- */
-static unsigned int nft_parse_register(const struct nlattr *attr)
+static int nft_parse_register(const struct nlattr *attr, u32 *preg)
 {
 	unsigned int reg;
 
 	reg = ntohl(nla_get_be32(attr));
 	switch (reg) {
 	case NFT_REG_VERDICT...NFT_REG_4:
-		return reg * NFT_REG_SIZE / NFT_REG32_SIZE;
+		*preg = reg * NFT_REG_SIZE / NFT_REG32_SIZE;
+		break;
+	case NFT_REG32_00...NFT_REG32_15:
+		*preg = reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
+		break;
 	default:
-		return reg + NFT_REG_SIZE / NFT_REG32_SIZE - NFT_REG32_00;
+		return -ERANGE;
 	}
+
+	return 0;
 }
 
 /**
@@ -5685,7 +5682,10 @@ int nft_parse_register_load(const struct nlattr *attr, u8 *sreg, u32 len)
 	u32 reg;
 	int err;
 
-	reg = nft_parse_register(attr);
+	err = nft_parse_register(attr, &reg);
+	if (err < 0)
+		return err;
+
 	err = nft_validate_register_load(reg, len);
 	if (err < 0)
 		return err;
@@ -5761,7 +5761,10 @@ int nft_parse_register_store(const struct nft_ctx *ctx,
 	int err;
 	u32 reg;
 
-	reg = nft_parse_register(attr);
+	err = nft_parse_register(attr, &reg);
+	if (err < 0)
+		return err;
+
 	err = nft_validate_register_store(ctx, reg, data, type, len);
 	if (err < 0)
 		return err;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH -stable,4.14 3/8] netfilter: nf_tables: add nft_setelem_parse_key()
  2023-05-16 15:15 [PATCH -stable,4.14 0/8] more stable fixes for 4.14 Pablo Neira Ayuso
  2023-05-16 15:15 ` [PATCH -stable,4.14 1/8] netfilter: nftables: statify nft_parse_register() Pablo Neira Ayuso
  2023-05-16 15:16 ` [PATCH -stable,4.14 2/8] netfilter: nf_tables: validate registers coming from userspace Pablo Neira Ayuso
@ 2023-05-16 15:16 ` Pablo Neira Ayuso
  2023-05-16 15:16 ` [PATCH -stable,4.14 4/8] netfilter: nf_tables: allow up to 64 bytes in the set element data area Pablo Neira Ayuso
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2023-05-16 15:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: gregkh, sashal, stable

[ 20a1452c35425b2cef76f21f8395ef069dfddfa9 ]

Add helper function to parse the set element key netlink attribute.

v4: No changes
v3: New patch

[sbrivio: refactor error paths and labels; use NFT_DATA_VALUE_MAXLEN
  instead of sizeof(*key) in helper, value can be longer than that;
  rebase]
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_tables_api.c | 78 +++++++++++++++++++----------------
 1 file changed, 42 insertions(+), 36 deletions(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 404e0484ddd0..c49e93c5db9c 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -3736,6 +3736,24 @@ static int nf_tables_dump_set_done(struct netlink_callback *cb)
 	return 0;
 }
 
+static int nft_setelem_parse_key(struct nft_ctx *ctx, struct nft_set *set,
+				 struct nft_data *key, struct nlattr *attr)
+{
+	struct nft_data_desc desc;
+	int err;
+
+	err = nft_data_init(ctx, key, NFT_DATA_VALUE_MAXLEN, &desc, attr);
+	if (err < 0)
+		return err;
+
+	if (desc.type != NFT_DATA_VALUE || desc.len != set->klen) {
+		nft_data_release(key, desc.type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int nf_tables_getsetelem(struct net *net, struct sock *nlsk,
 				struct sk_buff *skb, const struct nlmsghdr *nlh,
 				const struct nlattr * const nla[],
@@ -3941,13 +3959,13 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
 {
 	struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
 	u8 genmask = nft_genmask_next(ctx->net);
-	struct nft_data_desc d1, d2;
 	struct nft_set_ext_tmpl tmpl;
 	struct nft_set_ext *ext, *ext2;
 	struct nft_set_elem elem;
 	struct nft_set_binding *binding;
 	struct nft_object *obj = NULL;
 	struct nft_userdata *udata;
+	struct nft_data_desc desc;
 	struct nft_data data;
 	enum nft_registers dreg;
 	struct nft_trans *trans;
@@ -4000,15 +4018,12 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
 		timeout = set->timeout;
 	}
 
-	err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &d1,
-			    nla[NFTA_SET_ELEM_KEY]);
+	err = nft_setelem_parse_key(ctx, set, &elem.key.val,
+				    nla[NFTA_SET_ELEM_KEY]);
 	if (err < 0)
 		goto err1;
-	err = -EINVAL;
-	if (d1.type != NFT_DATA_VALUE || d1.len != set->klen)
-		goto err2;
 
-	nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, d1.len);
+	nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, set->klen);
 	if (timeout > 0) {
 		nft_set_ext_add(&tmpl, NFT_SET_EXT_EXPIRATION);
 		if (timeout != set->timeout)
@@ -4030,13 +4045,13 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
 	}
 
 	if (nla[NFTA_SET_ELEM_DATA] != NULL) {
-		err = nft_data_init(ctx, &data, sizeof(data), &d2,
+		err = nft_data_init(ctx, &data, sizeof(data), &desc,
 				    nla[NFTA_SET_ELEM_DATA]);
 		if (err < 0)
 			goto err2;
 
 		err = -EINVAL;
-		if (set->dtype != NFT_DATA_VERDICT && d2.len != set->dlen)
+		if (set->dtype != NFT_DATA_VERDICT && desc.len != set->dlen)
 			goto err3;
 
 		dreg = nft_type_to_reg(set->dtype);
@@ -4053,12 +4068,12 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
 
 			err = nft_validate_register_store(&bind_ctx, dreg,
 							  &data,
-							  d2.type, d2.len);
+							  desc.type, desc.len);
 			if (err < 0)
 				goto err3;
 		}
 
-		nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, d2.len);
+		nft_set_ext_add_length(&tmpl, NFT_SET_EXT_DATA, desc.len);
 	}
 
 	/* The full maximum length of userdata can exceed the maximum
@@ -4141,9 +4156,9 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
 	kfree(elem.priv);
 err3:
 	if (nla[NFTA_SET_ELEM_DATA] != NULL)
-		nft_data_release(&data, d2.type);
+		nft_data_release(&data, desc.type);
 err2:
-	nft_data_release(&elem.key.val, d1.type);
+	nft_data_release(&elem.key.val, NFT_DATA_VALUE);
 err1:
 	return err;
 }
@@ -4241,7 +4256,6 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
 {
 	struct nlattr *nla[NFTA_SET_ELEM_MAX + 1];
 	struct nft_set_ext_tmpl tmpl;
-	struct nft_data_desc desc;
 	struct nft_set_elem elem;
 	struct nft_set_ext *ext;
 	struct nft_trans *trans;
@@ -4252,11 +4266,10 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
 	err = nla_parse_nested(nla, NFTA_SET_ELEM_MAX, attr,
 			       nft_set_elem_policy, NULL);
 	if (err < 0)
-		goto err1;
+		return err;
 
-	err = -EINVAL;
 	if (nla[NFTA_SET_ELEM_KEY] == NULL)
-		goto err1;
+		return -EINVAL;
 
 	nft_set_ext_prepare(&tmpl);
 
@@ -4266,37 +4279,31 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
 	if (flags != 0)
 		nft_set_ext_add(&tmpl, NFT_SET_EXT_FLAGS);
 
-	err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &desc,
-			    nla[NFTA_SET_ELEM_KEY]);
+	err = nft_setelem_parse_key(ctx, set, &elem.key.val,
+				    nla[NFTA_SET_ELEM_KEY]);
 	if (err < 0)
-		goto err1;
-
-	err = -EINVAL;
-	if (desc.type != NFT_DATA_VALUE || desc.len != set->klen)
-		goto err2;
+		return err;
 
-	nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, desc.len);
+	nft_set_ext_add_length(&tmpl, NFT_SET_EXT_KEY, set->klen);
 
 	err = -ENOMEM;
 	elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, NULL, 0,
 				      GFP_KERNEL);
 	if (elem.priv == NULL)
-		goto err2;
+		goto fail_elem;
 
 	ext = nft_set_elem_ext(set, elem.priv);
 	if (flags)
 		*nft_set_ext_flags(ext) = flags;
 
 	trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set);
-	if (trans == NULL) {
-		err = -ENOMEM;
-		goto err3;
-	}
+	if (trans == NULL)
+		goto fail_trans;
 
 	priv = set->ops->deactivate(ctx->net, set, &elem);
 	if (priv == NULL) {
 		err = -ENOENT;
-		goto err4;
+		goto fail_ops;
 	}
 	kfree(elem.priv);
 	elem.priv = priv;
@@ -4307,13 +4314,12 @@ static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set,
 	list_add_tail(&trans->list, &ctx->net->nft.commit_list);
 	return 0;
 
-err4:
+fail_ops:
 	kfree(trans);
-err3:
+fail_trans:
 	kfree(elem.priv);
-err2:
-	nft_data_release(&elem.key.val, desc.type);
-err1:
+fail_elem:
+	nft_data_release(&elem.key.val, NFT_DATA_VALUE);
 	return err;
 }
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH -stable,4.14 4/8] netfilter: nf_tables: allow up to 64 bytes in the set element data area
  2023-05-16 15:15 [PATCH -stable,4.14 0/8] more stable fixes for 4.14 Pablo Neira Ayuso
                   ` (2 preceding siblings ...)
  2023-05-16 15:16 ` [PATCH -stable,4.14 3/8] netfilter: nf_tables: add nft_setelem_parse_key() Pablo Neira Ayuso
@ 2023-05-16 15:16 ` Pablo Neira Ayuso
  2023-05-16 15:16 ` [PATCH -stable,4.14 5/8] netfilter: nf_tables: stricter validation of element data Pablo Neira Ayuso
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2023-05-16 15:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: gregkh, sashal, stable

[ fdb9c405e35bdc6e305b9b4e20ebc141ed14fc81 ]

So far, the set elements could store up to 128-bits in the data area.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/net/netfilter/nf_tables.h |  4 ++++
 net/netfilter/nf_tables_api.c     | 35 ++++++++++++++++++++++---------
 2 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 8397f859ff70..4eb90800fc2e 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -229,6 +229,10 @@ struct nft_set_elem {
 		u32		buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)];
 		struct nft_data	val;
 	} key;
+	union {
+		u32		buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)];
+		struct nft_data val;
+	} data;
 	void			*priv;
 };
 
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index c49e93c5db9c..1cd49af7d375 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -3954,6 +3954,25 @@ static int nft_setelem_parse_flags(const struct nft_set *set,
 	return 0;
 }
 
+static int nft_setelem_parse_data(struct nft_ctx *ctx, struct nft_set *set,
+				  struct nft_data_desc *desc,
+				  struct nft_data *data,
+				  struct nlattr *attr)
+{
+	int err;
+
+	err = nft_data_init(ctx, data, NFT_DATA_VALUE_MAXLEN, desc, attr);
+	if (err < 0)
+		return err;
+
+	if (desc->type != NFT_DATA_VERDICT && desc->len != set->dlen) {
+		nft_data_release(data, desc->type);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
 			    const struct nlattr *attr, u32 nlmsg_flags)
 {
@@ -3966,7 +3985,6 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
 	struct nft_object *obj = NULL;
 	struct nft_userdata *udata;
 	struct nft_data_desc desc;
-	struct nft_data data;
 	enum nft_registers dreg;
 	struct nft_trans *trans;
 	u32 flags = 0;
@@ -4045,15 +4063,11 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
 	}
 
 	if (nla[NFTA_SET_ELEM_DATA] != NULL) {
-		err = nft_data_init(ctx, &data, sizeof(data), &desc,
-				    nla[NFTA_SET_ELEM_DATA]);
+		err = nft_setelem_parse_data(ctx, set, &desc, &elem.data.val,
+					     nla[NFTA_SET_ELEM_DATA]);
 		if (err < 0)
 			goto err2;
 
-		err = -EINVAL;
-		if (set->dtype != NFT_DATA_VERDICT && desc.len != set->dlen)
-			goto err3;
-
 		dreg = nft_type_to_reg(set->dtype);
 		list_for_each_entry(binding, &set->bindings, list) {
 			struct nft_ctx bind_ctx = {
@@ -4067,7 +4081,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
 				continue;
 
 			err = nft_validate_register_store(&bind_ctx, dreg,
-							  &data,
+							  &elem.data.val,
 							  desc.type, desc.len);
 			if (err < 0)
 				goto err3;
@@ -4089,7 +4103,8 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
 	}
 
 	err = -ENOMEM;
-	elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, data.data,
+	elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data,
+				      elem.data.val.data,
 				      timeout, GFP_KERNEL);
 	if (elem.priv == NULL)
 		goto err3;
@@ -4156,7 +4171,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
 	kfree(elem.priv);
 err3:
 	if (nla[NFTA_SET_ELEM_DATA] != NULL)
-		nft_data_release(&data, desc.type);
+		nft_data_release(&elem.data.val, desc.type);
 err2:
 	nft_data_release(&elem.key.val, NFT_DATA_VALUE);
 err1:
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH -stable,4.14 5/8] netfilter: nf_tables: stricter validation of element data
  2023-05-16 15:15 [PATCH -stable,4.14 0/8] more stable fixes for 4.14 Pablo Neira Ayuso
                   ` (3 preceding siblings ...)
  2023-05-16 15:16 ` [PATCH -stable,4.14 4/8] netfilter: nf_tables: allow up to 64 bytes in the set element data area Pablo Neira Ayuso
@ 2023-05-16 15:16 ` Pablo Neira Ayuso
  2023-05-16 15:16 ` [PATCH -stable,4.14 6/8] netfilter: nft_dynset: do not reject set updates with NFT_SET_EVAL Pablo Neira Ayuso
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2023-05-16 15:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: gregkh, sashal, stable

[ 7e6bc1f6cabcd30aba0b11219d8e01b952eacbb6 ]

Make sure element data type and length do not mismatch the one specified
by the set declaration.

Fixes: 7d7402642eaf ("netfilter: nf_tables: variable sized set element keys / data")
Reported-by: Hugues ANGUELKOV <hanguelkov@randorisec.fr>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_tables_api.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 1cd49af7d375..9caaac459ca9 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -3959,13 +3959,20 @@ static int nft_setelem_parse_data(struct nft_ctx *ctx, struct nft_set *set,
 				  struct nft_data *data,
 				  struct nlattr *attr)
 {
+	u32 dtype;
 	int err;
 
 	err = nft_data_init(ctx, data, NFT_DATA_VALUE_MAXLEN, desc, attr);
 	if (err < 0)
 		return err;
 
-	if (desc->type != NFT_DATA_VERDICT && desc->len != set->dlen) {
+	if (set->dtype == NFT_DATA_VERDICT)
+		dtype = NFT_DATA_VERDICT;
+	else
+		dtype = NFT_DATA_VALUE;
+
+	if (dtype != desc->type ||
+	    set->dlen != desc->len) {
 		nft_data_release(data, desc->type);
 		return -EINVAL;
 	}
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH -stable,4.14 6/8] netfilter: nft_dynset: do not reject set updates with NFT_SET_EVAL
  2023-05-16 15:15 [PATCH -stable,4.14 0/8] more stable fixes for 4.14 Pablo Neira Ayuso
                   ` (4 preceding siblings ...)
  2023-05-16 15:16 ` [PATCH -stable,4.14 5/8] netfilter: nf_tables: stricter validation of element data Pablo Neira Ayuso
@ 2023-05-16 15:16 ` Pablo Neira Ayuso
  2023-05-16 15:16 ` [PATCH -stable,4.14 7/8] netfilter: nf_tables: do not allow RULE_ID to refer to another chain Pablo Neira Ayuso
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2023-05-16 15:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: gregkh, sashal, stable

[ 215a31f19dedd4e92a67cf5a9717ee898d012b3a ]

NFT_SET_EVAL is signalling the kernel that this sets can be updated from
the evaluation path, even if there are no expressions attached to the
element. Otherwise, set updates with no expressions fail. Update
description to describe the right semantics.

Fixes: 22fe54d5fefc ("netfilter: nf_tables: add support for dynamic set updates")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/uapi/linux/netfilter/nf_tables.h | 2 +-
 net/netfilter/nft_dynset.c               | 4 +---
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 49b6997c3255..c7bb18ea4962 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -258,7 +258,7 @@ enum nft_rule_compat_attributes {
  * @NFT_SET_INTERVAL: set contains intervals
  * @NFT_SET_MAP: set is used as a dictionary
  * @NFT_SET_TIMEOUT: set uses timeouts
- * @NFT_SET_EVAL: set contains expressions for evaluation
+ * @NFT_SET_EVAL: set can be updated from the evaluation path
  * @NFT_SET_OBJECT: set contains stateful objects
  */
 enum nft_set_flags {
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index f174a66bbc4b..d1dc5c8937a5 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -190,9 +190,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
 		priv->expr = nft_expr_init(ctx, tb[NFTA_DYNSET_EXPR]);
 		if (IS_ERR(priv->expr))
 			return PTR_ERR(priv->expr);
-
-	} else if (set->flags & NFT_SET_EVAL)
-		return -EINVAL;
+	}
 
 	nft_set_ext_prepare(&priv->tmpl);
 	nft_set_ext_add_length(&priv->tmpl, NFT_SET_EXT_KEY, set->klen);
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH -stable,4.14 7/8] netfilter: nf_tables: do not allow RULE_ID to refer to another chain
  2023-05-16 15:15 [PATCH -stable,4.14 0/8] more stable fixes for 4.14 Pablo Neira Ayuso
                   ` (5 preceding siblings ...)
  2023-05-16 15:16 ` [PATCH -stable,4.14 6/8] netfilter: nft_dynset: do not reject set updates with NFT_SET_EVAL Pablo Neira Ayuso
@ 2023-05-16 15:16 ` Pablo Neira Ayuso
  2023-05-16 15:16 ` [PATCH -stable,4.14 8/8] netfilter: nf_tables: do not allow SET_ID to refer to another table Pablo Neira Ayuso
  2023-05-22 17:55 ` [PATCH -stable,4.14 0/8] more stable fixes for 4.14 Sasha Levin
  8 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2023-05-16 15:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: gregkh, sashal, stable

[ 36d5b2913219ac853908b0f1c664345e04313856 ]

When doing lookups for rules on the same batch by using its ID, a rule from
a different chain can be used. If a rule is added to a chain but tries to
be positioned next to a rule from a different chain, it will be linked to
chain2, but the use counter on chain1 would be the one to be incremented.

When looking for rules by ID, use the chain that was used for the lookup by
name. The chain used in the context copied to the transaction needs to
match that same chain. That way, struct nft_rule does not need to get
enlarged with another member.

Fixes: 1a94e38d254b ("netfilter: nf_tables: add NFTA_RULE_ID attribute")
Fixes: 75dd48e2e420 ("netfilter: nf_tables: Support RULE_ID reference in new rule")
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_tables_api.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 9caaac459ca9..86913d53eead 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2475,6 +2475,7 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
 }
 
 static struct nft_rule *nft_rule_lookup_byid(const struct net *net,
+					     const struct nft_chain *chain,
 					     const struct nlattr *nla)
 {
 	u32 id = ntohl(nla_get_be32(nla));
@@ -2484,6 +2485,7 @@ static struct nft_rule *nft_rule_lookup_byid(const struct net *net,
 		struct nft_rule *rule = nft_trans_rule(trans);
 
 		if (trans->msg_type == NFT_MSG_NEWRULE &&
+		    trans->ctx.chain == chain &&
 		    id == nft_trans_rule_id(trans))
 			return rule;
 	}
@@ -2530,7 +2532,7 @@ static int nf_tables_delrule(struct net *net, struct sock *nlsk,
 
 			err = nft_delrule(&ctx, rule);
 		} else if (nla[NFTA_RULE_ID]) {
-			rule = nft_rule_lookup_byid(net, nla[NFTA_RULE_ID]);
+			rule = nft_rule_lookup_byid(net, chain, nla[NFTA_RULE_ID]);
 			if (IS_ERR(rule))
 				return PTR_ERR(rule);
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH -stable,4.14 8/8] netfilter: nf_tables: do not allow SET_ID to refer to another table
  2023-05-16 15:15 [PATCH -stable,4.14 0/8] more stable fixes for 4.14 Pablo Neira Ayuso
                   ` (6 preceding siblings ...)
  2023-05-16 15:16 ` [PATCH -stable,4.14 7/8] netfilter: nf_tables: do not allow RULE_ID to refer to another chain Pablo Neira Ayuso
@ 2023-05-16 15:16 ` Pablo Neira Ayuso
  2023-05-22 17:55 ` [PATCH -stable,4.14 0/8] more stable fixes for 4.14 Sasha Levin
  8 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2023-05-16 15:16 UTC (permalink / raw)
  To: netfilter-devel; +Cc: gregkh, sashal, stable

[ 470ee20e069a6d05ae549f7d0ef2bdbcee6a81b2 ]

When doing lookups for sets on the same batch by using its ID, a set from a
different table can be used.

Then, when the table is removed, a reference to the set may be kept after
the set is freed, leading to a potential use-after-free.

When looking for sets by ID, use the table that was used for the lookup by
name, and only return sets belonging to that same table.

This fixes CVE-2022-2586, also reported as ZDI-CAN-17470.

Reported-by: Team Orca of Sea Security (@seasecresponse)
Fixes: 958bee14d071 ("netfilter: nf_tables: use new transaction infrastructure to handle sets")
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/net/netfilter/nf_tables.h | 2 ++
 net/netfilter/nf_tables_api.c     | 7 +++++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 4eb90800fc2e..0d625ff7841a 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -381,6 +381,7 @@ void nft_unregister_set(struct nft_set_type *type);
  *
  *	@list: table set list node
  *	@bindings: list of set bindings
+ *	@table: table this set belongs to
  * 	@name: name of the set
  * 	@ktype: key type (numeric type defined by userspace, not used in the kernel)
  * 	@dtype: data type (verdict or numeric type defined by userspace)
@@ -404,6 +405,7 @@ void nft_unregister_set(struct nft_set_type *type);
 struct nft_set {
 	struct list_head		list;
 	struct list_head		bindings;
+	struct nft_table		*table;
 	char				*name;
 	u32				ktype;
 	u32				dtype;
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 86913d53eead..345fa29f34b9 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2746,6 +2746,7 @@ static struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
 }
 
 static struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
+						 const struct nft_table *table,
 						 const struct nlattr *nla,
 						 u8 genmask)
 {
@@ -2757,6 +2758,7 @@ static struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
 			struct nft_set *set = nft_trans_set(trans);
 
 			if (id == nft_trans_set_id(trans) &&
+			    set->table == table &&
 			    nft_active_genmask(set, genmask))
 				return set;
 		}
@@ -2777,7 +2779,7 @@ struct nft_set *nft_set_lookup(const struct net *net,
 		if (!nla_set_id)
 			return set;
 
-		set = nf_tables_set_lookup_byid(net, nla_set_id, genmask);
+		set = nf_tables_set_lookup_byid(net, table, nla_set_id, genmask);
 	}
 	return set;
 }
@@ -3272,6 +3274,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
 	}
 
 	INIT_LIST_HEAD(&set->bindings);
+	set->table = table;
 	set->ops   = ops;
 	set->ktype = ktype;
 	set->klen  = desc.klen;
@@ -4209,7 +4212,7 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
 				   genmask);
 	if (IS_ERR(set)) {
 		if (nla[NFTA_SET_ELEM_LIST_SET_ID]) {
-			set = nf_tables_set_lookup_byid(net,
+			set = nf_tables_set_lookup_byid(net, ctx.table,
 					nla[NFTA_SET_ELEM_LIST_SET_ID],
 					genmask);
 		}
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH -stable,4.14 0/8] more stable fixes for 4.14
  2023-05-16 15:15 [PATCH -stable,4.14 0/8] more stable fixes for 4.14 Pablo Neira Ayuso
                   ` (7 preceding siblings ...)
  2023-05-16 15:16 ` [PATCH -stable,4.14 8/8] netfilter: nf_tables: do not allow SET_ID to refer to another table Pablo Neira Ayuso
@ 2023-05-22 17:55 ` Sasha Levin
  2023-05-23  8:41   ` Pablo Neira Ayuso
  8 siblings, 1 reply; 11+ messages in thread
From: Sasha Levin @ 2023-05-22 17:55 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, gregkh, stable

On Tue, May 16, 2023 at 05:15:58PM +0200, Pablo Neira Ayuso wrote:
>Hi Greg, Sasha,
>
>This is second round of -stable backport fixes for 4.14. This batch
>includes dependency patches which are not currently in the 4.14 branch.
>
>The following list shows the backported patches, I am using original
>commit IDs for reference:
>
>1) 08a01c11a5bb ("netfilter: nftables: statify nft_parse_register()")
>
>2) 6e1acfa387b9 ("netfilter: nf_tables: validate registers coming from userspace.")
>
>3) 20a1452c3542 ("netfilter: nf_tables: add nft_setelem_parse_key()")
>
>4) fdb9c405e35b ("netfilter: nf_tables: allow up to 64 bytes in the set element data area")
>
>5) 7e6bc1f6cabc ("netfilter: nf_tables: stricter validation of element data")
>
>6) 215a31f19ded ("netfilter: nft_dynset: do not reject set updates with NFT_SET_EVAL")
>
>7) 36d5b2913219 ("netfilter: nf_tables: do not allow RULE_ID to refer to another chain")
>
>8) 470ee20e069a ("netfilter: nf_tables: do not allow SET_ID to refer to another table")

I've applied the 5.4 and 4.19 series, but it looks like patch #1 here
fails to apply. Could you please re-send the 4.14 series?

-- 
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH -stable,4.14 0/8] more stable fixes for 4.14
  2023-05-22 17:55 ` [PATCH -stable,4.14 0/8] more stable fixes for 4.14 Sasha Levin
@ 2023-05-23  8:41   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 11+ messages in thread
From: Pablo Neira Ayuso @ 2023-05-23  8:41 UTC (permalink / raw)
  To: Sasha Levin; +Cc: netfilter-devel, gregkh, stable

On Mon, May 22, 2023 at 01:55:44PM -0400, Sasha Levin wrote:
> On Tue, May 16, 2023 at 05:15:58PM +0200, Pablo Neira Ayuso wrote:
> > Hi Greg, Sasha,
> > 
> > This is second round of -stable backport fixes for 4.14. This batch
> > includes dependency patches which are not currently in the 4.14 branch.
> > 
> > The following list shows the backported patches, I am using original
> > commit IDs for reference:
> > 
> > 1) 08a01c11a5bb ("netfilter: nftables: statify nft_parse_register()")
> > 
> > 2) 6e1acfa387b9 ("netfilter: nf_tables: validate registers coming from userspace.")
> > 
> > 3) 20a1452c3542 ("netfilter: nf_tables: add nft_setelem_parse_key()")
> > 
> > 4) fdb9c405e35b ("netfilter: nf_tables: allow up to 64 bytes in the set element data area")
> > 
> > 5) 7e6bc1f6cabc ("netfilter: nf_tables: stricter validation of element data")
> > 
> > 6) 215a31f19ded ("netfilter: nft_dynset: do not reject set updates with NFT_SET_EVAL")
> > 
> > 7) 36d5b2913219 ("netfilter: nf_tables: do not allow RULE_ID to refer to another chain")
> > 
> > 8) 470ee20e069a ("netfilter: nf_tables: do not allow SET_ID to refer to another table")
> 
> I've applied the 5.4 and 4.19 series, but it looks like patch #1 here
> fails to apply. Could you please re-send the 4.14 series?

Sure, I'll rebase and resend v2. Thanks.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2023-05-23  8:42 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-05-16 15:15 [PATCH -stable,4.14 0/8] more stable fixes for 4.14 Pablo Neira Ayuso
2023-05-16 15:15 ` [PATCH -stable,4.14 1/8] netfilter: nftables: statify nft_parse_register() Pablo Neira Ayuso
2023-05-16 15:16 ` [PATCH -stable,4.14 2/8] netfilter: nf_tables: validate registers coming from userspace Pablo Neira Ayuso
2023-05-16 15:16 ` [PATCH -stable,4.14 3/8] netfilter: nf_tables: add nft_setelem_parse_key() Pablo Neira Ayuso
2023-05-16 15:16 ` [PATCH -stable,4.14 4/8] netfilter: nf_tables: allow up to 64 bytes in the set element data area Pablo Neira Ayuso
2023-05-16 15:16 ` [PATCH -stable,4.14 5/8] netfilter: nf_tables: stricter validation of element data Pablo Neira Ayuso
2023-05-16 15:16 ` [PATCH -stable,4.14 6/8] netfilter: nft_dynset: do not reject set updates with NFT_SET_EVAL Pablo Neira Ayuso
2023-05-16 15:16 ` [PATCH -stable,4.14 7/8] netfilter: nf_tables: do not allow RULE_ID to refer to another chain Pablo Neira Ayuso
2023-05-16 15:16 ` [PATCH -stable,4.14 8/8] netfilter: nf_tables: do not allow SET_ID to refer to another table Pablo Neira Ayuso
2023-05-22 17:55 ` [PATCH -stable,4.14 0/8] more stable fixes for 4.14 Sasha Levin
2023-05-23  8:41   ` Pablo Neira Ayuso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).