linux/mm/maccess.c
<<
>>
Prefs
   1/*
   2 * Access kernel memory without faulting.
   3 */
   4#include <linux/export.h>
   5#include <linux/mm.h>
   6#include <linux/uaccess.h>
   7
   8/**
   9 * probe_kernel_read(): safely attempt to read from a location
  10 * @dst: pointer to the buffer that shall take the data
  11 * @src: address to read from
  12 * @size: size of the data chunk
  13 *
  14 * Safely read from address @src to the buffer at @dst.  If a kernel fault
  15 * happens, handle that and return -EFAULT.
  16 */
  17
  18long __weak probe_kernel_read(void *dst, const void *src, size_t size)
  19    __attribute__((alias("__probe_kernel_read")));
  20
  21long __probe_kernel_read(void *dst, const void *src, size_t size)
  22{
  23        long ret;
  24        mm_segment_t old_fs = get_fs();
  25
  26        set_fs(KERNEL_DS);
  27        pagefault_disable();
  28        ret = __copy_from_user_inatomic(dst,
  29                        (__force const void __user *)src, size);
  30        pagefault_enable();
  31        set_fs(old_fs);
  32
  33        return ret ? -EFAULT : 0;
  34}
  35EXPORT_SYMBOL_GPL(probe_kernel_read);
  36
  37/**
  38 * probe_kernel_write(): safely attempt to write to a location
  39 * @dst: address to write to
  40 * @src: pointer to the data that shall be written
  41 * @size: size of the data chunk
  42 *
  43 * Safely write to address @dst from the buffer at @src.  If a kernel fault
  44 * happens, handle that and return -EFAULT.
  45 */
  46long __weak probe_kernel_write(void *dst, const void *src, size_t size)
  47    __attribute__((alias("__probe_kernel_write")));
  48
  49long __probe_kernel_write(void *dst, const void *src, size_t size)
  50{
  51        long ret;
  52        mm_segment_t old_fs = get_fs();
  53
  54        set_fs(KERNEL_DS);
  55        pagefault_disable();
  56        ret = __copy_to_user_inatomic((__force void __user *)dst, src, size);
  57        pagefault_enable();
  58        set_fs(old_fs);
  59
  60        return ret ? -EFAULT : 0;
  61}
  62EXPORT_SYMBOL_GPL(probe_kernel_write);
  63