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:
 <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

Powered by Openwall GNU/*/Linux Powered by OpenVZ