cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

testing-overview.rst (8513B)


      1.. SPDX-License-Identifier: GPL-2.0
      2
      3====================
      4Kernel Testing Guide
      5====================
      6
      7
      8There are a number of different tools for testing the Linux kernel, so knowing
      9when to use each of them can be a challenge. This document provides a rough
     10overview of their differences, and how they fit together.
     11
     12
     13Writing and Running Tests
     14=========================
     15
     16The bulk of kernel tests are written using either the kselftest or KUnit
     17frameworks. These both provide infrastructure to help make running tests and
     18groups of tests easier, as well as providing helpers to aid in writing new
     19tests.
     20
     21If you're looking to verify the behaviour of the Kernel — particularly specific
     22parts of the kernel — then you'll want to use KUnit or kselftest.
     23
     24
     25The Difference Between KUnit and kselftest
     26------------------------------------------
     27
     28KUnit (Documentation/dev-tools/kunit/index.rst) is an entirely in-kernel system
     29for "white box" testing: because test code is part of the kernel, it can access
     30internal structures and functions which aren't exposed to userspace.
     31
     32KUnit tests therefore are best written against small, self-contained parts
     33of the kernel, which can be tested in isolation. This aligns well with the
     34concept of 'unit' testing.
     35
     36For example, a KUnit test might test an individual kernel function (or even a
     37single codepath through a function, such as an error handling case), rather
     38than a feature as a whole.
     39
     40This also makes KUnit tests very fast to build and run, allowing them to be
     41run frequently as part of the development process.
     42
     43There is a KUnit test style guide which may give further pointers in
     44Documentation/dev-tools/kunit/style.rst
     45
     46
     47kselftest (Documentation/dev-tools/kselftest.rst), on the other hand, is
     48largely implemented in userspace, and tests are normal userspace scripts or
     49programs.
     50
     51This makes it easier to write more complicated tests, or tests which need to
     52manipulate the overall system state more (e.g., spawning processes, etc.).
     53However, it's not possible to call kernel functions directly from kselftest.
     54This means that only kernel functionality which is exposed to userspace somehow
     55(e.g. by a syscall, device, filesystem, etc.) can be tested with kselftest.  To
     56work around this, some tests include a companion kernel module which exposes
     57more information or functionality. If a test runs mostly or entirely within the
     58kernel, however,  KUnit may be the more appropriate tool.
     59
     60kselftest is therefore suited well to tests of whole features, as these will
     61expose an interface to userspace, which can be tested, but not implementation
     62details. This aligns well with 'system' or 'end-to-end' testing.
     63
     64For example, all new system calls should be accompanied by kselftest tests.
     65
     66Code Coverage Tools
     67===================
     68
     69The Linux Kernel supports two different code coverage measurement tools. These
     70can be used to verify that a test is executing particular functions or lines
     71of code. This is useful for determining how much of the kernel is being tested,
     72and for finding corner-cases which are not covered by the appropriate test.
     73
     74Documentation/dev-tools/gcov.rst is GCC's coverage testing tool, which can be
     75used with the kernel to get global or per-module coverage. Unlike KCOV, it
     76does not record per-task coverage. Coverage data can be read from debugfs,
     77and interpreted using the usual gcov tooling.
     78
     79Documentation/dev-tools/kcov.rst is a feature which can be built in to the
     80kernel to allow capturing coverage on a per-task level. It's therefore useful
     81for fuzzing and other situations where information about code executed during,
     82for example, a single syscall is useful.
     83
     84
     85Dynamic Analysis Tools
     86======================
     87
     88The kernel also supports a number of dynamic analysis tools, which attempt to
     89detect classes of issues when they occur in a running kernel. These typically
     90each look for a different class of bugs, such as invalid memory accesses,
     91concurrency issues such as data races, or other undefined behaviour like
     92integer overflows.
     93
     94Some of these tools are listed below:
     95
     96* kmemleak detects possible memory leaks. See
     97  Documentation/dev-tools/kmemleak.rst
     98* KASAN detects invalid memory accesses such as out-of-bounds and
     99  use-after-free errors. See Documentation/dev-tools/kasan.rst
    100* UBSAN detects behaviour that is undefined by the C standard, like integer
    101  overflows. See Documentation/dev-tools/ubsan.rst
    102* KCSAN detects data races. See Documentation/dev-tools/kcsan.rst
    103* KFENCE is a low-overhead detector of memory issues, which is much faster than
    104  KASAN and can be used in production. See Documentation/dev-tools/kfence.rst
    105* lockdep is a locking correctness validator. See
    106  Documentation/locking/lockdep-design.rst
    107* There are several other pieces of debug instrumentation in the kernel, many
    108  of which can be found in lib/Kconfig.debug
    109
    110These tools tend to test the kernel as a whole, and do not "pass" like
    111kselftest or KUnit tests. They can be combined with KUnit or kselftest by
    112running tests on a kernel with these tools enabled: you can then be sure
    113that none of these errors are occurring during the test.
    114
    115Some of these tools integrate with KUnit or kselftest and will
    116automatically fail tests if an issue is detected.
    117
    118Static Analysis Tools
    119=====================
    120
    121In addition to testing a running kernel, one can also analyze kernel source code
    122directly (**at compile time**) using **static analysis** tools. The tools
    123commonly used in the kernel allow one to inspect the whole source tree or just
    124specific files within it. They make it easier to detect and fix problems during
    125the development process.
    126
    127Sparse can help test the kernel by performing type-checking, lock checking,
    128value range checking, in addition to reporting various errors and warnings while
    129examining the code. See the Documentation/dev-tools/sparse.rst documentation
    130page for details on how to use it.
    131
    132Smatch extends Sparse and provides additional checks for programming logic
    133mistakes such as missing breaks in switch statements, unused return values on
    134error checking, forgetting to set an error code in the return of an error path,
    135etc. Smatch also has tests against more serious issues such as integer
    136overflows, null pointer dereferences, and memory leaks. See the project page at
    137http://smatch.sourceforge.net/.
    138
    139Coccinelle is another static analyzer at our disposal. Coccinelle is often used
    140to aid refactoring and collateral evolution of source code, but it can also help
    141to avoid certain bugs that occur in common code patterns. The types of tests
    142available include API tests, tests for correct usage of kernel iterators, checks
    143for the soundness of free operations, analysis of locking behavior, and further
    144tests known to help keep consistent kernel usage. See the
    145Documentation/dev-tools/coccinelle.rst documentation page for details.
    146
    147Beware, though, that static analysis tools suffer from **false positives**.
    148Errors and warns need to be evaluated carefully before attempting to fix them.
    149
    150When to use Sparse and Smatch
    151-----------------------------
    152
    153Sparse does type checking, such as verifying that annotated variables do not
    154cause endianness bugs, detecting places that use ``__user`` pointers improperly,
    155and analyzing the compatibility of symbol initializers.
    156
    157Smatch does flow analysis and, if allowed to build the function database, it
    158also does cross function analysis. Smatch tries to answer questions like where
    159is this buffer allocated? How big is it? Can this index be controlled by the
    160user? Is this variable larger than that variable?
    161
    162It's generally easier to write checks in Smatch than it is to write checks in
    163Sparse. Nevertheless, there are some overlaps between Sparse and Smatch checks.
    164
    165Strong points of Smatch and Coccinelle
    166--------------------------------------
    167
    168Coccinelle is probably the easiest for writing checks. It works before the
    169pre-processor so it's easier to check for bugs in macros using Coccinelle.
    170Coccinelle also creates patches for you, which no other tool does.
    171
    172For example, with Coccinelle you can do a mass conversion from
    173``kmalloc(x * size, GFP_KERNEL)`` to ``kmalloc_array(x, size, GFP_KERNEL)``, and
    174that's really useful. If you just created a Smatch warning and try to push the
    175work of converting on to the maintainers they would be annoyed. You'd have to
    176argue about each warning if can really overflow or not.
    177
    178Coccinelle does no analysis of variable values, which is the strong point of
    179Smatch. On the other hand, Coccinelle allows you to do simple things in a simple
    180way.