maccess.c 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. #include <linux/uaccess.h>
  3. #include <linux/kernel.h>
  4. #include <asm/vsyscall.h>
  5. #ifdef CONFIG_X86_64
  6. bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
  7. {
  8. unsigned long vaddr = (unsigned long)unsafe_src;
  9. /*
  10. * Do not allow userspace addresses. This disallows
  11. * normal userspace and the userspace guard page:
  12. */
  13. if (vaddr < TASK_SIZE_MAX + PAGE_SIZE)
  14. return false;
  15. /*
  16. * Reading from the vsyscall page may cause an unhandled fault in
  17. * certain cases. Though it is at an address above TASK_SIZE_MAX, it is
  18. * usually considered as a user space address.
  19. */
  20. if (is_vsyscall_vaddr(vaddr))
  21. return false;
  22. /*
  23. * Allow everything during early boot before 'x86_virt_bits'
  24. * is initialized. Needed for instruction decoding in early
  25. * exception handlers.
  26. */
  27. if (!boot_cpu_data.x86_virt_bits)
  28. return true;
  29. return __is_canonical_address(vaddr, boot_cpu_data.x86_virt_bits);
  30. }
  31. #else
  32. bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
  33. {
  34. return (unsigned long)unsafe_src >= TASK_SIZE_MAX;
  35. }
  36. #endif