Implements HARDENED_USERCOPY verification of copy_to_user/copy_from_user
bounds checking for most architectures on SLAB and SLUB. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 Comment: Kees Cook <kees@outflux.net> iQIcBAABCgAGBQJXl9tlAAoJEIly9N/cbcAm5BoP/ikTtDp2bFw1sn92yHTnIWzl O+dcKVAeRgjfnSvPfb1JITpaM58exQSaDsPBeR0DbVzU1zDdhLcwHHiQupFh98Ka vBZthbrlL/u4NB26enEEW0iyA32BsxYBMnIu0z5ux9RbZflmQwGQ0c0rvy3dJ7/b FzB5ayVST5y/a0m6/sImeeExh78GU9rsMb1XmJRMwlJAy6miDz/F9TP0LnuW6PhG J5XC99ygNJS1pQBLACRsrZw6ImgBxXnWCok6tWPMxFfD+rJBU2//wqS+HozyMWHL iYP7+ytVo/ZVok4114X/V4Oof3a6wqgpBuYrivJ228QO+UsLYbYLo6sZ8kRK7VFm 9GgHo/8rWB1T9lBbSaa7UL5r0dVNNLjFGS42vwV+YlgUMQ1A35VRojO0jUnJSIQU Ug1IxKmylLd0nEcwD8/l3DXeQABsfL8GsoKW0OtdTZtW4RND4gzq34LK6t7hvayF kUkLg1OLNdUJwOi16M/rhugwYFZIMfoxQtjkRXKWN4RZ2QgSHnx2lhqNmRGPAXBG uy21wlzUTfLTqTpoeOyHzJwyF2qf2y4nsziBMhvmlrUvIzW1LIrYUKCNT4HR8Sh5 lC2WMGYuIqaiu+NOF3v6CgvKd9UW+mxMRyPEybH8mEgfm+FLZlWABiBjIUpSEZuB JFfuMv1zlljj/okIQRg8 =USIR -----END PGP SIGNATURE----- Merge tag 'usercopy-v4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux 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
This commit is contained in:
commit
1eccfa090e
28 changed files with 555 additions and 22 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -265,22 +265,25 @@ 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);
|
||||
return __arch_copy_from_user(to, from, 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);
|
||||
return __arch_copy_to_user(to, from, n);
|
||||
check_object_size(from, n, true);
|
||||
return __arch_copy_to_user(to, from, n);
|
||||
}
|
||||
|
||||
static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ config IA64
|
|||
select MODULES_USE_ELF_RELA
|
||||
select ARCH_USE_CMPXCHG_LOCKREF
|
||||
select HAVE_ARCH_AUDITSYSCALL
|
||||
select HAVE_ARCH_HARDENED_USERCOPY
|
||||
default y
|
||||
help
|
||||
The Itanium Processor Family is Intel's 64-bit successor to
|
||||
|
|
|
|||
|
|
@ -241,12 +241,18 @@ extern unsigned long __must_check __copy_user (void __user *to, const void __use
|
|||
static inline unsigned long
|
||||
__copy_to_user (void __user *to, const void *from, unsigned long count)
|
||||
{
|
||||
if (!__builtin_constant_p(count))
|
||||
check_object_size(from, count, true);
|
||||
|
||||
return __copy_user(to, (__force void __user *) from, count);
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
__copy_from_user (void *to, const void __user *from, unsigned long count)
|
||||
{
|
||||
if (!__builtin_constant_p(count))
|
||||
check_object_size(to, count, false);
|
||||
|
||||
return __copy_user((__force void __user *) to, from, count);
|
||||
}
|
||||
|
||||
|
|
@ -258,8 +264,11 @@ __copy_from_user (void *to, const void __user *from, unsigned long count)
|
|||
const void *__cu_from = (from); \
|
||||
long __cu_len = (n); \
|
||||
\
|
||||
if (__access_ok(__cu_to, __cu_len, get_fs())) \
|
||||
__cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len); \
|
||||
if (__access_ok(__cu_to, __cu_len, get_fs())) { \
|
||||
if (!__builtin_constant_p(n)) \
|
||||
check_object_size(__cu_from, __cu_len, true); \
|
||||
__cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len); \
|
||||
} \
|
||||
__cu_len; \
|
||||
})
|
||||
|
||||
|
|
@ -270,8 +279,11 @@ __copy_from_user (void *to, const void __user *from, unsigned long count)
|
|||
long __cu_len = (n); \
|
||||
\
|
||||
__chk_user_ptr(__cu_from); \
|
||||
if (__access_ok(__cu_from, __cu_len, get_fs())) \
|
||||
if (__access_ok(__cu_from, __cu_len, get_fs())) { \
|
||||
if (!__builtin_constant_p(n)) \
|
||||
check_object_size(__cu_to, __cu_len, false); \
|
||||
__cu_len = __copy_user((__force void __user *) __cu_to, __cu_from, __cu_len); \
|
||||
} \
|
||||
__cu_len; \
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ config PPC
|
|||
select HAVE_LIVEPATCH if HAVE_DYNAMIC_FTRACE_WITH_REGS
|
||||
select GENERIC_CPU_AUTOPROBE
|
||||
select HAVE_VIRT_CPU_ACCOUNTING
|
||||
select HAVE_ARCH_HARDENED_USERCOPY
|
||||
|
||||
config GENERIC_CSUM
|
||||
def_bool CPU_LITTLE_ENDIAN
|
||||
|
|
|
|||
|
|
@ -310,10 +310,15 @@ static inline unsigned long copy_from_user(void *to,
|
|||
{
|
||||
unsigned long over;
|
||||
|
||||
if (access_ok(VERIFY_READ, from, n))
|
||||
if (access_ok(VERIFY_READ, from, n)) {
|
||||
if (!__builtin_constant_p(n))
|
||||
check_object_size(to, n, false);
|
||||
return __copy_tofrom_user((__force void __user *)to, from, n);
|
||||
}
|
||||
if ((unsigned long)from < TASK_SIZE) {
|
||||
over = (unsigned long)from + n - TASK_SIZE;
|
||||
if (!__builtin_constant_p(n - over))
|
||||
check_object_size(to, n - over, false);
|
||||
return __copy_tofrom_user((__force void __user *)to, from,
|
||||
n - over) + over;
|
||||
}
|
||||
|
|
@ -325,10 +330,15 @@ static inline unsigned long copy_to_user(void __user *to,
|
|||
{
|
||||
unsigned long over;
|
||||
|
||||
if (access_ok(VERIFY_WRITE, to, n))
|
||||
if (access_ok(VERIFY_WRITE, to, n)) {
|
||||
if (!__builtin_constant_p(n))
|
||||
check_object_size(from, n, true);
|
||||
return __copy_tofrom_user(to, (__force void __user *)from, n);
|
||||
}
|
||||
if ((unsigned long)to < TASK_SIZE) {
|
||||
over = (unsigned long)to + n - TASK_SIZE;
|
||||
if (!__builtin_constant_p(n))
|
||||
check_object_size(from, n - over, true);
|
||||
return __copy_tofrom_user(to, (__force void __user *)from,
|
||||
n - over) + over;
|
||||
}
|
||||
|
|
@ -372,6 +382,10 @@ static inline unsigned long __copy_from_user_inatomic(void *to,
|
|||
if (ret == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!__builtin_constant_p(n))
|
||||
check_object_size(to, n, false);
|
||||
|
||||
return __copy_tofrom_user((__force void __user *)to, from, n);
|
||||
}
|
||||
|
||||
|
|
@ -398,6 +412,9 @@ static inline unsigned long __copy_to_user_inatomic(void __user *to,
|
|||
if (ret == 0)
|
||||
return 0;
|
||||
}
|
||||
if (!__builtin_constant_p(n))
|
||||
check_object_size(from, n, true);
|
||||
|
||||
return __copy_tofrom_user(to, (__force const void __user *)from, n);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ config S390
|
|||
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
|
||||
select HAVE_ARCH_AUDITSYSCALL
|
||||
select HAVE_ARCH_EARLY_PFN_TO_NID
|
||||
select HAVE_ARCH_HARDENED_USERCOPY
|
||||
select HAVE_ARCH_JUMP_LABEL
|
||||
select CPU_NO_EFFICIENT_FFS if !HAVE_MARCH_Z9_109_FEATURES
|
||||
select HAVE_ARCH_SECCOMP_FILTER
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ static inline unsigned long copy_from_user_mvcp(void *x, const void __user *ptr,
|
|||
|
||||
unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n)
|
||||
{
|
||||
check_object_size(to, n, false);
|
||||
if (static_branch_likely(&have_mvcos))
|
||||
return copy_from_user_mvcos(to, from, n);
|
||||
return copy_from_user_mvcp(to, from, n);
|
||||
|
|
@ -177,6 +178,7 @@ static inline unsigned long copy_to_user_mvcs(void __user *ptr, const void *x,
|
|||
|
||||
unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n)
|
||||
{
|
||||
check_object_size(from, n, true);
|
||||
if (static_branch_likely(&have_mvcos))
|
||||
return copy_to_user_mvcos(to, from, n);
|
||||
return copy_to_user_mvcs(to, from, n);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ config SPARC
|
|||
select OLD_SIGSUSPEND
|
||||
select ARCH_HAS_SG_CHAIN
|
||||
select CPU_NO_EFFICIENT_FFS
|
||||
select HAVE_ARCH_HARDENED_USERCOPY
|
||||
|
||||
config SPARC32
|
||||
def_bool !64BIT
|
||||
|
|
|
|||
|
|
@ -248,22 +248,28 @@ unsigned long __copy_user(void __user *to, const void __user *from, unsigned lon
|
|||
|
||||
static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
|
||||
{
|
||||
if (n && __access_ok((unsigned long) to, n))
|
||||
if (n && __access_ok((unsigned long) to, n)) {
|
||||
if (!__builtin_constant_p(n))
|
||||
check_object_size(from, n, true);
|
||||
return __copy_user(to, (__force void __user *) from, n);
|
||||
else
|
||||
} else
|
||||
return n;
|
||||
}
|
||||
|
||||
static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n)
|
||||
{
|
||||
if (!__builtin_constant_p(n))
|
||||
check_object_size(from, n, true);
|
||||
return __copy_user(to, (__force void __user *) from, n);
|
||||
}
|
||||
|
||||
static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
|
||||
{
|
||||
if (n && __access_ok((unsigned long) from, n))
|
||||
if (n && __access_ok((unsigned long) from, n)) {
|
||||
if (!__builtin_constant_p(n))
|
||||
check_object_size(to, n, false);
|
||||
return __copy_user((__force void __user *) to, from, n);
|
||||
else
|
||||
} else
|
||||
return n;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -210,8 +210,12 @@ unsigned long copy_from_user_fixup(void *to, const void __user *from,
|
|||
static inline unsigned long __must_check
|
||||
copy_from_user(void *to, const void __user *from, unsigned long size)
|
||||
{
|
||||
unsigned long ret = ___copy_from_user(to, from, size);
|
||||
unsigned long ret;
|
||||
|
||||
if (!__builtin_constant_p(size))
|
||||
check_object_size(to, size, false);
|
||||
|
||||
ret = ___copy_from_user(to, from, size);
|
||||
if (unlikely(ret))
|
||||
ret = copy_from_user_fixup(to, from, size);
|
||||
|
||||
|
|
@ -227,8 +231,11 @@ unsigned long copy_to_user_fixup(void __user *to, const void *from,
|
|||
static inline unsigned long __must_check
|
||||
copy_to_user(void __user *to, const void *from, unsigned long size)
|
||||
{
|
||||
unsigned long ret = ___copy_to_user(to, from, size);
|
||||
unsigned long ret;
|
||||
|
||||
if (!__builtin_constant_p(size))
|
||||
check_object_size(from, size, true);
|
||||
ret = ___copy_to_user(to, from, size);
|
||||
if (unlikely(ret))
|
||||
ret = copy_to_user_fixup(to, from, size);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ config X86
|
|||
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
|
||||
select HAVE_AOUT if X86_32
|
||||
select HAVE_ARCH_AUDITSYSCALL
|
||||
select HAVE_ARCH_HARDENED_USERCOPY
|
||||
select HAVE_ARCH_HUGE_VMAP if X86_64 || X86_PAE
|
||||
select HAVE_ARCH_JUMP_LABEL
|
||||
select HAVE_ARCH_KASAN if X86_64 && SPARSEMEM_VMEMMAP
|
||||
|
|
@ -91,6 +92,7 @@ config X86
|
|||
select HAVE_ARCH_SOFT_DIRTY if X86_64
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select HAVE_ARCH_TRANSPARENT_HUGEPAGE
|
||||
select HAVE_ARCH_WITHIN_STACK_FRAMES
|
||||
select HAVE_EBPF_JIT if X86_64
|
||||
select HAVE_CC_STACKPROTECTOR
|
||||
select HAVE_CMPXCHG_DOUBLE
|
||||
|
|
|
|||
|
|
@ -176,6 +176,50 @@ static inline unsigned long current_stack_pointer(void)
|
|||
return sp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Walks up the stack frames to make sure that the specified object is
|
||||
* entirely contained by a single stack frame.
|
||||
*
|
||||
* Returns:
|
||||
* 1 if within a frame
|
||||
* -1 if placed across a frame boundary (or outside stack)
|
||||
* 0 unable to determine (no frame pointers, etc)
|
||||
*/
|
||||
static inline int arch_within_stack_frames(const void * const stack,
|
||||
const void * const stackend,
|
||||
const void *obj, unsigned long len)
|
||||
{
|
||||
#if defined(CONFIG_FRAME_POINTER)
|
||||
const void *frame = NULL;
|
||||
const void *oldframe;
|
||||
|
||||
oldframe = __builtin_frame_address(1);
|
||||
if (oldframe)
|
||||
frame = __builtin_frame_address(2);
|
||||
/*
|
||||
* low ----------------------------------------------> high
|
||||
* [saved bp][saved ip][args][local vars][saved bp][saved ip]
|
||||
* ^----------------^
|
||||
* allow copies only within here
|
||||
*/
|
||||
while (stack <= frame && frame < stackend) {
|
||||
/*
|
||||
* If obj + len extends past the last frame, this
|
||||
* check won't pass and the next frame will be 0,
|
||||
* causing us to bail out and correctly report
|
||||
* the copy as invalid.
|
||||
*/
|
||||
if (obj + len <= frame)
|
||||
return obj >= oldframe + 2 * sizeof(void *) ? 1 : -1;
|
||||
oldframe = frame;
|
||||
frame = *(const void * const *)frame;
|
||||
}
|
||||
return -1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* !__ASSEMBLY__ */
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
|
|
|
|||
|
|
@ -761,9 +761,10 @@ copy_from_user(void *to, const void __user *from, unsigned long n)
|
|||
* case, and do only runtime checking for non-constant sizes.
|
||||
*/
|
||||
|
||||
if (likely(sz < 0 || sz >= n))
|
||||
if (likely(sz < 0 || sz >= n)) {
|
||||
check_object_size(to, n, false);
|
||||
n = _copy_from_user(to, from, n);
|
||||
else if(__builtin_constant_p(n))
|
||||
} else if (__builtin_constant_p(n))
|
||||
copy_from_user_overflow();
|
||||
else
|
||||
__copy_from_user_overflow(sz, n);
|
||||
|
|
@ -781,9 +782,10 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
|
|||
might_fault();
|
||||
|
||||
/* See the comment in copy_from_user() above. */
|
||||
if (likely(sz < 0 || sz >= n))
|
||||
if (likely(sz < 0 || sz >= n)) {
|
||||
check_object_size(from, n, true);
|
||||
n = _copy_to_user(to, from, n);
|
||||
else if(__builtin_constant_p(n))
|
||||
} else if (__builtin_constant_p(n))
|
||||
copy_to_user_overflow();
|
||||
else
|
||||
__copy_to_user_overflow(sz, n);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ unsigned long __must_check __copy_from_user_ll_nocache_nozero
|
|||
static __always_inline unsigned long __must_check
|
||||
__copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
|
||||
{
|
||||
check_object_size(from, n, true);
|
||||
return __copy_to_user_ll(to, from, n);
|
||||
}
|
||||
|
||||
|
|
@ -95,6 +96,7 @@ static __always_inline unsigned long
|
|||
__copy_from_user(void *to, const void __user *from, unsigned long n)
|
||||
{
|
||||
might_fault();
|
||||
check_object_size(to, n, false);
|
||||
if (__builtin_constant_p(n)) {
|
||||
unsigned long ret;
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ int __copy_from_user_nocheck(void *dst, const void __user *src, unsigned size)
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
check_object_size(dst, size, false);
|
||||
if (!__builtin_constant_p(size))
|
||||
return copy_user_generic(dst, (__force void *)src, size);
|
||||
switch (size) {
|
||||
|
|
@ -119,6 +120,7 @@ int __copy_to_user_nocheck(void __user *dst, const void *src, unsigned size)
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
check_object_size(src, size, true);
|
||||
if (!__builtin_constant_p(size))
|
||||
return copy_user_generic((__force void *)dst, src, size);
|
||||
switch (size) {
|
||||
|
|
|
|||
|
|
@ -68,8 +68,10 @@ extern char * const migratetype_names[MIGRATE_TYPES];
|
|||
|
||||
#ifdef CONFIG_CMA
|
||||
# define is_migrate_cma(migratetype) unlikely((migratetype) == MIGRATE_CMA)
|
||||
# define is_migrate_cma_page(_page) (get_pageblock_migratetype(_page) == MIGRATE_CMA)
|
||||
#else
|
||||
# define is_migrate_cma(migratetype) false
|
||||
# define is_migrate_cma_page(_page) false
|
||||
#endif
|
||||
|
||||
#define for_each_migratetype_order(order, type) \
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue