* checking before using them, but you have to surround them with the
  * user_access_begin/end() pair.
  */
-#define user_access_begin()    __uaccess_begin()
+static __must_check inline bool user_access_begin(const void __user *ptr, size_t len)
+{
+       if (unlikely(!access_ok(ptr,len)))
+               return 0;
+       __uaccess_begin();
+       return 1;
+}
+#define user_access_begin(a,b) user_access_begin(a,b)
 #define user_access_end()      __uaccess_end()
 
 #define unsafe_put_user(x, ptr, err_label)                                     \
 
                 * happened we would make the mistake of assuming that the
                 * relocations were valid.
                 */
-               user_access_begin();
+               if (!user_access_begin(urelocs, size))
+                       goto end_user;
+
                for (copied = 0; copied < nreloc; copied++)
                        unsafe_put_user(-1,
                                        &urelocs[copied].presumed_offset,
                unsigned int i;
 
                /* Copy the new buffer offsets back to the user's exec list. */
-               user_access_begin();
+               /*
+                * Note: count * sizeof(*user_exec_list) does not overflow,
+                * because we checked 'count' in check_buffer_count().
+                *
+                * And this range already got effectively checked earlier
+                * when we did the "copy_from_user()" above.
+                */
+               if (!user_access_begin(user_exec_list, count * sizeof(*user_exec_list)))
+                       goto end_user;
+
                for (i = 0; i < args->buffer_count; i++) {
                        if (!(exec2_list[i].offset & UPDATE))
                                continue;
 
        probe_kernel_read(&retval, addr, sizeof(retval))
 
 #ifndef user_access_begin
-#define user_access_begin() do { } while (0)
+#define user_access_begin(ptr,len) access_ok(ptr, len)
 #define user_access_end() do { } while (0)
 #define unsafe_get_user(x, ptr, err) do { if (unlikely(__get_user(x, ptr))) goto err; } while (0)
 #define unsafe_put_user(x, ptr, err) do { if (unlikely(__put_user(x, ptr))) goto err; } while (0)
 
        bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
        nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
 
-       if (!access_ok(umask, bitmap_size / 8))
+       if (!user_access_begin(umask, bitmap_size / 8))
                return -EFAULT;
 
-       user_access_begin();
        while (nr_compat_longs > 1) {
                compat_ulong_t l1, l2;
                unsafe_get_user(l1, umask++, Efault);
        bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
        nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
 
-       if (!access_ok(umask, bitmap_size / 8))
+       if (!user_access_begin(umask, bitmap_size / 8))
                return -EFAULT;
 
-       user_access_begin();
        while (nr_compat_longs > 1) {
                unsigned long m = *mask++;
                unsafe_put_user((compat_ulong_t)m, umask++, Efault);
 
        if (!infop)
                return err;
 
-       if (!access_ok(infop, sizeof(*infop)))
+       if (!user_access_begin(infop, sizeof(*infop)))
                return -EFAULT;
 
-       user_access_begin();
        unsafe_put_user(signo, &infop->si_signo, Efault);
        unsafe_put_user(0, &infop->si_errno, Efault);
        unsafe_put_user(info.cause, &infop->si_code, Efault);
        if (!infop)
                return err;
 
-       if (!access_ok(infop, sizeof(*infop)))
+       if (!user_access_begin(infop, sizeof(*infop)))
                return -EFAULT;
 
-       user_access_begin();
        unsafe_put_user(signo, &infop->si_signo, Efault);
        unsafe_put_user(0, &infop->si_errno, Efault);
        unsafe_put_user(info.cause, &infop->si_code, Efault);
 
 
                kasan_check_write(dst, count);
                check_object_size(dst, count, false);
-               user_access_begin();
-               retval = do_strncpy_from_user(dst, src, count, max);
-               user_access_end();
-               return retval;
+               if (user_access_begin(src, max)) {
+                       retval = do_strncpy_from_user(dst, src, count, max);
+                       user_access_end();
+                       return retval;
+               }
        }
        return -EFAULT;
 }
 
                unsigned long max = max_addr - src_addr;
                long retval;
 
-               user_access_begin();
-               retval = do_strnlen_user(str, count, max);
-               user_access_end();
-               return retval;
+               if (user_access_begin(str, max)) {
+                       retval = do_strnlen_user(str, count, max);
+                       user_access_end();
+                       return retval;
+               }
        }
        return 0;
 }