xref: /freebsd/contrib/llvm-project/compiler-rt/include/sanitizer/dfsan_interface.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
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