Merge tag 'riscv-for-linus-5.10-mw1' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / include / linux / uaccess.h
index d0e43761c708d82ce05c992d34dc35c744775443..c7c6e8b8344d49871fd65524a30b5e1e1d02cbf6 100644 (file)
@@ -2,7 +2,9 @@
 #ifndef __LINUX_UACCESS_H__
 #define __LINUX_UACCESS_H__
 
+#include <linux/fault-inject-usercopy.h>
 #include <linux/instrumented.h>
+#include <linux/minmax.h>
 #include <linux/sched.h>
 #include <linux/thread_info.h>
 
@@ -105,6 +107,8 @@ static __always_inline __must_check unsigned long
 __copy_from_user(void *to, const void __user *from, unsigned long n)
 {
        might_fault();
+       if (should_fail_usercopy())
+               return n;
        instrument_copy_from_user(to, from, n);
        check_object_size(to, n, false);
        return raw_copy_from_user(to, from, n);
@@ -126,6 +130,8 @@ __copy_from_user(void *to, const void __user *from, unsigned long n)
 static __always_inline __must_check unsigned long
 __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
 {
+       if (should_fail_usercopy())
+               return n;
        instrument_copy_to_user(to, from, n);
        check_object_size(from, n, true);
        return raw_copy_to_user(to, from, n);
@@ -135,6 +141,8 @@ static __always_inline __must_check unsigned long
 __copy_to_user(void __user *to, const void *from, unsigned long n)
 {
        might_fault();
+       if (should_fail_usercopy())
+               return n;
        instrument_copy_to_user(to, from, n);
        check_object_size(from, n, true);
        return raw_copy_to_user(to, from, n);
@@ -146,7 +154,7 @@ _copy_from_user(void *to, const void __user *from, unsigned long n)
 {
        unsigned long res = n;
        might_fault();
-       if (likely(access_ok(from, n))) {
+       if (!should_fail_usercopy() && likely(access_ok(from, n))) {
                instrument_copy_from_user(to, from, n);
                res = raw_copy_from_user(to, from, n);
        }
@@ -164,6 +172,8 @@ static inline __must_check unsigned long
 _copy_to_user(void __user *to, const void *from, unsigned long n)
 {
        might_fault();
+       if (should_fail_usercopy())
+               return n;
        if (access_ok(to, n)) {
                instrument_copy_to_user(to, from, n);
                n = raw_copy_to_user(to, from, n);
@@ -201,6 +211,19 @@ copy_in_user(void __user *to, const void __user *from, unsigned long n)
 }
 #endif
 
+#ifndef copy_mc_to_kernel
+/*
+ * Without arch opt-in this generic copy_mc_to_kernel() will not handle
+ * #MC (or arch equivalent) during source read.
+ */
+static inline unsigned long __must_check
+copy_mc_to_kernel(void *dst, const void *src, size_t cnt)
+{
+       memcpy(dst, src, cnt);
+       return 0;
+}
+#endif
+
 static __always_inline void pagefault_disabled_inc(void)
 {
        current->pagefault_disabled++;