lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20201016200226.23994-2-ceggers@arri.de>
Date:   Fri, 16 Oct 2020 22:02:24 +0200
From:   Christian Eggers <ceggers@...i.de>
To:     Andrew Lunn <andrew@...n.ch>,
        Vivien Didelot <vivien.didelot@...il.com>,
        Florian Fainelli <f.fainelli@...il.com>,
        Vladimir Oltean <olteanv@...il.com>,
        Jakub Kicinski <kuba@...nel.org>,
        Kurt Kanzenbach <kurt@...utronix.de>
CC:     "David S . Miller" <davem@...emloft.net>,
        Woojung Huh <woojung.huh@...rochip.com>,
        Microchip Linux Driver Support <UNGLinuxDriver@...rochip.com>,
        <netdev@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
        Christian Eggers <ceggers@...i.de>
Subject: [PATCH net-next 1/3] net: dsa: don't pass cloned skb's to drivers xmit function

Ensure that the skb is not cloned and has enough tail room for the tail
tag. This code will be removed from the drivers in the next commits.

Signed-off-by: Christian Eggers <ceggers@...i.de>
---
 net/dsa/dsa_priv.h |  3 +++
 net/dsa/slave.c    | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 12998bf04e55..975001c625b1 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -77,6 +77,9 @@ struct dsa_slave_priv {
 	/* Copy of CPU port xmit for faster access in slave transmit hot path */
 	struct sk_buff *	(*xmit)(struct sk_buff *skb,
 					struct net_device *dev);
+	/* same for tail_tag and overhead */
+	bool tail_tag;
+	unsigned int overhead;
 
 	struct pcpu_sw_netstats	__percpu *stats64;
 
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 3bc5ca40c9fb..49a19a3b0736 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -553,6 +553,7 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct dsa_slave_priv *p = netdev_priv(dev);
 	struct pcpu_sw_netstats *s;
 	struct sk_buff *nskb;
+	int padlen;
 
 	s = this_cpu_ptr(p->stats64);
 	u64_stats_update_begin(&s->syncp);
@@ -567,6 +568,41 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev)
 	 */
 	dsa_skb_tx_timestamp(p, skb);
 
+	/* We have to pad he packet to the minimum Ethernet frame size,
+	 * if necessary, before adding the trailer (tail tagging only).
+	 */
+	padlen = (skb->len >= ETH_ZLEN) ? 0 : ETH_ZLEN - skb->len;
+
+	/* To keep the slave's xmit() methods simple, don't pass cloned skbs to
+	 * them. Additionally ensure, that suitable room for tail tagging is
+	 * available.
+	 */
+	if (skb_cloned(skb) ||
+	    (p->tail_tag && skb_tailroom(skb) < (padlen + p->overhead))) {
+		struct sk_buff *nskb;
+
+		nskb = alloc_skb(NET_IP_ALIGN + skb->len +
+				 padlen + p->overhead, GFP_ATOMIC);
+		if (!nskb) {
+			kfree_skb(skb);
+			return NETDEV_TX_OK;
+		}
+		skb_reserve(nskb, NET_IP_ALIGN);
+
+		skb_reset_mac_header(nskb);
+		skb_set_network_header(nskb,
+				       skb_network_header(skb) - skb->head);
+		skb_set_transport_header(nskb,
+					 skb_transport_header(skb) - skb->head);
+		skb_copy_and_csum_dev(skb, skb_put(nskb, skb->len));
+		consume_skb(skb);
+
+		if (padlen)
+			skb_put_zero(nskb, padlen);
+
+		skb = nskb;
+	}
+
 	/* Transmit function may have to reallocate the original SKB,
 	 * in which case it must have freed it. Only free it here on error.
 	 */
@@ -1814,6 +1850,8 @@ int dsa_slave_create(struct dsa_port *port)
 	p->dp = port;
 	INIT_LIST_HEAD(&p->mall_tc_list);
 	p->xmit = cpu_dp->tag_ops->xmit;
+	p->tail_tag = cpu_dp->tag_ops->tail_tag;
+	p->overhead = cpu_dp->tag_ops->overhead;
 	port->slave = slave_dev;
 
 	rtnl_lock();
-- 
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ