Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1eccfa09 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull usercopy protection from Kees Cook:
 "Tbhis implements HARDENED_USERCOPY verification of copy_to_user and
  copy_from_user bounds checking for most architectures on SLAB and
  SLUB"

* tag 'usercopy-v4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  mm: SLUB hardened usercopy support
  mm: SLAB hardened usercopy support
  s390/uaccess: Enable hardened usercopy
  sparc/uaccess: Enable hardened usercopy
  powerpc/uaccess: Enable hardened usercopy
  ia64/uaccess: Enable hardened usercopy
  arm64/uaccess: Enable hardened usercopy
  ARM: uaccess: Enable hardened usercopy
  x86/uaccess: Enable hardened usercopy
  mm: Hardened usercopy
  mm: Implement stack frame object validation
  mm: Add is_migrate_cma_page
parents 1bd4403d ed18adc1
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -461,6 +461,15 @@ config CC_STACKPROTECTOR_STRONG

endchoice

config HAVE_ARCH_WITHIN_STACK_FRAMES
	bool
	help
	  An architecture should select this if it can walk the kernel stack
	  frames to determine if an object is part of either the arguments
	  or local variables (i.e. that it excludes saved return addresses,
	  and similar) by implementing an inline arch_within_stack_frames(),
	  which is used by CONFIG_HARDENED_USERCOPY.

config HAVE_CONTEXT_TRACKING
	bool
	help
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ config ARM
	select HARDIRQS_SW_RESEND
	select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT)
	select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
	select HAVE_ARCH_HARDENED_USERCOPY
	select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
	select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU
	select HAVE_ARCH_MMAP_RND_BITS if MMU
+9 −2
Original line number Diff line number Diff line
@@ -480,7 +480,10 @@ arm_copy_from_user(void *to, const void __user *from, unsigned long n);
static inline unsigned long __must_check
__copy_from_user(void *to, const void __user *from, unsigned long n)
{
	unsigned int __ua_flags = uaccess_save_and_enable();
	unsigned int __ua_flags;

	check_object_size(to, n, false);
	__ua_flags = uaccess_save_and_enable();
	n = arm_copy_from_user(to, from, n);
	uaccess_restore(__ua_flags);
	return n;
@@ -495,11 +498,15 @@ static inline unsigned long __must_check
__copy_to_user(void __user *to, const void *from, unsigned long n)
{
#ifndef CONFIG_UACCESS_WITH_MEMCPY
	unsigned int __ua_flags = uaccess_save_and_enable();
	unsigned int __ua_flags;

	check_object_size(from, n, true);
	__ua_flags = uaccess_save_and_enable();
	n = arm_copy_to_user(to, from, n);
	uaccess_restore(__ua_flags);
	return n;
#else
	check_object_size(from, n, true);
	return arm_copy_to_user(to, from, n);
#endif
}
+1 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ config ARM64
	select HAVE_ALIGNED_STRUCT_PAGE if SLUB
	select HAVE_ARCH_AUDITSYSCALL
	select HAVE_ARCH_BITREVERSE
	select HAVE_ARCH_HARDENED_USERCOPY
	select HAVE_ARCH_HUGE_VMAP
	select HAVE_ARCH_JUMP_LABEL
	select HAVE_ARCH_KASAN if SPARSEMEM_VMEMMAP && !(ARM64_16K_PAGES && ARM64_VA_BITS_48)
+10 −5
Original line number Diff line number Diff line
@@ -265,12 +265,14 @@ extern unsigned long __must_check __clear_user(void __user *addr, unsigned long
static inline unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n)
{
	kasan_check_write(to, n);
	check_object_size(to, n, false);
	return __arch_copy_from_user(to, from, n);
}

static inline unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n)
{
	kasan_check_read(from, n);
	check_object_size(from, n, true);
	return __arch_copy_to_user(to, from, n);
}

@@ -278,9 +280,10 @@ static inline unsigned long __must_check copy_from_user(void *to, const void __u
{
	kasan_check_write(to, n);

	if (access_ok(VERIFY_READ, from, n))
	if (access_ok(VERIFY_READ, from, n)) {
		check_object_size(to, n, false);
		n = __arch_copy_from_user(to, from, n);
	else /* security hole - plug it */
	} else /* security hole - plug it */
		memset(to, 0, n);
	return n;
}
@@ -289,8 +292,10 @@ static inline unsigned long __must_check copy_to_user(void __user *to, const voi
{
	kasan_check_read(from, n);

	if (access_ok(VERIFY_WRITE, to, n))
	if (access_ok(VERIFY_WRITE, to, n)) {
		check_object_size(from, n, true);
		n = __arch_copy_to_user(to, from, n);
	}
	return n;
}

Loading