File: SanitizerSpecialCaseList.rst

package info (click to toggle)
llvm-toolchain-20 1%3A20.1.8-1~exp1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 2,111,388 kB
  • sloc: cpp: 7,438,767; ansic: 1,393,871; asm: 1,012,926; python: 241,728; f90: 86,635; objc: 75,411; lisp: 42,144; pascal: 17,286; sh: 10,027; ml: 5,082; perl: 4,730; awk: 3,523; makefile: 3,349; javascript: 2,251; xml: 892; fortran: 672
file content (182 lines) | stat: -rw-r--r-- 6,780 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
===========================
Sanitizer special case list
===========================

.. contents::
   :local:

Introduction
============

This document describes the way to disable or alter the behavior of
sanitizer tools for certain source-level entities by providing a special
file at compile-time.

Goal and usage
==============

Users of sanitizer tools, such as :doc:`AddressSanitizer`,
:doc:`HardwareAssistedAddressSanitizerDesign`, :doc:`ThreadSanitizer`,
:doc:`MemorySanitizer` or :doc:`UndefinedBehaviorSanitizer` may want to disable
or alter some checks for certain source-level entities to:

* speedup hot function, which is known to be correct;
* ignore a function that does some low-level magic (e.g. walks through the
  thread stack, bypassing the frame boundaries);
* ignore a known problem.

To achieve this, user may create a file listing the entities they want to
ignore, and pass it to clang at compile-time using
``-fsanitize-ignorelist`` flag. See :doc:`UsersManual` for details.

Example
=======

.. code-block:: bash

  $ cat foo.c
  #include <stdlib.h>
  void bad_foo() {
    int *a = (int*)malloc(40);
    a[10] = 1;
  }
  int main() { bad_foo(); }
  $ cat ignorelist.txt
  # Ignore reports from bad_foo function.
  fun:bad_foo
  $ clang -fsanitize=address foo.c ; ./a.out
  # AddressSanitizer prints an error report.
  $ clang -fsanitize=address -fsanitize-ignorelist=ignorelist.txt foo.c ; ./a.out
  # No error report here.

Usage with UndefinedBehaviorSanitizer
=====================================

``unsigned-integer-overflow``, ``signed-integer-overflow``,
``implicit-signed-integer-truncation``,
``implicit-unsigned-integer-truncation``, and ``enum`` sanitizers support the
ability to adjust instrumentation based on type.

By default, supported sanitizers will have their instrumentation disabled for
types specified within an ignorelist.

.. code-block:: bash

  $ cat foo.c
  void foo() {
    int a = 2147483647; // INT_MAX
    ++a;                // Normally, an overflow with -fsanitize=signed-integer-overflow
  }
  $ cat ignorelist.txt
  [signed-integer-overflow]
  type:int
  $ clang -fsanitize=signed-integer-overflow -fsanitize-ignorelist=ignorelist.txt foo.c ; ./a.out
  # no signed-integer-overflow error

For example, supplying the above ``ignorelist.txt`` to
``-fsanitize-ignorelist=ignorelist.txt`` disables overflow sanitizer
instrumentation for arithmetic operations containing values of type ``int``.

The ``=sanitize`` category is also supported. Any types assigned to the
``sanitize`` category will have their sanitizer instrumentation remain. If the
same type appears within or across ignorelists with different categories the
``sanitize`` category takes precedence -- regardless of order.

With this, one may disable instrumentation for some or all types and
specifically allow instrumentation for one or many types -- including types
created via ``typedef``. This is a way to achieve a sort of "allowlist" for
supported sanitizers.

.. code-block:: bash

  $ cat ignorelist.txt
  [implicit-signed-integer-truncation]
  type:*
  type:T=sanitize

  $ cat foo.c
  typedef char T;
  typedef char U;
  void foo(int toobig) {
    T a = toobig;    // instrumented
    U b = toobig;    // not instrumented
    char c = toobig; // also not instrumented
  }

Format
======

Ignorelists consist of entries, optionally grouped into sections. Empty lines
and lines starting with "#" are ignored.

.. note::

  Prior to Clang 18, section names and entries described below use a variant of
  regex where ``*`` is translated to ``.*``. Clang 18 (`D154014
  <https://reviews.llvm.org/D154014>`) switches to glob and plans to remove
  regex support in Clang 19.

  For Clang 18, regex is supported if ``#!special-case-list-v1`` is the first
  line of the file.

  Many special case lists use ``.`` to indicate the literal character and do
  not use regex metacharacters such as ``(``, ``)``. They are unaffected by the
  regex to glob transition. For more details, see `this discourse post
  <https://discourse.llvm.org/t/use-glob-instead-of-regex-for-specialcaselists/71666>`_.

Section names are globs written in square brackets that denote
which sanitizer the following entries apply to. For example, ``[address]``
specifies AddressSanitizer while ``[{cfi-vcall,cfi-icall}]`` specifies Control
Flow Integrity virtual and indirect call checking. Entries without a section
will be placed under the ``[*]`` section applying to all enabled sanitizers.

Entries contain an entity type, followed by a colon and a glob,
specifying the names of the entities, optionally followed by an equals sign and
a tool-specific category, e.g. ``fun:*ExampleFunc=example_category``.
Two generic entity types are ``src`` and
``fun``, which allow users to specify source files and functions, respectively.
Some sanitizer tools may introduce custom entity types and categories - refer to
tool-specific docs.

.. code-block:: bash

    # The line above is explained in the note above
    # Lines starting with # are ignored.
    # Turn off checks for the source file
    # Entries without sections are placed into [*] and apply to all sanitizers
    src:path/to/source/file.c
    src:*/source/file.c
    # Turn off checks for this main file, including files included by it.
    # Useful when the main file instead of an included file should be ignored.
    mainfile:file.c
    # Turn off checks for a particular functions (use mangled names):
    fun:_Z8MyFooBarv
    # Glob brace expansions and character ranges are supported
    fun:bad_{foo,bar}
    src:bad_source[1-9].c
    # "*" matches zero or more characters
    src:bad/sources/*
    fun:*BadFunction*
    # Specific sanitizer tools may introduce categories.
    src:/special/path/*=special_sources
    # Sections can be used to limit ignorelist entries to specific sanitizers
    [address]
    fun:*BadASanFunc*
    # Section names are globs
    [{cfi-vcall,cfi-icall}]
    fun:*BadCfiCall

``mainfile`` is similar to applying ``-fno-sanitize=`` to a set of files but
does not need plumbing into the build system. This works well for internal
linkage functions but has a caveat for C++ vague linkage functions.

C++ vague linkage functions (e.g. inline functions, template instantiations) are
deduplicated at link time. A function (in an included file) ignored by a
specific ``mainfile`` pattern may not be the prevailing copy picked by the
linker. Therefore, using ``mainfile`` requires caution. It may still be useful,
e.g. when patterns are picked in a way to ensure the prevailing one is ignored.
(There is action-at-a-distance risk.)

``mainfile`` can be useful enabling a ubsan check for a large code base when
finding the direct stack frame triggering the failure for every failure is
difficult.