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: <20230922200042.GA1981-beaub@linux.microsoft.com>
Date:   Fri, 22 Sep 2023 13:00:42 -0700
From:   Beau Belgrave <beaub@...ux.microsoft.com>
To:     Clément Léger <cleger@...osinc.com>
Cc:     Steven Rostedt <rostedt@...dmis.org>,
        Masami Hiramatsu <mhiramat@...nel.org>,
        linux-kernel@...r.kernel.org, linux-trace-kernel@...r.kernel.org
Subject: Re: [PATCH] tracing/user_events: align uaddr on unsigned long
 alignment

On Tue, Sep 19, 2023 at 02:59:12PM +0200, Clément Léger wrote:
> 
> 
> On 14/09/2023 19:29, Steven Rostedt wrote:
> > On Thu, 14 Sep 2023 13:17:00 -0400
> > Steven Rostedt <rostedt@...dmis.org> wrote:
> > 
> >> Now lets look at big endian layout:
> >>
> >>  uaddr = 0xbeef0004
> >>  enabler = 1;
> >>
> >>  memory at 0xbeef0000:  00 00 00 00 00 00 00 02
> >>                                     ^
> >>                                     addr: 0xbeef0004
> >>
> >> 				(enabler is set )
> >>
> >> 	bitoffset = uaddr & (sizeof(unsigned long) - 1); bitoffset = 4
> >> 	bit_offset *= 8;				 bitoffset = 32
> >> 	uaddr &= ~(sizeof(unsigned long) - 1);		 uaddr = 0xbeef0000
> >>
> >> 	ptr = kaddr + (uaddr & ~PAGE_MASK);
> >>
> >> 	clear_bit(1 + 32, ptr);
> >>
> >>  memory at 0xbeef0000:  00 00 00 00 00 00 00 02
> >>                                   ^
> >> 				bit 33 of 0xbeef0000
> >>
> >> I don't think that's what you expected!
> > 
> > I believe the above can be fixed with:
> > 
> > 	bit_offset = uaddr & (sizeof(unsigned long) - 1);
> > 	if (bit_offset) {
> > #ifdef CONFIG_CPU_BIG_ENDIAN
> > 		bit_offest = 0;
> > #else
> > 		bit_offset *= BITS_PER_BYTE;
> > #endif
> > 		uaddr &= ~(sizeof(unsigned long) - 1);
> > 	}
> > 
> > -- Steve
> 
> 
> Actually, after looking more in depth at that, it seems like there are
> actually 2 problems that can happen.
> 
> First one is atomic access misalignment due to enable_size == 4 and
> uaddr not being aligned on a (long) boundary on 64 bits architecture.
> This can generate misaligned exceptions on various architectures. This
> can be fixed in a more general way according to Masami snippet.
> 
> Second one that I can see is on 64 bits, big endian architectures with
> enable_size == 4. In that case, the bit provided by the userspace won't
> be correctly set since this code kind of assume that the atomic are done
> on 32bits value. Since the kernel assume long sized atomic operation, on
> big endian 64 bits architecture, the updated bit will actually be in the
> next 32 bits word.
> 
> Can someone confirm my understanding ?
> 

Actually, I take back some of what I said [1]. If a 32-bit on a 64-bit
kernel comes in on BE, and is aligned, we do need to offset the bits as
well (just verified on my ppc64 BE VM).

You should be able to use that patch as a base though and add a flag to
struct user_event_enabler when this case occurs. Then in the
align_addr_bit() adjust the bits as well upon aligned cases.

Thanks,
-Beau

1. https://lore.kernel.org/linux-trace-kernel/20230922192231.GA1828-beaub@linux.microsoft.com/

> Clément

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ