1*0b57cec5SDimitry Andric //===-- dfsan_interface.h -------------------------------------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file is a part of DataFlowSanitizer. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric // Public interface header. 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric #ifndef DFSAN_INTERFACE_H 14*0b57cec5SDimitry Andric #define DFSAN_INTERFACE_H 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric #include <stddef.h> 17*0b57cec5SDimitry Andric #include <stdint.h> 18*0b57cec5SDimitry Andric #include <sanitizer/common_interface_defs.h> 19*0b57cec5SDimitry Andric 20*0b57cec5SDimitry Andric #ifdef __cplusplus 21*0b57cec5SDimitry Andric extern "C" { 22*0b57cec5SDimitry Andric #endif 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric typedef uint16_t dfsan_label; 25*0b57cec5SDimitry Andric 26*0b57cec5SDimitry Andric /// Stores information associated with a specific label identifier. A label 27*0b57cec5SDimitry Andric /// may be a base label created using dfsan_create_label, with associated 28*0b57cec5SDimitry Andric /// text description and user data, or an automatically created union label, 29*0b57cec5SDimitry Andric /// which represents the union of two label identifiers (which may themselves 30*0b57cec5SDimitry Andric /// be base or union labels). 31*0b57cec5SDimitry Andric struct dfsan_label_info { 32*0b57cec5SDimitry Andric // Fields for union labels, set to 0 for base labels. 33*0b57cec5SDimitry Andric dfsan_label l1; 34*0b57cec5SDimitry Andric dfsan_label l2; 35*0b57cec5SDimitry Andric 36*0b57cec5SDimitry Andric // Fields for base labels. 37*0b57cec5SDimitry Andric const char *desc; 38*0b57cec5SDimitry Andric void *userdata; 39*0b57cec5SDimitry Andric }; 40*0b57cec5SDimitry Andric 41*0b57cec5SDimitry Andric /// Signature of the callback argument to dfsan_set_write_callback(). 42*0b57cec5SDimitry Andric typedef void (*dfsan_write_callback_t)(int fd, const void *buf, size_t count); 43*0b57cec5SDimitry Andric 44*0b57cec5SDimitry Andric /// Computes the union of \c l1 and \c l2, possibly creating a union label in 45*0b57cec5SDimitry Andric /// the process. 46*0b57cec5SDimitry Andric dfsan_label dfsan_union(dfsan_label l1, dfsan_label l2); 47*0b57cec5SDimitry Andric 48*0b57cec5SDimitry Andric /// Creates and returns a base label with the given description and user data. 49*0b57cec5SDimitry Andric dfsan_label dfsan_create_label(const char *desc, void *userdata); 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric /// Sets the label for each address in [addr,addr+size) to \c label. 52*0b57cec5SDimitry Andric void dfsan_set_label(dfsan_label label, void *addr, size_t size); 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric /// Sets the label for each address in [addr,addr+size) to the union of the 55*0b57cec5SDimitry Andric /// current label for that address and \c label. 56*0b57cec5SDimitry Andric void dfsan_add_label(dfsan_label label, void *addr, size_t size); 57*0b57cec5SDimitry Andric 58*0b57cec5SDimitry Andric /// Retrieves the label associated with the given data. 59*0b57cec5SDimitry Andric /// 60*0b57cec5SDimitry Andric /// The type of 'data' is arbitrary. The function accepts a value of any type, 61*0b57cec5SDimitry Andric /// which can be truncated or extended (implicitly or explicitly) as necessary. 62*0b57cec5SDimitry Andric /// The truncation/extension operations will preserve the label of the original 63*0b57cec5SDimitry Andric /// value. 64*0b57cec5SDimitry Andric dfsan_label dfsan_get_label(long data); 65*0b57cec5SDimitry Andric 66*0b57cec5SDimitry Andric /// Retrieves the label associated with the data at the given address. 67*0b57cec5SDimitry Andric dfsan_label dfsan_read_label(const void *addr, size_t size); 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric /// Retrieves a pointer to the dfsan_label_info struct for the given label. 70*0b57cec5SDimitry Andric const struct dfsan_label_info *dfsan_get_label_info(dfsan_label label); 71*0b57cec5SDimitry Andric 72*0b57cec5SDimitry Andric /// Returns whether the given label label contains the label elem. 73*0b57cec5SDimitry Andric int dfsan_has_label(dfsan_label label, dfsan_label elem); 74*0b57cec5SDimitry Andric 75*0b57cec5SDimitry Andric /// If the given label label contains a label with the description desc, returns 76*0b57cec5SDimitry Andric /// that label, else returns 0. 77*0b57cec5SDimitry Andric dfsan_label dfsan_has_label_with_desc(dfsan_label label, const char *desc); 78*0b57cec5SDimitry Andric 79*0b57cec5SDimitry Andric /// Returns the number of labels allocated. 80*0b57cec5SDimitry Andric size_t dfsan_get_label_count(void); 81*0b57cec5SDimitry Andric 82*0b57cec5SDimitry Andric /// Flushes the DFSan shadow, i.e. forgets about all labels currently associated 83*0b57cec5SDimitry Andric /// with the application memory. Will work only if there are no other 84*0b57cec5SDimitry Andric /// threads executing DFSan-instrumented code concurrently. 85*0b57cec5SDimitry Andric /// Use this call to start over the taint tracking within the same procces. 86*0b57cec5SDimitry Andric void dfsan_flush(void); 87*0b57cec5SDimitry Andric 88*0b57cec5SDimitry Andric /// Sets a callback to be invoked on calls to write(). The callback is invoked 89*0b57cec5SDimitry Andric /// before the write is done. The write is not guaranteed to succeed when the 90*0b57cec5SDimitry Andric /// callback executes. Pass in NULL to remove any callback. 91*0b57cec5SDimitry Andric void dfsan_set_write_callback(dfsan_write_callback_t labeled_write_callback); 92*0b57cec5SDimitry Andric 93*0b57cec5SDimitry Andric /// Writes the labels currently used by the program to the given file 94*0b57cec5SDimitry Andric /// descriptor. The lines of the output have the following format: 95*0b57cec5SDimitry Andric /// 96*0b57cec5SDimitry Andric /// <label> <parent label 1> <parent label 2> <label description if any> 97*0b57cec5SDimitry Andric void dfsan_dump_labels(int fd); 98*0b57cec5SDimitry Andric 99*0b57cec5SDimitry Andric /// Interceptor hooks. 100*0b57cec5SDimitry Andric /// Whenever a dfsan's custom function is called the corresponding 101*0b57cec5SDimitry Andric /// hook is called it non-zero. The hooks should be defined by the user. 102*0b57cec5SDimitry Andric /// The primary use case is taint-guided fuzzing, where the fuzzer 103*0b57cec5SDimitry Andric /// needs to see the parameters of the function and the labels. 104*0b57cec5SDimitry Andric /// FIXME: implement more hooks. 105*0b57cec5SDimitry Andric void dfsan_weak_hook_memcmp(void *caller_pc, const void *s1, const void *s2, 106*0b57cec5SDimitry Andric size_t n, dfsan_label s1_label, 107*0b57cec5SDimitry Andric dfsan_label s2_label, dfsan_label n_label); 108*0b57cec5SDimitry Andric void dfsan_weak_hook_strncmp(void *caller_pc, const char *s1, const char *s2, 109*0b57cec5SDimitry Andric size_t n, dfsan_label s1_label, 110*0b57cec5SDimitry Andric dfsan_label s2_label, dfsan_label n_label); 111*0b57cec5SDimitry Andric #ifdef __cplusplus 112*0b57cec5SDimitry Andric } // extern "C" 113*0b57cec5SDimitry Andric 114*0b57cec5SDimitry Andric template <typename T> 115*0b57cec5SDimitry Andric void dfsan_set_label(dfsan_label label, T &data) { // NOLINT 116*0b57cec5SDimitry Andric dfsan_set_label(label, (void *)&data, sizeof(T)); 117*0b57cec5SDimitry Andric } 118*0b57cec5SDimitry Andric 119*0b57cec5SDimitry Andric #endif 120*0b57cec5SDimitry Andric 121*0b57cec5SDimitry Andric #endif // DFSAN_INTERFACE_H 122