blob: d0022c869dd2084d8e9dc8c53215eeab841ea914 [file] [log] [blame]
<!--
Documentation/_templates/layout.html
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership. The
ASF licenses this file to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
-->
<!DOCTYPE html>
<html class="writer-html5" lang="en">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>The Kernel Address Sanitizer (KASAN) &mdash; NuttX latest documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/css/theme.css" />
<link rel="stylesheet" type="text/css" href="../_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="../_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css" />
<link rel="stylesheet" type="text/css" href="../_static/custom.css" />
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<script src="../_static/jquery.js"></script>
<script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/sphinx_highlight.js"></script>
<script src="../_static/clipboard.min.js"></script>
<script src="../_static/copybutton.js"></script>
<script src="../_static/design-tabs.js"></script>
<script src="../_static/js/theme.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Core Dump" href="coredump.html" />
<link rel="prev" title="Task Trace Internals" href="tasktraceinternal.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="../index.html" class="icon icon-home"> NuttX
</a>
<!-- this version selector is quite ugly, should be probably replaced by something
more modern -->
<div class="version-selector">
<select onchange="javascript:location.href = this.value;">
<option value="../../latest" selected="selected">latest</option>
<option value="../../10.0.0" >10.0.0</option>
<option value="../../10.0.1" >10.0.1</option>
<option value="../../10.1.0" >10.1.0</option>
<option value="../../10.2.0" >10.2.0</option>
<option value="../../10.3.0" >10.3.0</option>
<option value="../../11.0.0" >11.0.0</option>
<option value="../../12.0.0" >12.0.0</option>
<option value="../../12.1.0" >12.1.0</option>
<option value="../../12.2.0" >12.2.0</option>
<option value="../../12.2.1" >12.2.1</option>
<option value="../../12.3.0" >12.3.0</option>
<option value="../../12.4.0" >12.4.0</option>
<option value="../../12.5.0" >12.5.0</option>
<option value="../../12.5.1" >12.5.1</option>
<option value="../../12.6.0" >12.6.0</option>
<option value="../../12.7.0" >12.7.0</option>
<option value="../../12.8.0" >12.8.0</option>
<option value="../../12.9.0" >12.9.0</option>
<option value="../../12.10.0" >12.10.0</option>
<option value="../../12.11.0" >12.11.0</option>
</select>
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<p class="caption" role="heading"><span class="caption-text">Table of Contents</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../index.html">Home</a></li>
<li class="toctree-l1"><a class="reference internal" href="../introduction/index.html">Introduction</a></li>
<li class="toctree-l1"><a class="reference internal" href="../quickstart/index.html">Getting Started</a></li>
<li class="toctree-l1"><a class="reference internal" href="../contributing/index.html">Contributing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../introduction/inviolables.html">The Inviolable Principles of NuttX</a></li>
<li class="toctree-l1"><a class="reference internal" href="../platforms/index.html">Supported Platforms</a></li>
<li class="toctree-l1"><a class="reference internal" href="../components/index.html">OS Components</a></li>
<li class="toctree-l1"><a class="reference internal" href="../applications/index.html">Applications</a></li>
<li class="toctree-l1"><a class="reference internal" href="../implementation/index.html">Implementation Details</a></li>
<li class="toctree-l1"><a class="reference internal" href="../reference/index.html">API Reference</a></li>
<li class="toctree-l1"><a class="reference internal" href="../faq/index.html">FAQ</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Debugging</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="gdbwithpython.html">GDB with Python</a></li>
<li class="toctree-l2"><a class="reference internal" href="qemugdb.html">How to debug NuttX using QEMU and GDB</a></li>
<li class="toctree-l2"><a class="reference internal" href="gdbserver.html">gdbserver</a></li>
<li class="toctree-l2"><a class="reference internal" href="debugging_elf_loadable_modules.html">Debugging ELF Loadable Modules</a></li>
<li class="toctree-l2"><a class="reference internal" href="tasktrace.html">Task Trace</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">The Kernel Address Sanitizer (KASAN)</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#overview">Overview</a></li>
<li class="toctree-l3"><a class="reference internal" href="#support">Support</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#architectures">Architectures</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#usage">Usage</a></li>
<li class="toctree-l3"><a class="reference internal" href="#implementation-details">Implementation details</a></li>
<li class="toctree-l3"><a class="reference internal" href="#for-developers">For developers</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#ignoring-accesses">Ignoring accesses</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="coredump.html">Core Dump</a></li>
<li class="toctree-l2"><a class="reference internal" href="coresight.html">Coresight - HW Assisted Tracing on ARM</a></li>
<li class="toctree-l2"><a class="reference internal" href="stackcheck.html">Stack Overflow Check</a></li>
<li class="toctree-l2"><a class="reference internal" href="stackrecord.html">Run time stack statistics</a></li>
<li class="toctree-l2"><a class="reference internal" href="disabling_stackdumpdebug.html">Disabling the Stack Dump During Debugging</a></li>
<li class="toctree-l2"><a class="reference internal" href="debuggingflash_nuttxonarm.html">Debugging / flashing NuttX on ARM with hardware debugger (JTAG/SWD)</a></li>
<li class="toctree-l2"><a class="reference internal" href="cortexmhardfaults.html">Analyzing Cortex-M Hardfaults</a></li>
<li class="toctree-l2"><a class="reference internal" href="mte.html">ATM64 MTE extension</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../guides/index.html">Guides</a></li>
<li class="toctree-l1"><a class="reference internal" href="../glossary.html">Glossary</a></li>
<li class="toctree-l1"><a class="reference internal" href="../logos/index.html">NuttX Logos</a></li>
<li class="toctree-l1"><a class="reference internal" href="../_tags/tagsindex.html">Tags</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">NuttX</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item"><a href="index.html">Debugging</a></li>
<li class="breadcrumb-item active">The Kernel Address Sanitizer (KASAN)</li>
<li class="wy-breadcrumbs-aside">
<a href="https://github.com/apache/nuttx/blob/master/Documentation/debugging/kasan.rst" class="fa fa-github"> Edit on GitHub</a>
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="the-kernel-address-sanitizer-kasan">
<h1>The Kernel Address Sanitizer (KASAN)<a class="headerlink" href="#the-kernel-address-sanitizer-kasan" title="Permalink to this heading"></a></h1>
<section id="overview">
<h2>Overview<a class="headerlink" href="#overview" title="Permalink to this heading"></a></h2>
<p>Kernel Address Sanitizer (KASAN) is a dynamic memory safety error detector
designed to find out-of-bounds and use-after-free bugs.</p>
<p>The current version of NuttX has two modes:</p>
<ol class="arabic simple">
<li><p>Generic KASAN</p></li>
<li><p>Software Tag-Based KASAN</p></li>
</ol>
<p>Generic KASAN, enabled with CONFIG_MM_KASAN_GENERIC, is the mode intended for
debugging, similar to linux user level ASan. This mode is supported on many CPU
architectures, but it has significant performance and memory overheads.
The current NuttX Generic KASAN can support memory out of bounds detection
allocated by the default NuttX heap allocator,which depends on CONFIG_MM_DEFAULT_MANAGER
or CONFIG_MM_TLSF_MANAGER, and detection of out of bounds with global variables.</p>
<p>Software Tag-Based KASAN or SW_TAGS KASAN, enabled with CONFIG_MM_KASAN_SW_TAGS,
can be used for both debugging, This mode is only supported for arm64,
but its moderate memory overhead allows using it for testing on
memory-restricted devices with real workloads.</p>
</section>
<section id="support">
<h2>Support<a class="headerlink" href="#support" title="Permalink to this heading"></a></h2>
<section id="architectures">
<h3>Architectures<a class="headerlink" href="#architectures" title="Permalink to this heading"></a></h3>
<p>Generic KASAN is supported on x86_64, arm, arm64, riscv, xtensa and so on.</p>
<p>Software Tag-Based KASAN modes are supported only on arm64.</p>
</section>
</section>
<section id="usage">
<h2>Usage<a class="headerlink" href="#usage" title="Permalink to this heading"></a></h2>
<p>To enable Generic KASAN, configure the kernel with:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>CONFIG_MM_KASAN=y
CONFIG_MM_KASAN_INSTRUMENT_ALL=y
CONFIG_MM_KASAN_GENERIC=y
</pre></div>
</div>
<p>If you want to enable global variable out of bounds detection,
you can add configurations based on the above:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>CONFIG_MM_KASAN_GLOBAL=y
</pre></div>
</div>
<p>To enable Software Tag-Based KASAN, configure the kernel with:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>CONFIG_MM_KASAN=y
CONFIG_MM_KASAN_INSTRUMENT_ALL=y
CONFIG_MM_KASAN_SW_TAGS=y
</pre></div>
</div>
</section>
<section id="implementation-details">
<h2>Implementation details<a class="headerlink" href="#implementation-details" title="Permalink to this heading"></a></h2>
<p>Generic KASAN:</p>
<p>Compile with param -fsanitize=kernel-address,
Compile-time instrumentation is used to insert memory access checks. Compiler
inserts function calls (<code class="docutils literal notranslate"><span class="pre">__asan_load*(addr)</span></code>, <code class="docutils literal notranslate"><span class="pre">__asan_store*(addr)</span></code>) before
each memory access of size 1, 2, 4, 8, or 16. These functions check whether
memory accesses are valid or not by checking corresponding shadow memory.</p>
<p>It is slightly different from Linux.
On the one hand, in terms of the source of the shadow area;
NuttX’s shadow area comes from the end of each heap. During heap initialization,
it is offset and a kasan region is shaped at the end.
Regions between multiple heaps are concatenated using a linked list.</p>
<p>Secondly, in order to save more memory consumption,
the implementation of NuttX adopts a bitmap detection method;
For example, in the case of a 32-bit machine,
if the NuttX heap allocator allocates four bytes of memory to it,
the kasan module will allocate a shadow area of one bit per unit of
memory group on a four byte basis. If the shadow area is 0,
the memory group can be accessed, otherwise 1 is inaccessible</p>
<p>Thirdly, the implementation of global variable out of bounds detection
for this NuttX is also different from Linux.
Due to the particularity of the shadow region, NuttX needs to construct kasan regions
separately for the data and bss segments where the global variable is located.
Before compiling, add the compile option ‘–param asan-globals=1’.
In this way, the compiler will store all global variable information in this special sections,
‘.data..LASAN0’, These two segments store information about all global variables
and can be parsed using the following structure:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>struct kasan_global {
const void *beg; /* Address of the beginning of the global variable. */
size_t size; /* Size of the global variable. */
size_t size_with_redzone; /* Size of the variable + size of the redzone. 32 bytes aligned. */
const void *name;
const void *module_name; /* Name of the module where the global variable is declared. */
unsigned long has_dynamic_init; /* This is needed for C++. */
/* It will point to a location that stores the file row,
* column, and file name information of each global variable */
struct kasan_source_location *location;
char *odr_indicator;
};
</pre></div>
</div>
<p>In order to reduce the amount of data generated by the compiler occupying the already precious flash space.
NuttX’s approach is to use multiple links to extract the global variable information in elf through scripts,
construct the region and shadow of the global variables according to the rules of kasan region,
form an array, and finally link it to the program. The program concatenates the array to kasan’s region linked list.</p>
<p>The data generated by the compiler will be placed in a non-existent memory block.
After the compilation is completed, this segment will be deleted
and will not be copied to the bin file of the final burned board.</p>
<p>Software Tag-Based KASAN:</p>
<p>Software Tag-Based KASAN uses a software memory tagging approach to checking
access validity. It is currently only implemented for the arm64 architecture.</p>
<p>Software Tag-Based KASAN uses the Top Byte Ignore (TBI) feature of arm64 CPUs
to store a pointer tag in the top byte of kernel pointers. It uses shadow memory
to store memory tags associated with each heap allocated memory cell (therefore, it
dedicates 1/8 th of the kernel memory for shadow memory).</p>
<p>On each memory allocation, Software Tag-Based KASAN generates a random tag, tags
the allocated memory with this tag, and embeds the same tag into the returned
pointer.</p>
<p>Software Tag-Based KASAN uses compile-time instrumentation to insert checks
before each memory access. These checks make sure that the tag of the memory
that is being accessed is equal to the tag of the pointer that is used to access
this memory. In case of a tag mismatch, Software Tag-Based KASAN prints a bug
report.</p>
</section>
<section id="for-developers">
<h2>For developers<a class="headerlink" href="#for-developers" title="Permalink to this heading"></a></h2>
<section id="ignoring-accesses">
<h3>Ignoring accesses<a class="headerlink" href="#ignoring-accesses" title="Permalink to this heading"></a></h3>
<p>If you want the module you are writing to not be inserted by the compiler,
you can add the option ‘CFLAGS += -fno-sanitize=kernel-address’ to a single module.
If it is a file, you can write it this way,
special_file.o: CFLAGS = -fno-sanitize=kernel-address</p>
</section>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="tasktraceinternal.html" class="btn btn-neutral float-left" title="Task Trace Internals" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="coredump.html" class="btn btn-neutral float-right" title="Core Dump" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2023, The Apache Software Foundation.</p>
</div>
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>