Linux Kernel

Linux kernel #

This list includes basic checks for Linux kernel drivers and modules.

  • Check that all uses of data coming from the userspace are validated.
    • Look for the __user tag in the code. Not necessarily all userspace data is marked with the tag, but it is a good start.
    • Uses of copy_from_user(to, from, size) should be validated:
      • The length should be validated correctly.
      • There should be no uninitialized to addresses.
      • The low-level __copy_from_user function should be used with the access_ok identifier.
  • Check that uses of copy_to_user(to, from, size) are validated.
    • from memory should be initialized (including the struct’s padding).
  • Review uses of user_access_{begin,end}.
    • These calls make kernel code disable/enable SMAP. Any code between these calls must be reviewed carefully.
  • Review other userspace-to-kernel methods.
    • At least the following functions should be reviewed: get_user, strncpy_from_user, copy_struct_from_user, access_process_vm, and get_user_pages.
    • Review uses of explicitly unsafe functions such as __put_user and unsafe_put_user with extra care.
  • Check for instances in which the kernel fetches or copies memory from userspace twice instead of once, which results in TOCTOU (or double fetch) issues.
    • This often happens when pre- or post-syscall hooks are involved.
  • Review the codebase for pointer leaks.
    • For example, use of the %p format string may leak kernel addresses. The mitigation for this particular issue is to use kptr_restrict. Developers should use the %pK or %px format strings.
  • Check that file descriptors passed to userspace (with fd_install, for example) are not used by the kernel anymore.
    • Userspace can call close or dup2 on the descriptor to make it point to a different file, and the kernel would then use a different file structure than the expected one, which may lead to issues like use after free.
  • Check for uses of strlen_user and strnlen_user (which are used only in old kernels). These functions return the length including the nullbyte, which is different behavior from the userspace strlen function and may be confusing.
  • Examine uses of strncpy_from_user, as they may not null-terminate the destination string (same behavior as stdlib strncpy).
  • Check that reference counting is implemented correctly (fget/fput, sock_hold/sock_put, get_pid_task/get_task_struct/put_task_struct, {get,put}_pid, d_find_alias/dget/dput, etc.).
    • There are no double decrements (causing use-after-free conditions).
    • There are no missing increments (causing use-after-free conditions).
    • There are no double increments (causing dangling objects).
    • There are no missing decrements (causing dangling objects).
    • The correct type is used for custom refcounters ( refcount_t versus atomic_t).
    • Return values of refcount-taking functions like try_module_get are checked.
  • Check that mutex locking is implemented correctly (mutex_lock, spin_lock).
  • Check that the __ro_after_init attribute is used for init-once variables.
  • Examine dynamic allocations to ensure they are correct.
  • Check that if a global initialization function (like genl_register_family and init_module) allocates memory, the corresponding deinitialization function frees the memory.
  • For code that modifies protection of kernel memory mappings, check that any read-only pages, like syscall tables, stay read-only after the modification.
  • Check that all interfaces (procfs entries, sysfs files, device files, ioctl and netlink operations, etc.) that allow administrative operations to be performed or sensitive data to be obtained (via pointers, configuration, etc.) require root user and relevant capabilities.
    • Low-privilege users can become root (users with UID 0) in their own namespace (e.g., inside a Docker container). Missing capability checks could allow root-owned procfs files to be accessed or kernel pointers to be leaked.
  • Ensure capability checks for the correct process(es) are performed.
    • For example, there should be capability checks not only of the calling process but also of the process that created a resource. See CVE-2023-2002 for more information.
  • Check that custom filesystems (defined by the file_system_type struct) and files (defined by the file_operations struct) have the owner field set to THIS_MODULE.
  • Use kernel-specific static analysis.
This content is licensed under a Creative Commons Attribution 4.0 International license.