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: <2234a5e1-5926-4b2d-a8f2-c780bf374a27@csgroup.eu>
Date: Tue, 10 Sep 2024 14:28:52 +0200
From: Christophe Leroy <christophe.leroy@...roup.eu>
To: Arnd Bergmann <arnd@...db.de>,
 Vincenzo Frascino <vincenzo.frascino@....com>, linux-kernel@...r.kernel.org,
 Linux-Arch <linux-arch@...r.kernel.org>, linux-mm@...ck.org
Cc: Andy Lutomirski <luto@...nel.org>, Thomas Gleixner <tglx@...utronix.de>,
 "Jason A . Donenfeld" <Jason@...c4.com>,
 Michael Ellerman <mpe@...erman.id.au>, Nicholas Piggin <npiggin@...il.com>,
 Naveen N Rao <naveen@...nel.org>, Ingo Molnar <mingo@...hat.com>,
 Borislav Petkov <bp@...en8.de>, Dave Hansen <dave.hansen@...ux.intel.com>,
 "H. Peter Anvin" <hpa@...or.com>, Theodore Ts'o <tytso@....edu>,
 Andrew Morton <akpm@...ux-foundation.org>,
 Steven Rostedt <rostedt@...dmis.org>, Masami Hiramatsu
 <mhiramat@...nel.org>, Mathieu Desnoyers <mathieu.desnoyers@...icios.com>
Subject: Re: [PATCH 3/9] x86: vdso: Introduce asm/vdso/page.h



Le 08/09/2024 à 22:48, Arnd Bergmann a écrit :
> On Fri, Sep 6, 2024, at 18:40, Christophe Leroy wrote:
>> Le 06/09/2024 à 21:19, Arnd Bergmann a écrit :
>>> On Fri, Sep 6, 2024, at 11:20, Vincenzo Frascino wrote:
> 
>>>> Looking at the definition of PAGE_SIZE and PAGE_MASK for each architecture they
>>>> all depend on CONFIG_PAGE_SHIFT but they are slightly different, e.g.:
>>>>
>>>> x86:
>>>> #define PAGE_SIZE        (_AC(1,UL) << PAGE_SHIFT)
>>>>
>>>> powerpc:
>>>> #define PAGE_SIZE        (ASM_CONST(1) << PAGE_SHIFT)
>>>>
>>>> hence I left to the architecture the responsibility of redefining the constants
>>>> for the VSDO.
>>>
>>> ASM_CONST() is a powerpc-specific macro that is defined the
>>> same way as _AC(). We could probably just replace all ASM_CONST()
>>> as a cleanup, but for this purpose, just remove the custom PAGE_SIZE
>>> and PAGE_SHIFT macros. This can be a single patch fro all
>>> architectures.
>>>
>>
>> I'm not worried about _AC versus ASM_CONST, but I am by the 1UL versus 1.
>>
>>
>> This can be a problem on 32 bits platforms with 64 bits phys_addr_t
> 
> But that would already be a bug if anything used this, however
> none of them do. The only instance of an open-coded
> 
> #define PAGE_SIZE       (1 << PAGE_SHIFT)
> 
> is from openrisc, but that is only used inside of __ASSEMBLY__, for
> the same effect as _AC().

Maybe I was not clear enough. The problem is not with PAGE_SHIFT but 
with PAGE_MASK, and that's what I show with my exemple.

If take the definition from ARM64 (which is the same as several other 
artchitectures):

#define PAGE_SIZE		(_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK		(~(PAGE_SIZE-1))

PAGE_SHIFT is 12
PAGE_SIZE is then 4096 UL
PAGE_MASK is then 0xfffff000 UL

So if I take the probe() in drivers/uio/uio_pci_generic.c, it has:

	uiomem->addr = r->start & PAGE_MASK;

uiomem->addr is a phys_addr_t
r->start is a ressource_size_t hence a phys_addr_t

And phys_addr_t is defined as:

	#ifdef CONFIG_PHYS_ADDR_T_64BIT
	typedef u64 phys_addr_t;
	#else
	typedef u32 phys_addr_t;
	#endif

On a 32 bits platform, UL is unsigned 32 bits, so the r->start & 
PAGE_MASK will and r->start with 0x00000000fffff000

That is wrong.


That's the reason why powerpc does not define PAGE_MASK like ARM64 but 
defines PAGE_MASK as:

	(~((1 << PAGE_SHIFT) - 1))

When using 1 instead of 1UL, PAGE_MASK is still 0xfffff000 but it is a 
signed constant, so when it is anded with an u64, it gets 
signed-extended to 0xfffffffffffff000 which gives the expected result.

That's what I wanted to illustrate with the exemple in my previous 
message. The function f() was using the signed PAGE_MASK while function 
g() was using the unsigned PAGE_MASK:

00000000 <f>:
    0:    54 84 00 26     clrrwi  r4,r4,12
    4:    4e 80 00 20     blr

00000008 <g>:
    8:    54 84 00 26     clrrwi  r4,r4,12
    c:    38 60 00 00     li      r3,0
   10:    4e 80 00 20     blr

Function f() returns the given u64 value with the 12 lowest bits cleared
Function g() returns the given u64 value with the 12 lowest bits cleared 
and the 32 highest bits cleared as well, which is unexpected.

Christophe

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ