LCOV - code coverage report
Current view: top level - lib - usercopy.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 17 0.0 %
Date: 2023-04-06 08:38:28 Functions: 0 1 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : #include <linux/bitops.h>
       3             : #include <linux/fault-inject-usercopy.h>
       4             : #include <linux/instrumented.h>
       5             : #include <linux/uaccess.h>
       6             : #include <linux/nospec.h>
       7             : 
       8             : /* out-of-line parts */
       9             : 
      10             : #ifndef INLINE_COPY_FROM_USER
      11             : unsigned long _copy_from_user(void *to, const void __user *from, unsigned long n)
      12             : {
      13             :         unsigned long res = n;
      14             :         might_fault();
      15             :         if (!should_fail_usercopy() && likely(access_ok(from, n))) {
      16             :                 /*
      17             :                  * Ensure that bad access_ok() speculation will not
      18             :                  * lead to nasty side effects *after* the copy is
      19             :                  * finished:
      20             :                  */
      21             :                 barrier_nospec();
      22             :                 instrument_copy_from_user_before(to, from, n);
      23             :                 res = raw_copy_from_user(to, from, n);
      24             :                 instrument_copy_from_user_after(to, from, n, res);
      25             :         }
      26             :         if (unlikely(res))
      27             :                 memset(to + (n - res), 0, res);
      28             :         return res;
      29             : }
      30             : EXPORT_SYMBOL(_copy_from_user);
      31             : #endif
      32             : 
      33             : #ifndef INLINE_COPY_TO_USER
      34             : unsigned long _copy_to_user(void __user *to, const void *from, unsigned long n)
      35             : {
      36             :         might_fault();
      37             :         if (should_fail_usercopy())
      38             :                 return n;
      39             :         if (likely(access_ok(to, n))) {
      40             :                 instrument_copy_to_user(to, from, n);
      41             :                 n = raw_copy_to_user(to, from, n);
      42             :         }
      43             :         return n;
      44             : }
      45             : EXPORT_SYMBOL(_copy_to_user);
      46             : #endif
      47             : 
      48             : /**
      49             :  * check_zeroed_user: check if a userspace buffer only contains zero bytes
      50             :  * @from: Source address, in userspace.
      51             :  * @size: Size of buffer.
      52             :  *
      53             :  * This is effectively shorthand for "memchr_inv(from, 0, size) == NULL" for
      54             :  * userspace addresses (and is more efficient because we don't care where the
      55             :  * first non-zero byte is).
      56             :  *
      57             :  * Returns:
      58             :  *  * 0: There were non-zero bytes present in the buffer.
      59             :  *  * 1: The buffer was full of zero bytes.
      60             :  *  * -EFAULT: access to userspace failed.
      61             :  */
      62           0 : int check_zeroed_user(const void __user *from, size_t size)
      63             : {
      64             :         unsigned long val;
      65           0 :         uintptr_t align = (uintptr_t) from % sizeof(unsigned long);
      66             : 
      67           0 :         if (unlikely(size == 0))
      68             :                 return 1;
      69             : 
      70           0 :         from -= align;
      71           0 :         size += align;
      72             : 
      73           0 :         if (!user_read_access_begin(from, size))
      74             :                 return -EFAULT;
      75             : 
      76           0 :         unsafe_get_user(val, (unsigned long __user *) from, err_fault);
      77           0 :         if (align)
      78           0 :                 val &= ~aligned_byte_mask(align);
      79             : 
      80           0 :         while (size > sizeof(unsigned long)) {
      81           0 :                 if (unlikely(val))
      82             :                         goto done;
      83             : 
      84           0 :                 from += sizeof(unsigned long);
      85           0 :                 size -= sizeof(unsigned long);
      86             : 
      87           0 :                 unsafe_get_user(val, (unsigned long __user *) from, err_fault);
      88             :         }
      89             : 
      90           0 :         if (size < sizeof(unsigned long))
      91           0 :                 val &= aligned_byte_mask(size);
      92             : 
      93             : done:
      94             :         user_read_access_end();
      95           0 :         return (val == 0);
      96             : err_fault:
      97             :         user_read_access_end();
      98             :         return -EFAULT;
      99             : }
     100             : EXPORT_SYMBOL(check_zeroed_user);

Generated by: LCOV version 1.14