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: <20210505131943.ci2svd6fmb22y7ac@treble>
Date:   Wed, 5 May 2021 08:19:43 -0500
From:   Josh Poimboeuf <jpoimboe@...hat.com>
To:     David Laight <David.Laight@...LAB.COM>
Cc:     Al Viro <viro@...iv.linux.org.uk>,
        "x86@...nel.org" <x86@...nel.org>,
        "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
        Linus Torvalds <torvalds@...ux-foundation.org>,
        Will Deacon <will@...nel.org>,
        Dan Williams <dan.j.williams@...el.com>,
        Andrea Arcangeli <aarcange@...hat.com>,
        Waiman Long <longman@...hat.com>,
        Peter Zijlstra <peterz@...radead.org>,
        Thomas Gleixner <tglx@...utronix.de>,
        Andrew Cooper <andrew.cooper3@...rix.com>,
        Andy Lutomirski <luto@...nel.org>,
        Christoph Hellwig <hch@....de>,
        Mark Rutland <mark.rutland@....com>,
        Borislav Petkov <bp@...en8.de>
Subject: Re: [PATCH v4 3/4] x86/uaccess: Use pointer masking to limit uaccess
 speculation

On Wed, May 05, 2021 at 08:48:48AM +0000, David Laight wrote:
> From: Josh Poimboeuf
> > Sent: 05 May 2021 04:55
> > 
> > The x86 uaccess code uses barrier_nospec() in various places to prevent
> > speculative dereferencing of user-controlled pointers (which might be
> > combined with further gadgets or CPU bugs to leak data).
> ...
> > Remove existing barrier_nospec() usage, and instead do user pointer
> > masking, throughout the x86 uaccess code.  This is similar to what arm64
> > is already doing with uaccess_mask_ptr().
> ...
> > diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
> > index fb75657b5e56..ebe9ab46b183 100644
> > --- a/arch/x86/include/asm/uaccess.h
> > +++ b/arch/x86/include/asm/uaccess.h
> > @@ -66,12 +66,35 @@ static inline bool pagefault_disabled(void);
> >   * Return: true (nonzero) if the memory block may be valid, false (zero)
> >   * if it is definitely invalid.
> >   */
> > -#define access_ok(addr, size)					\
> > +#define access_ok(addr, size)						\
> >  ({									\
> >  	WARN_ON_IN_IRQ();						\
> >  	likely(!__range_not_ok(addr, size, TASK_SIZE_MAX));		\
> >  })
> > 
> > +/*
> > + * Sanitize a user pointer such that it becomes NULL if it's not a valid user
> > + * pointer.  This prevents speculatively dereferencing a user-controlled
> > + * pointer to kernel space if access_ok() speculatively returns true.  This
> > + * should be done *after* access_ok(), to avoid affecting error handling
> > + * behavior.
> > + */
> > +#define mask_user_ptr(ptr)						\
> > +({									\
> > +	unsigned long _ptr = (__force unsigned long)ptr;		\
> > +	unsigned long mask;						\
> > +									\
> > +	asm volatile("cmp %[max], %[_ptr]\n\t"				\
> > +		     "sbb %[mask], %[mask]\n\t"				\
> > +		     : [mask] "=r" (mask)				\
> > +		     : [_ptr] "r" (_ptr),				\
> > +		       [max] "r" (TASK_SIZE_MAX)			\
> > +		     : "cc");						\
> > +									\
> > +	mask &= _ptr;							\
> > +	((typeof(ptr)) mask);						\
> > +})
> > +
> 
> access_ok() and mask_user_ptr() are doing much the same check.
> Is there scope for making access_ok() return the masked pointer?
> 
> So the canonical calling code would be:
> 	uptr = access_ok(uptr, size);
> 	if (!uptr)
> 		return -EFAULT;
> 
> This would error requests for address 0 earlier - but I don't
> believe they are ever valid in Linux.
> (Some historic x86 a.out formats did load to address 0.)
> 
> Clearly for a follow up patch.

Yeah.  I mentioned a similar idea in the cover letter.

But I'm thinking we should still rename it to access_ok_mask(), or
otherwise change the API to avoid the masked value getting ignored.

But that'll be a much bigger patch.

-- 
Josh

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ