summaryrefslogtreecommitdiff
path: root/net/dsa
diff options
context:
space:
mode:
authorAndrew Lunn <andrew@lunn.ch>2018-04-07 20:37:40 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-04-24 09:36:39 +0200
commit30593709f80ddf23a3e8b41f3a7edfc68c4786be (patch)
tree8025231ce002bff05766db48fbabef1d1ca5e0b6 /net/dsa
parent90a32d1f0ec9844b7984f52f07fe7bcb0abfb6a7 (diff)
net: dsa: Discard frames from unused ports
commit fc5f33768cca7144f8d793205b229d46740d183b upstream. The Marvell switches under some conditions will pass a frame to the host with the port being the CPU port. Such frames are invalid, and should be dropped. Not dropping them can result in a crash when incrementing the receive statistics for an invalid port. This has been reworked for 4.14, which does not have the central dsa_master_find_slave() function, so each tag driver needs to check. Reported-by: Chris Healy <cphealy@gmail.com> Fixes: 91da11f870f0 ("net: Distributed Switch Architecture protocol support") Signed-off-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/dsa')
-rw-r--r--net/dsa/tag_brcm.c3
-rw-r--r--net/dsa/tag_dsa.c3
-rw-r--r--net/dsa/tag_edsa.c3
-rw-r--r--net/dsa/tag_ksz.c3
-rw-r--r--net/dsa/tag_lan9303.c3
-rw-r--r--net/dsa/tag_mtk.c3
-rw-r--r--net/dsa/tag_qca.c3
-rw-r--r--net/dsa/tag_trailer.c3
8 files changed, 24 insertions, 0 deletions
diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c
index dbb016434ace..de92fc1fc3be 100644
--- a/net/dsa/tag_brcm.c
+++ b/net/dsa/tag_brcm.c
@@ -121,6 +121,9 @@ static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev,
if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
return NULL;
+ if (unlikely(ds->cpu_port_mask & BIT(source_port)))
+ return NULL;
+
/* Remove Broadcom tag and update checksum */
skb_pull_rcsum(skb, BRCM_TAG_LEN);
diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c
index fbf9ca954773..b3008a9bacf3 100644
--- a/net/dsa/tag_dsa.c
+++ b/net/dsa/tag_dsa.c
@@ -107,6 +107,9 @@ static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev,
if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
return NULL;
+ if (unlikely(ds->cpu_port_mask & BIT(source_port)))
+ return NULL;
+
/*
* Convert the DSA header to an 802.1q header if the 'tagged'
* bit in the DSA header is set. If the 'tagged' bit is clear,
diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c
index 76367ba1b2e2..c86b6d90576d 100644
--- a/net/dsa/tag_edsa.c
+++ b/net/dsa/tag_edsa.c
@@ -120,6 +120,9 @@ static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev,
if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
return NULL;
+ if (unlikely(ds->cpu_port_mask & BIT(source_port)))
+ return NULL;
+
/*
* If the 'tagged' bit is set, convert the DSA tag to a 802.1q
* tag and delete the ethertype part. If the 'tagged' bit is
diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
index 010ca0a336c4..6c894692b9cd 100644
--- a/net/dsa/tag_ksz.c
+++ b/net/dsa/tag_ksz.c
@@ -92,6 +92,9 @@ static struct sk_buff *ksz_rcv(struct sk_buff *skb, struct net_device *dev,
if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
return NULL;
+ if (unlikely(ds->cpu_port_mask & BIT(source_port)))
+ return NULL;
+
pskb_trim_rcsum(skb, skb->len - KSZ_EGRESS_TAG_LEN);
skb->dev = ds->ports[source_port].netdev;
diff --git a/net/dsa/tag_lan9303.c b/net/dsa/tag_lan9303.c
index 0b9826105e42..2d1603009e16 100644
--- a/net/dsa/tag_lan9303.c
+++ b/net/dsa/tag_lan9303.c
@@ -108,6 +108,9 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev,
return NULL;
}
+ if (unlikely(ds->cpu_port_mask & BIT(source_port)))
+ return NULL;
+
if (!ds->ports[source_port].netdev) {
dev_warn_ratelimited(&dev->dev, "Dropping packet due to invalid netdev or device\n");
return NULL;
diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c
index ec8ee5f43255..5c471854412d 100644
--- a/net/dsa/tag_mtk.c
+++ b/net/dsa/tag_mtk.c
@@ -81,6 +81,9 @@ static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev,
if (!ds->ports[port].netdev)
return NULL;
+ if (unlikely(ds->cpu_port_mask & BIT(port)))
+ return NULL;
+
skb->dev = ds->ports[port].netdev;
return skb;
diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c
index 1d4c70711c0f..b8c05f1cf47d 100644
--- a/net/dsa/tag_qca.c
+++ b/net/dsa/tag_qca.c
@@ -104,6 +104,9 @@ static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, struct net_device *dev,
if (!ds->ports[port].netdev)
return NULL;
+ if (unlikely(ds->cpu_port_mask & BIT(port)))
+ return NULL;
+
/* Update skb & forward the frame accordingly */
skb->dev = ds->ports[port].netdev;
diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c
index d2fd4923aa3e..fcc9aa72877d 100644
--- a/net/dsa/tag_trailer.c
+++ b/net/dsa/tag_trailer.c
@@ -76,6 +76,9 @@ static struct sk_buff *trailer_rcv(struct sk_buff *skb, struct net_device *dev,
if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
return NULL;
+ if (unlikely(ds->cpu_port_mask & BIT(source_port)))
+ return NULL;
+
pskb_trim_rcsum(skb, skb->len - 4);
skb->dev = ds->ports[source_port].netdev;