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