Messages in this thread | | | Date | Wed, 18 Jan 2023 16:49:57 +0100 | From | Peter Zijlstra <> | Subject | Re: [PATCHv14 01/17] x86/mm: Rework address range check in get_user() and put_user() |
| |
On Wed, Jan 11, 2023 at 03:37:20PM +0300, Kirill A. Shutemov wrote: > The functions get_user() and put_user() check that the target address > range resides in the user space portion of the virtual address space. > In order to perform this check, the functions compare the end of the > range against TASK_SIZE_MAX. > > For kernels compiled with CONFIG_X86_5LEVEL, this process requires some > additional trickery using ALTERNATIVE, as TASK_SIZE_MAX depends on the > paging mode in use. > > Linus suggested that this check could be simplified for 64-bit kernels. > It is sufficient to check bit 63 of the address to ensure that the range > belongs to user space. Additionally, the use of branches can be avoided > by setting the target address to all ones if bit 63 is set. > > There's no need to check the end of the access range as there's huge > gap between end of userspace range and start of the kernel range. The > gap consists of canonical hole and unused ranges on both kernel and > userspace sides.
So far I can follow, however
> If an address with bit 63 set is passed down, it will trigger a #GP > exception. _ASM_EXTABLE_UA() complains about this. Replace it with > plain _ASM_EXTABLE() as it is expected behaviour now.
here I don't. The new logic basically squishes every kernel address to -1L -- a known unmapped address, but getting that address in {get,put}_user() is still a fail, right?
We used to manually branch to bad_get_user when outside TASK_SIZE_MAX, now we rely on #GP.
So why silence it?
| |