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
| ||
|
Message-ID: <DM3PR11MB8736CCEC9ADD424FEE973E1DEC8AA@DM3PR11MB8736.namprd11.prod.outlook.com> Date: Fri, 9 May 2025 22:18:17 +0000 From: <Tristram.Ha@...rochip.com> To: <jakobunt@...il.com> CC: <quentin.schulz@...rry.de>, <jakob.unterwurzacher@...rry.de>, <netdev@...r.kernel.org>, <linux-kernel@...r.kernel.org>, <Woojung.Huh@...rochip.com>, <UNGLinuxDriver@...rochip.com>, <andrew@...n.ch>, <olteanv@...il.com>, <davem@...emloft.net>, <edumazet@...gle.com>, <kuba@...nel.org>, <pabeni@...hat.com>, <horms@...nel.org> Subject: RE: [PATCH] net: dsa: microchip: linearize skb for tail-tagging switches > The pointer arithmentic for accessing the tail tag does not > seem to handle nonlinear skbs. > > For nonlinear skbs, it reads uninitialized memory inside the > skb headroom, essentially randomizing the tag, breaking user > traffic. > > Example where ksz9477_rcv thinks that the packet from port 1 comes > from port 6 (which does not exist for the ksz9896 that's in use), > dropping the packet. Debug prints added by me (not included in > this patch): > > [ 256.645337] ksz9477_rcv:323 tag0=6 > [ 256.645349] skb len=47 headroom=78 headlen=0 tailroom=0 > mac=(64,14) mac_len=14 net=(78,0) trans=78 > shinfo(txflags=0 nr_frags=1 gso(size=0 type=0 segs=0)) > csum(0x0 start=0 offset=0 ip_summed=0 complete_sw=0 valid=0 > level=0) > hash(0x0 sw=0 l4=0) proto=0x00f8 pkttype=1 iif=3 > priority=0x0 mark=0x0 alloc_cpu=0 vlan_all=0x0 > encapsulation=0 inner(proto=0x0000, mac=0, net=0, trans=0) > [ 256.645377] dev name=end1 feat=0x0002e10200114bb3 > [ 256.645386] skb headroom: 00000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 > [ 256.645395] skb headroom: 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 > [ 256.645403] skb headroom: 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 > [ 256.645411] skb headroom: 00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 > 00 00 00 > [ 256.645420] skb headroom: 00000040: ff ff ff ff ff ff 00 1c 19 f2 e2 db 08 06 > [ 256.645428] skb frag: 00000000: 00 01 08 00 06 04 00 01 00 1c 19 f2 e2 db > 0a 02 > [ 256.645436] skb frag: 00000010: 00 83 00 00 00 00 00 00 0a 02 a0 2f 00 00 > 00 00 > [ 256.645444] skb frag: 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > 01 > [ 256.645452] ksz_common_rcv:92 dsa_conduit_find_user returned NULL > > Call skb_linearize before trying to access the tag. > > This patch fixes ksz9477_rcv which is used by the ksz9896 I have at > hand, and also applies the same fix to ksz8795_rcv which seems to have > the same problem. > > Tested on v6.12.19 and today's master (d76bb1ebb5587f66b). > > Signed-off-by: Jakob Unterwurzacher <jakob.unterwurzacher@...rry.de> > --- > net/dsa/tag_ksz.c | 14 ++++++++++++-- > 1 file changed, 12 insertions(+), 2 deletions(-) > > diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c > index c33d4bf17929..7fbcdb7f152a 100644 > --- a/net/dsa/tag_ksz.c > +++ b/net/dsa/tag_ksz.c > @@ -140,7 +140,12 @@ static struct sk_buff *ksz8795_xmit(struct sk_buff *skb, > struct net_device *dev) > > static struct sk_buff *ksz8795_rcv(struct sk_buff *skb, struct net_device *dev) > { > - u8 *tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN; > + u8 *tag; > + > + if (skb_linearize(skb)) > + return NULL; > + > + tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN; > > return ksz_common_rcv(skb, dev, tag[0] & KSZ8795_TAIL_TAG_EG_PORT_M, > KSZ_EGRESS_TAG_LEN); > @@ -311,8 +316,13 @@ static struct sk_buff *ksz9477_xmit(struct sk_buff *skb, > > static struct sk_buff *ksz9477_rcv(struct sk_buff *skb, struct net_device *dev) > { > + u8 *tag; > + > + if (skb_linearize(skb)) > + return NULL; > + > /* Tag decoding */ > - u8 *tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN; > + tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN; > unsigned int port = tag[0] & KSZ9477_TAIL_TAG_EG_PORT_M; > unsigned int len = KSZ_EGRESS_TAG_LEN; > I am curious about what MAC controller are you using to return socket buffer with fragments? I thought DSA already disables most advanced hardware acceleration features so that the tag manipulation functions do not need to worry about accessing the socket buffer incorrectly. Now that the socket buffer has fragment is it better to remove the tail tag inside the fragment to preserve the performance of receiving such socket buffer? I know using skb_linearize() is an easy fix, but is it worthwhile to check the receive performance? This is out of topic. The transmit performance can be improved by keeping the fragments while adding the tail tag. At one time there is an API in the kernel to do that, but it was removed as nobody used it. I see the hardware checksum generation feature is now preserved so the tag manipulation functions need to handle it. Is there a way to allocate a few more bytes in the fragments so that the socket buffer does not need to be consolidated to add tail tag?
Powered by blists - more mailing lists