diff options
Diffstat (limited to 'lib/usercopy.c')
-rw-r--r-- | lib/usercopy.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/lib/usercopy.c b/lib/usercopy.c index cbb4d9ec00f2..1505a52f23a0 100644 --- a/lib/usercopy.c +++ b/lib/usercopy.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 -#include <linux/uaccess.h> #include <linux/bitops.h> +#include <linux/fault-inject-usercopy.h> +#include <linux/instrumented.h> +#include <linux/uaccess.h> /* out-of-line parts */ @@ -9,9 +11,10 @@ unsigned long _copy_from_user(void *to, const void __user *from, unsigned long n { unsigned long res = n; might_fault(); - if (likely(access_ok(from, n))) { - kasan_check_write(to, n); + if (!should_fail_usercopy() && likely(access_ok(from, n))) { + instrument_copy_from_user_before(to, from, n); res = raw_copy_from_user(to, from, n); + instrument_copy_from_user_after(to, from, n, res); } if (unlikely(res)) memset(to + (n - res), 0, res); @@ -24,8 +27,10 @@ EXPORT_SYMBOL(_copy_from_user); unsigned long _copy_to_user(void __user *to, const void *from, unsigned long n) { might_fault(); + if (should_fail_usercopy()) + return n; if (likely(access_ok(to, n))) { - kasan_check_read(from, n); + instrument_copy_to_user(to, from, n); n = raw_copy_to_user(to, from, n); } return n; @@ -58,7 +63,7 @@ int check_zeroed_user(const void __user *from, size_t size) from -= align; size += align; - if (!user_access_begin(from, size)) + if (!user_read_access_begin(from, size)) return -EFAULT; unsafe_get_user(val, (unsigned long __user *) from, err_fault); @@ -79,10 +84,10 @@ int check_zeroed_user(const void __user *from, size_t size) val &= aligned_byte_mask(size); done: - user_access_end(); + user_read_access_end(); return (val == 0); err_fault: - user_access_end(); + user_read_access_end(); return -EFAULT; } EXPORT_SYMBOL(check_zeroed_user); |