netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net 0/3] amt: fix several bugs in amt_rcv()
@ 2022-06-02 14:01 Taehee Yoo
  2022-06-02 14:01 ` [PATCH net 1/3] amt: fix wrong usage of pskb_may_pull() Taehee Yoo
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Taehee Yoo @ 2022-06-02 14:01 UTC (permalink / raw)
  To: davem, kuba, pabeni, edumazet, netdev; +Cc: ap420073

This series fixes bugs in amt_rcv().

First patch fixes pskb_may_pull() issue.
Some functions missed to call pskb_may_pull() and uses wrong
parameter of pskb_may_pull().

Second patch fixes possible null-ptr-deref in amt_rcv().
If there is no amt private data in sock, skb will be freed.
And it increases stats.
But in order to increase stats, amt private data is needed.
So, uninitialised pointer will be used at that point.

Third patch fixes wrong definition of type_str[] in amt.c

Taehee Yoo (3):
  amt: fix wrong usage of pskb_may_pull()
  amt: fix possible null-ptr-deref in amt_rcv()
  amt: fix wrong type string definition

 drivers/net/amt.c | 59 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 40 insertions(+), 19 deletions(-)

-- 
2.17.1


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

* [PATCH net 1/3] amt: fix wrong usage of pskb_may_pull()
  2022-06-02 14:01 [PATCH net 0/3] amt: fix several bugs in amt_rcv() Taehee Yoo
@ 2022-06-02 14:01 ` Taehee Yoo
  2022-06-02 14:01 ` [PATCH net 2/3] amt: fix possible null-ptr-deref in amt_rcv() Taehee Yoo
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Taehee Yoo @ 2022-06-02 14:01 UTC (permalink / raw)
  To: davem, kuba, pabeni, edumazet, netdev; +Cc: ap420073

It adds missing pskb_may_pull() in amt_update_handler() and
amt_multicast_data_handler().
And it fixes wrong parameter of pskb_may_pull() in
amt_advertisement_handler() and amt_membership_query_handler().

Reported-by: Jakub Kicinski <kuba@kernel.org>
Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface")
Signed-off-by: Taehee Yoo <ap420073@gmail.com>
---
 drivers/net/amt.c | 55 +++++++++++++++++++++++++++++++----------------
 1 file changed, 37 insertions(+), 18 deletions(-)

diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index ebee5f07a208..900948e135ad 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -2220,8 +2220,7 @@ static bool amt_advertisement_handler(struct amt_dev *amt, struct sk_buff *skb)
 	struct amt_header_advertisement *amta;
 	int hdr_size;
 
-	hdr_size = sizeof(*amta) - sizeof(struct amt_header);
-
+	hdr_size = sizeof(*amta) + sizeof(struct udphdr);
 	if (!pskb_may_pull(skb, hdr_size))
 		return true;
 
@@ -2251,19 +2250,27 @@ static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb)
 	struct ethhdr *eth;
 	struct iphdr *iph;
 
+	hdr_size = sizeof(*amtmd) + sizeof(struct udphdr);
+	if (!pskb_may_pull(skb, hdr_size))
+		return true;
+
 	amtmd = (struct amt_header_mcast_data *)(udp_hdr(skb) + 1);
 	if (amtmd->reserved || amtmd->version)
 		return true;
 
-	hdr_size = sizeof(*amtmd) + sizeof(struct udphdr);
 	if (iptunnel_pull_header(skb, hdr_size, htons(ETH_P_IP), false))
 		return true;
+
 	skb_reset_network_header(skb);
 	skb_push(skb, sizeof(*eth));
 	skb_reset_mac_header(skb);
 	skb_pull(skb, sizeof(*eth));
 	eth = eth_hdr(skb);
+
+	if (!pskb_may_pull(skb, sizeof(*iph)))
+		return true;
 	iph = ip_hdr(skb);
+
 	if (iph->version == 4) {
 		if (!ipv4_is_multicast(iph->daddr))
 			return true;
@@ -2274,6 +2281,9 @@ static bool amt_multicast_data_handler(struct amt_dev *amt, struct sk_buff *skb)
 	} else if (iph->version == 6) {
 		struct ipv6hdr *ip6h;
 
+		if (!pskb_may_pull(skb, sizeof(*ip6h)))
+			return true;
+
 		ip6h = ipv6_hdr(skb);
 		if (!ipv6_addr_is_multicast(&ip6h->daddr))
 			return true;
@@ -2306,8 +2316,7 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
 	struct iphdr *iph;
 	int hdr_size, len;
 
-	hdr_size = sizeof(*amtmq) - sizeof(struct amt_header);
-
+	hdr_size = sizeof(*amtmq) + sizeof(struct udphdr);
 	if (!pskb_may_pull(skb, hdr_size))
 		return true;
 
@@ -2315,22 +2324,27 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
 	if (amtmq->reserved || amtmq->version)
 		return true;
 
-	hdr_size = sizeof(*amtmq) + sizeof(struct udphdr) - sizeof(*eth);
+	hdr_size -= sizeof(*eth);
 	if (iptunnel_pull_header(skb, hdr_size, htons(ETH_P_TEB), false))
 		return true;
+
 	oeth = eth_hdr(skb);
 	skb_reset_mac_header(skb);
 	skb_pull(skb, sizeof(*eth));
 	skb_reset_network_header(skb);
 	eth = eth_hdr(skb);
+	if (!pskb_may_pull(skb, sizeof(*iph)))
+		return true;
+
 	iph = ip_hdr(skb);
 	if (iph->version == 4) {
-		if (!ipv4_is_multicast(iph->daddr))
-			return true;
 		if (!pskb_may_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS +
 				   sizeof(*ihv3)))
 			return true;
 
+		if (!ipv4_is_multicast(iph->daddr))
+			return true;
+
 		ihv3 = skb_pull(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
 		skb_reset_transport_header(skb);
 		skb_push(skb, sizeof(*iph) + AMT_IPHDR_OPTS);
@@ -2345,15 +2359,17 @@ static bool amt_membership_query_handler(struct amt_dev *amt,
 		ip_eth_mc_map(iph->daddr, eth->h_dest);
 #if IS_ENABLED(CONFIG_IPV6)
 	} else if (iph->version == 6) {
-		struct ipv6hdr *ip6h = ipv6_hdr(skb);
 		struct mld2_query *mld2q;
+		struct ipv6hdr *ip6h;
 
-		if (!ipv6_addr_is_multicast(&ip6h->daddr))
-			return true;
 		if (!pskb_may_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS +
 				   sizeof(*mld2q)))
 			return true;
 
+		ip6h = ipv6_hdr(skb);
+		if (!ipv6_addr_is_multicast(&ip6h->daddr))
+			return true;
+
 		mld2q = skb_pull(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
 		skb_reset_transport_header(skb);
 		skb_push(skb, sizeof(*ip6h) + AMT_IP6HDR_OPTS);
@@ -2389,23 +2405,23 @@ static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb)
 {
 	struct amt_header_membership_update *amtmu;
 	struct amt_tunnel_list *tunnel;
-	struct udphdr *udph;
 	struct ethhdr *eth;
 	struct iphdr *iph;
-	int len;
+	int len, hdr_size;
 
 	iph = ip_hdr(skb);
-	udph = udp_hdr(skb);
 
-	if (__iptunnel_pull_header(skb, sizeof(*udph), skb->protocol,
-				   false, false))
+	hdr_size = sizeof(*amtmu) + sizeof(struct udphdr);
+	if (!pskb_may_pull(skb, hdr_size))
 		return true;
 
-	amtmu = (struct amt_header_membership_update *)skb->data;
+	amtmu = (struct amt_header_membership_update *)(udp_hdr(skb) + 1);
 	if (amtmu->reserved || amtmu->version)
 		return true;
 
-	skb_pull(skb, sizeof(*amtmu));
+	if (iptunnel_pull_header(skb, hdr_size, skb->protocol, false))
+		return true;
+
 	skb_reset_network_header(skb);
 
 	list_for_each_entry_rcu(tunnel, &amt->tunnel_list, list) {
@@ -2426,6 +2442,9 @@ static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb)
 	return true;
 
 report:
+	if (!pskb_may_pull(skb, sizeof(*iph)))
+		return true;
+
 	iph = ip_hdr(skb);
 	if (iph->version == 4) {
 		if (ip_mc_check_igmp(skb)) {
-- 
2.17.1


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

* [PATCH net 2/3] amt: fix possible null-ptr-deref in amt_rcv()
  2022-06-02 14:01 [PATCH net 0/3] amt: fix several bugs in amt_rcv() Taehee Yoo
  2022-06-02 14:01 ` [PATCH net 1/3] amt: fix wrong usage of pskb_may_pull() Taehee Yoo
@ 2022-06-02 14:01 ` Taehee Yoo
  2022-06-02 14:01 ` [PATCH net 3/3] amt: fix wrong type string definition Taehee Yoo
  2022-06-06 22:04 ` [PATCH net 0/3] amt: fix several bugs in amt_rcv() patchwork-bot+netdevbpf
  3 siblings, 0 replies; 5+ messages in thread
From: Taehee Yoo @ 2022-06-02 14:01 UTC (permalink / raw)
  To: davem, kuba, pabeni, edumazet, netdev; +Cc: ap420073

When amt interface receives amt message, it tries to obtain amt private
data from sock.
If there is no amt private data, it frees an skb immediately.
After kfree_skb(), it increases the rx_dropped stats.
But in order to use rx_dropped, amt private data is needed.
So, it makes amt_rcv() to do not increase rx_dropped stats when it can
not obtain amt private data.

Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Fixes: 1a1a0e80e005 ("amt: fix possible memory leak in amt_rcv()")
Signed-off-by: Taehee Yoo <ap420073@gmail.com>
---
 drivers/net/amt.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index 900948e135ad..ef483bf51033 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -2698,7 +2698,8 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb)
 	amt = rcu_dereference_sk_user_data(sk);
 	if (!amt) {
 		err = true;
-		goto drop;
+		kfree_skb(skb);
+		goto out;
 	}
 
 	skb->dev = amt->dev;
-- 
2.17.1


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

* [PATCH net 3/3] amt: fix wrong type string definition
  2022-06-02 14:01 [PATCH net 0/3] amt: fix several bugs in amt_rcv() Taehee Yoo
  2022-06-02 14:01 ` [PATCH net 1/3] amt: fix wrong usage of pskb_may_pull() Taehee Yoo
  2022-06-02 14:01 ` [PATCH net 2/3] amt: fix possible null-ptr-deref in amt_rcv() Taehee Yoo
@ 2022-06-02 14:01 ` Taehee Yoo
  2022-06-06 22:04 ` [PATCH net 0/3] amt: fix several bugs in amt_rcv() patchwork-bot+netdevbpf
  3 siblings, 0 replies; 5+ messages in thread
From: Taehee Yoo @ 2022-06-02 14:01 UTC (permalink / raw)
  To: davem, kuba, pabeni, edumazet, netdev; +Cc: ap420073

amt message type definition starts from 1, not 0.
But type_str[] starts from 0.
So, it prints wrong type information.

Fixes: cbc21dc1cfe9 ("amt: add data plane of amt interface")
Signed-off-by: Taehee Yoo <ap420073@gmail.com>
---
 drivers/net/amt.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index ef483bf51033..be2719a3ba70 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -51,6 +51,7 @@ static char *status_str[] = {
 };
 
 static char *type_str[] = {
+	"", /* Type 0 is not defined */
 	"AMT_MSG_DISCOVERY",
 	"AMT_MSG_ADVERTISEMENT",
 	"AMT_MSG_REQUEST",
-- 
2.17.1


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

* Re: [PATCH net 0/3] amt: fix several bugs in amt_rcv()
  2022-06-02 14:01 [PATCH net 0/3] amt: fix several bugs in amt_rcv() Taehee Yoo
                   ` (2 preceding siblings ...)
  2022-06-02 14:01 ` [PATCH net 3/3] amt: fix wrong type string definition Taehee Yoo
@ 2022-06-06 22:04 ` patchwork-bot+netdevbpf
  3 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-06-06 22:04 UTC (permalink / raw)
  To: Taehee Yoo; +Cc: davem, kuba, pabeni, edumazet, netdev

Hello:

This series was applied to netdev/net.git (master)
by Jakub Kicinski <kuba@kernel.org>:

On Thu,  2 Jun 2022 14:01:05 +0000 you wrote:
> This series fixes bugs in amt_rcv().
> 
> First patch fixes pskb_may_pull() issue.
> Some functions missed to call pskb_may_pull() and uses wrong
> parameter of pskb_may_pull().
> 
> Second patch fixes possible null-ptr-deref in amt_rcv().
> If there is no amt private data in sock, skb will be freed.
> And it increases stats.
> But in order to increase stats, amt private data is needed.
> So, uninitialised pointer will be used at that point.
> 
> [...]

Here is the summary with links:
  - [net,1/3] amt: fix wrong usage of pskb_may_pull()
    https://git.kernel.org/netdev/net/c/f55a07074fdd
  - [net,2/3] amt: fix possible null-ptr-deref in amt_rcv()
    https://git.kernel.org/netdev/net/c/d16207f92a4a
  - [net,3/3] amt: fix wrong type string definition
    https://git.kernel.org/netdev/net/c/d7970039d87c

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

end of thread, other threads:[~2022-06-06 22:04 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-06-02 14:01 [PATCH net 0/3] amt: fix several bugs in amt_rcv() Taehee Yoo
2022-06-02 14:01 ` [PATCH net 1/3] amt: fix wrong usage of pskb_may_pull() Taehee Yoo
2022-06-02 14:01 ` [PATCH net 2/3] amt: fix possible null-ptr-deref in amt_rcv() Taehee Yoo
2022-06-02 14:01 ` [PATCH net 3/3] amt: fix wrong type string definition Taehee Yoo
2022-06-06 22:04 ` [PATCH net 0/3] amt: fix several bugs in amt_rcv() patchwork-bot+netdevbpf

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).