diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
index d349484..0c21a0d 100644
--- a/arch/arm64/include/asm/uaccess.h
+++ b/arch/arm64/include/asm/uaccess.h
@@ -356,22 +356,6 @@ do {
                         \
                -EFAULT;                                                \
 })

-static inline void check_obj_in_unused_stack(const void *obj,
unsigned long len)
-{
-       unsigned long stack = (unsigned long)task_stack_page(current);
-
-       if (__builtin_constant_p(len) ||
!IS_ENABLED(CONFIG_HARDENED_USERCOPY) || !len)
-               return;
-
-       /*
-        * If current_stack_pointer is on the task stack, obj must not lie
-        * between current_stack_pointer and the last stack address.
-        */
-       if ((current_stack_pointer & ~(THREAD_SIZE-1)) == stack)
-               BUG_ON(stack <= (unsigned long)obj &&
-                      (unsigned long)obj < current_stack_pointer);
-}
-
 extern unsigned long __must_check __arch_copy_from_user(void *to,
const void __user *from, unsigned long n);
 extern unsigned long __must_check __arch_copy_to_user(void __user
*to, const void *from, unsigned long n);
 extern unsigned long __must_check __copy_in_user(void __user *to,
const void __user *from, unsigned long n);
@@ -380,16 +364,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_obj_in_unused_stack(to, n);
-       check_object_size(to, n, false);
+       check_object_size(to, n, current_stack_pointer, 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_obj_in_unused_stack(from, n);
-       check_object_size(from, n, true);
+       check_object_size(from, n, current_stack_pointer, true);
        return __arch_copy_to_user(to, from, n);
 }

@@ -399,8 +381,7 @@ 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)) {
-               check_obj_in_unused_stack(to, n);
-               check_object_size(to, n, false);
+               check_object_size(to, n, current_stack_pointer, false);
                res = __arch_copy_from_user(to, from, n);
        }
        if (unlikely(res))
@@ -413,8 +394,7 @@ 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)) {
-               check_obj_in_unused_stack(from, n);
-               check_object_size(from, n, true);
+               check_object_size(from, n, current_stack_pointer, true);
                n = __arch_copy_to_user(to, from, n);
        }
        return n;
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index a38b3be..5c676bc 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -94,17 +94,17 @@ static inline enum stack_type
arch_within_stack_frames(const void * const stack,

 #ifdef CONFIG_HARDENED_USERCOPY
 extern void __check_object_size(const void *ptr, unsigned long n,
-                                       bool to_user);
+                               unsigned long sp, bool to_user);

 static __always_inline void check_object_size(const void *ptr, unsigned long n,
-                                             bool to_user)
+                                             unsigned long sp, bool to_user)
 {
        if (!__builtin_constant_p(n))
-               __check_object_size(ptr, n, to_user);
+               __check_object_size(ptr, n, sp, to_user);
 }
 #else
 static inline void check_object_size(const void *ptr, unsigned long n,
-                                    bool to_user)
+                                    unsigned long sp, bool to_user)
 { }
 #endif /* CONFIG_HARDENED_USERCOPY */

diff --git a/lib/strncpy_from_user.c b/lib/strncpy_from_user.c
index 7e35fc4..4118da4 100644
--- a/lib/strncpy_from_user.c
+++ b/lib/strncpy_from_user.c
@@ -112,7 +112,7 @@ long strncpy_from_user(char *dst, const char
__user *src, long count)
                long retval;

                kasan_check_write(dst, count);
-               check_object_size(dst, count, false);
+               check_object_size(dst, count, current_stack_pointer, false);
                user_access_begin();
                retval = do_strncpy_from_user(dst, src, count, max);
                user_access_end();
diff --git a/mm/usercopy.c b/mm/usercopy.c
index 3531ae7..3739022 100644
--- a/mm/usercopy.c
+++ b/mm/usercopy.c
@@ -29,7 +29,8 @@
  *     GOOD_STACK: fully on the stack (when can't do frame-checking)
  *     BAD_STACK: error condition (invalid stack position or bad stack frame)
  */
-static noinline int check_stack_object(const void *obj, unsigned long len)
+static noinline int check_stack_object(const void *obj, unsigned long len,
+                                      unsigned long usercopy_sp)
 {
        const void * const stack = task_stack_page(current);
        const void * const stackend = stack + THREAD_SIZE;
@@ -44,7 +45,7 @@ static noinline int check_stack_object(const void
*obj, unsigned long len)
         * the check above means at least one end is within the stack,
         * so if this check fails, the other end is outside the stack).
         */
-       if (obj < stack || stackend < obj + len)
+       if (obj < usercopy_sp || stackend < obj + len)
                return BAD_STACK;

