LCOV - code coverage report
Current view: top level - lib - usercopy.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 35 38 92.1 %
Date: 2021-04-22 12:43:58 Functions: 3 3 100.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             : 
       7             : /* out-of-line parts */
       8             : 
       9             : #ifndef INLINE_COPY_FROM_USER
      10      178636 : unsigned long _copy_from_user(void *to, const void __user *from, unsigned long n)
      11             : {
      12      178636 :         unsigned long res = n;
      13      178636 :         might_fault();
      14      357268 :         if (!should_fail_usercopy() && likely(access_ok(from, n))) {
      15      178634 :                 instrument_copy_from_user(to, from, n);
      16      178633 :                 res = raw_copy_from_user(to, from, n);
      17             :         }
      18      178637 :         if (unlikely(res))
      19           1 :                 memset(to + (n - res), 0, res);
      20      178637 :         return res;
      21             : }
      22             : EXPORT_SYMBOL(_copy_from_user);
      23             : #endif
      24             : 
      25             : #ifndef INLINE_COPY_TO_USER
      26       72207 : unsigned long _copy_to_user(void __user *to, const void *from, unsigned long n)
      27             : {
      28       72207 :         might_fault();
      29       72217 :         if (should_fail_usercopy())
      30             :                 return n;
      31      144434 :         if (likely(access_ok(to, n))) {
      32       72217 :                 instrument_copy_to_user(to, from, n);
      33       72220 :                 n = raw_copy_to_user(to, from, n);
      34             :         }
      35       72206 :         return n;
      36             : }
      37             : EXPORT_SYMBOL(_copy_to_user);
      38             : #endif
      39             : 
      40             : /**
      41             :  * check_zeroed_user: check if a userspace buffer only contains zero bytes
      42             :  * @from: Source address, in userspace.
      43             :  * @size: Size of buffer.
      44             :  *
      45             :  * This is effectively shorthand for "memchr_inv(from, 0, size) == NULL" for
      46             :  * userspace addresses (and is more efficient because we don't care where the
      47             :  * first non-zero byte is).
      48             :  *
      49             :  * Returns:
      50             :  *  * 0: There were non-zero bytes present in the buffer.
      51             :  *  * 1: The buffer was full of zero bytes.
      52             :  *  * -EFAULT: access to userspace failed.
      53             :  */
      54           2 : int check_zeroed_user(const void __user *from, size_t size)
      55             : {
      56           2 :         unsigned long val;
      57           2 :         uintptr_t align = (uintptr_t) from % sizeof(unsigned long);
      58             : 
      59           2 :         if (unlikely(size == 0))
      60             :                 return 1;
      61             : 
      62           2 :         from -= align;
      63           2 :         size += align;
      64             : 
      65           2 :         if (!user_read_access_begin(from, size))
      66             :                 return -EFAULT;
      67             : 
      68           2 :         unsafe_get_user(val, (unsigned long __user *) from, err_fault);
      69           2 :         if (align)
      70           0 :                 val &= ~aligned_byte_mask(align);
      71             : 
      72        1022 :         while (size > sizeof(unsigned long)) {
      73        1020 :                 if (unlikely(val))
      74           0 :                         goto done;
      75             : 
      76        1020 :                 from += sizeof(unsigned long);
      77        1020 :                 size -= sizeof(unsigned long);
      78             : 
      79        1022 :                 unsafe_get_user(val, (unsigned long __user *) from, err_fault);
      80             :         }
      81             : 
      82           2 :         if (size < sizeof(unsigned long))
      83           0 :                 val &= aligned_byte_mask(size);
      84             : 
      85           2 : done:
      86           2 :         user_read_access_end();
      87           2 :         return (val == 0);
      88           2 : err_fault:
      89             :         user_read_access_end();
      90             :         return -EFAULT;
      91             : }
      92             : EXPORT_SYMBOL(check_zeroed_user);

Generated by: LCOV version 1.14