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: <nycvar.YSQ.7.78.906.2011060942360.2184@knanqh.ubzr>
Date:   Fri, 6 Nov 2020 10:05:59 -0500 (EST)
From:   Nicolas Pitre <nico@...xnic.net>
To:     David Laight <David.Laight@...LAB.COM>
cc:     'Jakub Kicinski' <kuba@...nel.org>, Andrew Lunn <andrew@...n.ch>,
        netdev <netdev@...r.kernel.org>, Lee Jones <lee.jones@...aro.org>
Subject: RE: [PATCH net-next v2 6/7] drivers: net: smc911x: Fix cast from
 pointer to integer of different size

On Fri, 6 Nov 2020, David Laight wrote:

> From: Jakub Kicinski
> > Sent: 05 November 2020 22:47
> > 
> > On Wed,  4 Nov 2020 16:48:57 +0100 Andrew Lunn wrote:
> > > -	buf = (char*)((u32)skb->data & ~0x3);
> > > -	len = (skb->len + 3 + ((u32)skb->data & 3)) & ~0x3;
> > > -	cmdA = (((u32)skb->data & 0x3) << 16) |
> > > +	offset = (unsigned long)skb->data & 3;
> > > +	buf = skb->data - offset;
> > > +	len = skb->len + offset;
> > > +	cmdA = (offset << 16) |
> > 
> > The len calculation is wrong, you trusted people on the mailing list
> > too much ;)
> 
> I misread what the comment-free convoluted code was doing....
> 
> Clearly it is rounding the base address down to a multiple of 4
> and passing the offset in cmdA.
> This is fine - but quite why the (I assume) hardware doesn't do
> this itself and just document that it does a 32bit read is
> another matter - the logic will be much the same and I doubt
> anything modern is that pushed for space.
> 
> However rounding the length up to a multiple of 4 is buggy.
> If this is an ethernet chipset it must (honest) be able to
> send frames that don't end on a 4 byte boundary.
> So rounding up the length is very dubious.

I probably wrote that code. Probably something like 20 years ago at this 
point. I no longer have access to the actual hardware either.

But my recollection is that this ethernet chip had the ability to do 1, 
2 or 4 byte wide data transfers.

To be able to efficiently use I/O helpers like readsl()/writesl() on 
ARM, the host memory pointer had to be aligned to a 32-bit boundary 
because misaligned accesses were not supported by the hardware and 
therefore were very costly to perform in software with a bytewise 
approach. Remember that back then, the CPU clock was very close to the 
actual ethernet throughput and PIO was the only option.

This was made even worse by the fact that, on some boards, the hw 
designers didn't consider connecting the byte select signals as a 
worthwhile thing to do. That means only 32-bit wide access to the chip 
were possible.

So to work around this, the skb buffer address was rounded down, the 
length was rounded up, and 
the on-chip pointer was adjusted to refer to the actual data 
payload accordingly with the original length. Therefore the proposed 
patch is indeed wrong.

Just to say that, although the code might look suspicious, there was a 
reason for that and it did work correctly for a long long time at this 
point. Obviously those were only 32- bit systems (I really doubt those 
ethernet chips were ever used on 64-bit systems).


Nicolas

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ