10b57cec5SDimitry Andric //===-- dfsan.h -------------------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file is a part of DataFlowSanitizer.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric // Private DFSan header.
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric #ifndef DFSAN_H
150b57cec5SDimitry Andric #define DFSAN_H
160b57cec5SDimitry Andric
170b57cec5SDimitry Andric #include "sanitizer_common/sanitizer_internal_defs.h"
18fe6060f1SDimitry Andric
190b57cec5SDimitry Andric #include "dfsan_platform.h"
200b57cec5SDimitry Andric
21fe6060f1SDimitry Andric using __sanitizer::u32;
22fe6060f1SDimitry Andric using __sanitizer::u8;
230b57cec5SDimitry Andric using __sanitizer::uptr;
240b57cec5SDimitry Andric
250b57cec5SDimitry Andric // Copy declarations from public sanitizer/dfsan_interface.h header here.
26fe6060f1SDimitry Andric typedef u8 dfsan_label;
27fe6060f1SDimitry Andric typedef u32 dfsan_origin;
280b57cec5SDimitry Andric
290b57cec5SDimitry Andric extern "C" {
300b57cec5SDimitry Andric void dfsan_add_label(dfsan_label label, void *addr, uptr size);
310b57cec5SDimitry Andric void dfsan_set_label(dfsan_label label, void *addr, uptr size);
320b57cec5SDimitry Andric dfsan_label dfsan_read_label(const void *addr, uptr size);
330b57cec5SDimitry Andric dfsan_label dfsan_union(dfsan_label l1, dfsan_label l2);
34fe6060f1SDimitry Andric // Zero out [offset, offset+size) from __dfsan_arg_tls.
35fe6060f1SDimitry Andric void dfsan_clear_arg_tls(uptr offset, uptr size);
36fe6060f1SDimitry Andric // Zero out the TLS storage.
37fe6060f1SDimitry Andric void dfsan_clear_thread_local_state();
38fe6060f1SDimitry Andric
39*81ad6265SDimitry Andric // Set DFSan label and origin TLS of argument for a call.
40*81ad6265SDimitry Andric // Note that offset may not correspond with argument number.
41*81ad6265SDimitry Andric // Some arguments (aggregate/array) will use several offsets.
42*81ad6265SDimitry Andric void dfsan_set_arg_tls(uptr offset, dfsan_label label);
43*81ad6265SDimitry Andric void dfsan_set_arg_origin_tls(uptr offset, dfsan_origin o);
44*81ad6265SDimitry Andric
45fe6060f1SDimitry Andric // Return the origin associated with the first taint byte in the size bytes
46fe6060f1SDimitry Andric // from the address addr.
47fe6060f1SDimitry Andric dfsan_origin dfsan_read_origin_of_first_taint(const void *addr, uptr size);
48fe6060f1SDimitry Andric
49fe6060f1SDimitry Andric // Set the data within [addr, addr+size) with label and origin.
50fe6060f1SDimitry Andric void dfsan_set_label_origin(dfsan_label label, dfsan_origin origin, void *addr,
51fe6060f1SDimitry Andric uptr size);
52fe6060f1SDimitry Andric
53fe6060f1SDimitry Andric // Copy or move the origins of the len bytes from src to dst.
54fe6060f1SDimitry Andric void dfsan_mem_origin_transfer(const void *dst, const void *src, uptr len);
5504eeddc0SDimitry Andric
5604eeddc0SDimitry Andric // Copy shadow bytes from src to dst.
5704eeddc0SDimitry Andric // Note this preserves distinct taint labels at specific offsets.
5804eeddc0SDimitry Andric void dfsan_mem_shadow_transfer(void *dst, const void *src, uptr len);
590b57cec5SDimitry Andric } // extern "C"
600b57cec5SDimitry Andric
610b57cec5SDimitry Andric template <typename T>
dfsan_set_label(dfsan_label label,T & data)62349cc55cSDimitry Andric void dfsan_set_label(dfsan_label label, T &data) {
630b57cec5SDimitry Andric dfsan_set_label(label, (void *)&data, sizeof(T));
640b57cec5SDimitry Andric }
650b57cec5SDimitry Andric
660b57cec5SDimitry Andric namespace __dfsan {
670b57cec5SDimitry Andric
68fe6060f1SDimitry Andric extern bool dfsan_inited;
69fe6060f1SDimitry Andric extern bool dfsan_init_is_running;
70fe6060f1SDimitry Andric
71fe6060f1SDimitry Andric void initialize_interceptors();
720b57cec5SDimitry Andric
shadow_for(void * ptr)730b57cec5SDimitry Andric inline dfsan_label *shadow_for(void *ptr) {
74fe6060f1SDimitry Andric return (dfsan_label *)MEM_TO_SHADOW(ptr);
750b57cec5SDimitry Andric }
760b57cec5SDimitry Andric
shadow_for(const void * ptr)770b57cec5SDimitry Andric inline const dfsan_label *shadow_for(const void *ptr) {
780b57cec5SDimitry Andric return shadow_for(const_cast<void *>(ptr));
790b57cec5SDimitry Andric }
800b57cec5SDimitry Andric
unaligned_origin_for(uptr ptr)81fe6060f1SDimitry Andric inline uptr unaligned_origin_for(uptr ptr) { return MEM_TO_ORIGIN(ptr); }
820b57cec5SDimitry Andric
origin_for(void * ptr)83fe6060f1SDimitry Andric inline dfsan_origin *origin_for(void *ptr) {
84fe6060f1SDimitry Andric auto aligned_addr = unaligned_origin_for(reinterpret_cast<uptr>(ptr)) &
85fe6060f1SDimitry Andric ~(sizeof(dfsan_origin) - 1);
86fe6060f1SDimitry Andric return reinterpret_cast<dfsan_origin *>(aligned_addr);
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric
origin_for(const void * ptr)89fe6060f1SDimitry Andric inline const dfsan_origin *origin_for(const void *ptr) {
90fe6060f1SDimitry Andric return origin_for(const_cast<void *>(ptr));
91fe6060f1SDimitry Andric }
92fe6060f1SDimitry Andric
93fe6060f1SDimitry Andric void dfsan_copy_memory(void *dst, const void *src, uptr size);
94fe6060f1SDimitry Andric
95fe6060f1SDimitry Andric void dfsan_allocator_init();
96fe6060f1SDimitry Andric void dfsan_deallocate(void *ptr);
97fe6060f1SDimitry Andric
98fe6060f1SDimitry Andric void *dfsan_malloc(uptr size);
99fe6060f1SDimitry Andric void *dfsan_calloc(uptr nmemb, uptr size);
100fe6060f1SDimitry Andric void *dfsan_realloc(void *ptr, uptr size);
101fe6060f1SDimitry Andric void *dfsan_reallocarray(void *ptr, uptr nmemb, uptr size);
102fe6060f1SDimitry Andric void *dfsan_valloc(uptr size);
103fe6060f1SDimitry Andric void *dfsan_pvalloc(uptr size);
104fe6060f1SDimitry Andric void *dfsan_aligned_alloc(uptr alignment, uptr size);
105fe6060f1SDimitry Andric void *dfsan_memalign(uptr alignment, uptr size);
106fe6060f1SDimitry Andric int dfsan_posix_memalign(void **memptr, uptr alignment, uptr size);
107fe6060f1SDimitry Andric
108fe6060f1SDimitry Andric void dfsan_init();
109fe6060f1SDimitry Andric
1100b57cec5SDimitry Andric } // namespace __dfsan
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andric #endif // DFSAN_H
113