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: <aMqCPVmOArg8dIqR@shell.armlinux.org.uk>
Date: Wed, 17 Sep 2025 10:41:17 +0100
From: "Russell King (Oracle)" <linux@...linux.org.uk>
To: Thomas Gleixner <tglx@...utronix.de>
Cc: LKML <linux-kernel@...r.kernel.org>,
	Linus Torvalds <torvalds@...ux-foundation.org>,
	Peter Zijlstra <peterz@...radead.org>,
	kernel test robot <lkp@...el.com>,
	linux-arm-kernel@...ts.infradead.org,
	Nathan Chancellor <nathan@...nel.org>,
	Christophe Leroy <christophe.leroy@...roup.eu>,
	Darren Hart <dvhart@...radead.org>,
	Davidlohr Bueso <dave@...olabs.net>,
	André Almeida <andrealmeid@...lia.com>,
	x86@...nel.org, Alexander Viro <viro@...iv.linux.org.uk>,
	Christian Brauner <brauner@...nel.org>, Jan Kara <jack@...e.cz>,
	linux-fsdevel@...r.kernel.org
Subject: Re: [patch V2 1/6] ARM: uaccess: Implement missing
 __get_user_asm_dword()

On Wed, Sep 17, 2025 at 07:48:00AM +0200, Thomas Gleixner wrote:
> On Tue, Sep 16 2025 at 22:26, Russell King wrote:
> > On Tue, Sep 16, 2025 at 06:33:09PM +0200, Thomas Gleixner wrote:
> >> When CONFIG_CPU_SPECTRE=n then get_user() is missing the 8 byte ASM variant
> >> for no real good reason. This prevents using get_user(u64) in generic code.
> >
> > I'm sure you will eventually discover the reason when you start getting
> > all the kernel build bot warnings that will result from a cast from a
> > u64 to a pointer.
> 
> I really don't know which cast you are talking about.

I'll grant you that the problem is not obvious. It comes about because
of all the different types that get_user() is subject to - it's not
just integers, it's also pointers.

The next bit to realise is that casting between integers that are not
the same size as a pointer causes warnings. For example, casting
between a 64-bit integer type and pointer type causes the compiler to
emit a warning. It doesn't matter if the code path ends up being
optimised away, the warning is still issued.

Putting together a simple test case, where the only change is making
__gu_val an unsigned long long:

t.c: In function ‘get_ptr’:
t.c:40:15: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
   40 |         (x) = (__typeof__(*(ptr)))__gu_val;                             \
      |               ^
t.c:21:9: note: in expansion of macro ‘__get_user_err’
   21 |         __get_user_err((x), (ptr), __gu_err, TUSER());                  \
      |         ^~~~~~~~~~~~~~
t.c:102:16: note: in expansion of macro ‘__get_user’
  102 |         return __get_user(p, ptr);
      |                ^~~~~~~~~~

In order for the code you are modifying to be reachable, you need to
build with CONFIG_CPU_SPECTRE disabled. This is produced by:

int get_ptr(void **ptr)
{
        void *p;

        return __get_user(p, ptr);
}

Now, one idea may be to declare __gu_val as:

	__typeof__(x) __gu_val;

but then we run into:

t.c: In function ‘get_ptr’:
t.c:37:29: error: assignment to ‘void *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
   37 |         default: (__gu_val) = __get_user_bad();                         \
      |                             ^
t.c:21:9: note: in expansion of macro ‘__get_user_err’
   21 |         __get_user_err((x), (ptr), __gu_err, TUSER());                  \
      |         ^~~~~~~~~~~~~~
t.c:102:16: note: in expansion of macro ‘__get_user’
  102 |         return __get_user(p, ptr);
      |                ^~~~~~~~~~

You may think this is easy to solve, just change the last cast to:

	(x) = (__typeof__(*(ptr)))(__typeof__(x))__gu_val;

but that doesn't work either (because in the test case __typeof__(x) is
still a pointer type. You can't cast this down to a 32-bit quantity
because that will knock off the upper 32 bits for the case you're trying
to add.

You may think, why not  move this cast into each switch statement...
there will still be warnings because the cast is still reachable at the
point the compiler evaluates the code for warnings, even though the
optimiser gets rid of it later.

Feel free to try to solve this, but I can assure you that you certainly
are not the first. Several people have already tried.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ