File: nsan_malloc_linux.cpp

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-19
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,999,616 kB
  • sloc: cpp: 6,951,724; ansic: 1,486,157; asm: 913,598; python: 232,059; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,079; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,430; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (123 lines) | stat: -rw-r--r-- 3,737 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//===- nsan_malloc_linux.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Interceptors for memory allocation functions on ELF OSes.
//
//===----------------------------------------------------------------------===//

#include "interception/interception.h"
#include "nsan/nsan.h"
#include "sanitizer_common/sanitizer_allocator_dlsym.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_platform.h"
#include "sanitizer_common/sanitizer_platform_interceptors.h"

#if !SANITIZER_APPLE && !SANITIZER_WINDOWS
using namespace __sanitizer;
using __nsan::nsan_initialized;

namespace {
struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> {
  static bool UseImpl() { return !nsan_initialized; }
};
} // namespace

INTERCEPTOR(void *, aligned_alloc, uptr align, uptr size) {
  void *res = REAL(aligned_alloc)(align, size);
  if (res)
    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
  return res;
}

INTERCEPTOR(void *, calloc, uptr nmemb, uptr size) {
  if (DlsymAlloc::Use())
    return DlsymAlloc::Callocate(nmemb, size);

  void *res = REAL(calloc)(nmemb, size);
  if (res)
    __nsan_set_value_unknown(static_cast<u8 *>(res), nmemb * size);
  return res;
}

INTERCEPTOR(void, free, void *ptr) {
  if (DlsymAlloc::PointerIsMine(ptr))
    return DlsymAlloc::Free(ptr);
  REAL(free)(ptr);
}

INTERCEPTOR(void *, malloc, uptr size) {
  if (DlsymAlloc::Use())
    return DlsymAlloc::Allocate(size);
  void *res = REAL(malloc)(size);
  if (res)
    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
  return res;
}

INTERCEPTOR(void *, realloc, void *ptr, uptr size) {
  if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr))
    return DlsymAlloc::Realloc(ptr, size);
  void *res = REAL(realloc)(ptr, size);
  // TODO: We might want to copy the types from the original allocation
  // (although that would require that we know its size).
  if (res)
    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
  return res;
}

#if SANITIZER_INTERCEPT_REALLOCARRAY
INTERCEPTOR(void *, reallocarray, void *ptr, uptr nmemb, uptr size) {
  void *res = REAL(reallocarray)(ptr, nmemb, size);
  if (res)
    __nsan_set_value_unknown(static_cast<u8 *>(res), nmemb * size);
  return res;
}
#endif // SANITIZER_INTERCEPT_REALLOCARRAY

INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr size) {
  int res = REAL(posix_memalign)(memptr, align, size);
  if (res == 0 && *memptr)
    __nsan_set_value_unknown(static_cast<u8 *>(*memptr), size);
  return res;
}

// Deprecated allocation functions (memalign, etc).
#if SANITIZER_INTERCEPT_MEMALIGN
INTERCEPTOR(void *, memalign, uptr align, uptr size) {
  void *const res = REAL(memalign)(align, size);
  if (res)
    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
  return res;
}

INTERCEPTOR(void *, __libc_memalign, uptr align, uptr size) {
  void *const res = REAL(__libc_memalign)(align, size);
  if (res)
    __nsan_set_value_unknown(static_cast<u8 *>(res), size);
  return res;
}
#endif

void __nsan::InitializeMallocInterceptors() {
  INTERCEPT_FUNCTION(aligned_alloc);
  INTERCEPT_FUNCTION(calloc);
  INTERCEPT_FUNCTION(free);
  INTERCEPT_FUNCTION(malloc);
  INTERCEPT_FUNCTION(posix_memalign);
  INTERCEPT_FUNCTION(realloc);
#if SANITIZER_INTERCEPT_REALLOCARRAY
  INTERCEPT_FUNCTION(reallocarray);
#endif

#if SANITIZER_INTERCEPT_MEMALIGN
  INTERCEPT_FUNCTION(memalign);
  INTERCEPT_FUNCTION(__libc_memalign);
#endif
}

#endif