xref: /minix3/external/bsd/llvm/dist/clang/docs/DataFlowSanitizer.rst (revision f4a2713ac843a11c696ec80c0a5e3e5d80b4d338)
1*f4a2713aSLionel Sambuc=================
2*f4a2713aSLionel SambucDataFlowSanitizer
3*f4a2713aSLionel Sambuc=================
4*f4a2713aSLionel Sambuc
5*f4a2713aSLionel Sambuc.. toctree::
6*f4a2713aSLionel Sambuc   :hidden:
7*f4a2713aSLionel Sambuc
8*f4a2713aSLionel Sambuc   DataFlowSanitizerDesign
9*f4a2713aSLionel Sambuc
10*f4a2713aSLionel Sambuc.. contents::
11*f4a2713aSLionel Sambuc   :local:
12*f4a2713aSLionel Sambuc
13*f4a2713aSLionel SambucIntroduction
14*f4a2713aSLionel Sambuc============
15*f4a2713aSLionel Sambuc
16*f4a2713aSLionel SambucDataFlowSanitizer is a generalised dynamic data flow analysis.
17*f4a2713aSLionel Sambuc
18*f4a2713aSLionel SambucUnlike other Sanitizer tools, this tool is not designed to detect a
19*f4a2713aSLionel Sambucspecific class of bugs on its own.  Instead, it provides a generic
20*f4a2713aSLionel Sambucdynamic data flow analysis framework to be used by clients to help
21*f4a2713aSLionel Sambucdetect application-specific issues within their own code.
22*f4a2713aSLionel Sambuc
23*f4a2713aSLionel SambucUsage
24*f4a2713aSLionel Sambuc=====
25*f4a2713aSLionel Sambuc
26*f4a2713aSLionel SambucWith no program changes, applying DataFlowSanitizer to a program
27*f4a2713aSLionel Sambucwill not alter its behavior.  To use DataFlowSanitizer, the program
28*f4a2713aSLionel Sambucuses API functions to apply tags to data to cause it to be tracked, and to
29*f4a2713aSLionel Sambuccheck the tag of a specific data item.  DataFlowSanitizer manages
30*f4a2713aSLionel Sambucthe propagation of tags through the program according to its data flow.
31*f4a2713aSLionel Sambuc
32*f4a2713aSLionel SambucThe APIs are defined in the header file ``sanitizer/dfsan_interface.h``.
33*f4a2713aSLionel SambucFor further information about each function, please refer to the header
34*f4a2713aSLionel Sambucfile.
35*f4a2713aSLionel Sambuc
36*f4a2713aSLionel SambucABI List
37*f4a2713aSLionel Sambuc--------
38*f4a2713aSLionel Sambuc
39*f4a2713aSLionel SambucDataFlowSanitizer uses a list of functions known as an ABI list to decide
40*f4a2713aSLionel Sambucwhether a call to a specific function should use the operating system's native
41*f4a2713aSLionel SambucABI or whether it should use a variant of this ABI that also propagates labels
42*f4a2713aSLionel Sambucthrough function parameters and return values.  The ABI list file also controls
43*f4a2713aSLionel Sambuchow labels are propagated in the former case.  DataFlowSanitizer comes with a
44*f4a2713aSLionel Sambucdefault ABI list which is intended to eventually cover the glibc library on
45*f4a2713aSLionel SambucLinux but it may become necessary for users to extend the ABI list in cases
46*f4a2713aSLionel Sambucwhere a particular library or function cannot be instrumented (e.g. because
47*f4a2713aSLionel Sambucit is implemented in assembly or another language which DataFlowSanitizer does
48*f4a2713aSLionel Sambucnot support) or a function is called from a library or function which cannot
49*f4a2713aSLionel Sambucbe instrumented.
50*f4a2713aSLionel Sambuc
51*f4a2713aSLionel SambucDataFlowSanitizer's ABI list file is a :doc:`SanitizerSpecialCaseList`.
52*f4a2713aSLionel SambucThe pass treats every function in the ``uninstrumented`` category in the
53*f4a2713aSLionel SambucABI list file as conforming to the native ABI.  Unless the ABI list contains
54*f4a2713aSLionel Sambucadditional categories for those functions, a call to one of those functions
55*f4a2713aSLionel Sambucwill produce a warning message, as the labelling behavior of the function
56*f4a2713aSLionel Sambucis unknown.  The other supported categories are ``discard``, ``functional``
57*f4a2713aSLionel Sambucand ``custom``.
58*f4a2713aSLionel Sambuc
59*f4a2713aSLionel Sambuc* ``discard`` -- To the extent that this function writes to (user-accessible)
60*f4a2713aSLionel Sambuc  memory, it also updates labels in shadow memory (this condition is trivially
61*f4a2713aSLionel Sambuc  satisfied for functions which do not write to user-accessible memory).  Its
62*f4a2713aSLionel Sambuc  return value is unlabelled.
63*f4a2713aSLionel Sambuc* ``functional`` -- Like ``discard``, except that the label of its return value
64*f4a2713aSLionel Sambuc  is the union of the label of its arguments.
65*f4a2713aSLionel Sambuc* ``custom`` -- Instead of calling the function, a custom wrapper ``__dfsw_F``
66*f4a2713aSLionel Sambuc  is called, where ``F`` is the name of the function.  This function may wrap
67*f4a2713aSLionel Sambuc  the original function or provide its own implementation.  This category is
68*f4a2713aSLionel Sambuc  generally used for uninstrumentable functions which write to user-accessible
69*f4a2713aSLionel Sambuc  memory or which have more complex label propagation behavior.  The signature
70*f4a2713aSLionel Sambuc  of ``__dfsw_F`` is based on that of ``F`` with each argument having a
71*f4a2713aSLionel Sambuc  label of type ``dfsan_label`` appended to the argument list.  If ``F``
72*f4a2713aSLionel Sambuc  is of non-void return type a final argument of type ``dfsan_label *``
73*f4a2713aSLionel Sambuc  is appended to which the custom function can store the label for the
74*f4a2713aSLionel Sambuc  return value.  For example:
75*f4a2713aSLionel Sambuc
76*f4a2713aSLionel Sambuc.. code-block:: c++
77*f4a2713aSLionel Sambuc
78*f4a2713aSLionel Sambuc  void f(int x);
79*f4a2713aSLionel Sambuc  void __dfsw_f(int x, dfsan_label x_label);
80*f4a2713aSLionel Sambuc
81*f4a2713aSLionel Sambuc  void *memcpy(void *dest, const void *src, size_t n);
82*f4a2713aSLionel Sambuc  void *__dfsw_memcpy(void *dest, const void *src, size_t n,
83*f4a2713aSLionel Sambuc                      dfsan_label dest_label, dfsan_label src_label,
84*f4a2713aSLionel Sambuc                      dfsan_label n_label, dfsan_label *ret_label);
85*f4a2713aSLionel Sambuc
86*f4a2713aSLionel SambucIf a function defined in the translation unit being compiled belongs to the
87*f4a2713aSLionel Sambuc``uninstrumented`` category, it will be compiled so as to conform to the
88*f4a2713aSLionel Sambucnative ABI.  Its arguments will be assumed to be unlabelled, but it will
89*f4a2713aSLionel Sambucpropagate labels in shadow memory.
90*f4a2713aSLionel Sambuc
91*f4a2713aSLionel SambucFor example:
92*f4a2713aSLionel Sambuc
93*f4a2713aSLionel Sambuc.. code-block:: none
94*f4a2713aSLionel Sambuc
95*f4a2713aSLionel Sambuc  # main is called by the C runtime using the native ABI.
96*f4a2713aSLionel Sambuc  fun:main=uninstrumented
97*f4a2713aSLionel Sambuc  fun:main=discard
98*f4a2713aSLionel Sambuc
99*f4a2713aSLionel Sambuc  # malloc only writes to its internal data structures, not user-accessible memory.
100*f4a2713aSLionel Sambuc  fun:malloc=uninstrumented
101*f4a2713aSLionel Sambuc  fun:malloc=discard
102*f4a2713aSLionel Sambuc
103*f4a2713aSLionel Sambuc  # tolower is a pure function.
104*f4a2713aSLionel Sambuc  fun:tolower=uninstrumented
105*f4a2713aSLionel Sambuc  fun:tolower=functional
106*f4a2713aSLionel Sambuc
107*f4a2713aSLionel Sambuc  # memcpy needs to copy the shadow from the source to the destination region.
108*f4a2713aSLionel Sambuc  # This is done in a custom function.
109*f4a2713aSLionel Sambuc  fun:memcpy=uninstrumented
110*f4a2713aSLionel Sambuc  fun:memcpy=custom
111*f4a2713aSLionel Sambuc
112*f4a2713aSLionel SambucExample
113*f4a2713aSLionel Sambuc=======
114*f4a2713aSLionel Sambuc
115*f4a2713aSLionel SambucThe following program demonstrates label propagation by checking that
116*f4a2713aSLionel Sambucthe correct labels are propagated.
117*f4a2713aSLionel Sambuc
118*f4a2713aSLionel Sambuc.. code-block:: c++
119*f4a2713aSLionel Sambuc
120*f4a2713aSLionel Sambuc  #include <sanitizer/dfsan_interface.h>
121*f4a2713aSLionel Sambuc  #include <assert.h>
122*f4a2713aSLionel Sambuc
123*f4a2713aSLionel Sambuc  int main(void) {
124*f4a2713aSLionel Sambuc    int i = 1;
125*f4a2713aSLionel Sambuc    dfsan_label i_label = dfsan_create_label("i", 0);
126*f4a2713aSLionel Sambuc    dfsan_set_label(i_label, &i, sizeof(i));
127*f4a2713aSLionel Sambuc
128*f4a2713aSLionel Sambuc    int j = 2;
129*f4a2713aSLionel Sambuc    dfsan_label j_label = dfsan_create_label("j", 0);
130*f4a2713aSLionel Sambuc    dfsan_set_label(j_label, &j, sizeof(j));
131*f4a2713aSLionel Sambuc
132*f4a2713aSLionel Sambuc    int k = 3;
133*f4a2713aSLionel Sambuc    dfsan_label k_label = dfsan_create_label("k", 0);
134*f4a2713aSLionel Sambuc    dfsan_set_label(k_label, &k, sizeof(k));
135*f4a2713aSLionel Sambuc
136*f4a2713aSLionel Sambuc    dfsan_label ij_label = dfsan_get_label(i + j);
137*f4a2713aSLionel Sambuc    assert(dfsan_has_label(ij_label, i_label));
138*f4a2713aSLionel Sambuc    assert(dfsan_has_label(ij_label, j_label));
139*f4a2713aSLionel Sambuc    assert(!dfsan_has_label(ij_label, k_label));
140*f4a2713aSLionel Sambuc
141*f4a2713aSLionel Sambuc    dfsan_label ijk_label = dfsan_get_label(i + j + k);
142*f4a2713aSLionel Sambuc    assert(dfsan_has_label(ijk_label, i_label));
143*f4a2713aSLionel Sambuc    assert(dfsan_has_label(ijk_label, j_label));
144*f4a2713aSLionel Sambuc    assert(dfsan_has_label(ijk_label, k_label));
145*f4a2713aSLionel Sambuc
146*f4a2713aSLionel Sambuc    return 0;
147*f4a2713aSLionel Sambuc  }
148*f4a2713aSLionel Sambuc
149*f4a2713aSLionel SambucCurrent status
150*f4a2713aSLionel Sambuc==============
151*f4a2713aSLionel Sambuc
152*f4a2713aSLionel SambucDataFlowSanitizer is a work in progress, currently under development for
153*f4a2713aSLionel Sambucx86\_64 Linux.
154*f4a2713aSLionel Sambuc
155*f4a2713aSLionel SambucDesign
156*f4a2713aSLionel Sambuc======
157*f4a2713aSLionel Sambuc
158*f4a2713aSLionel SambucPlease refer to the :doc:`design document<DataFlowSanitizerDesign>`.
159