Home | History | Annotate | Line # | Download | only in sanitizer_common
      1 //===-- sanitizer_allocator_checks.h ----------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // Various checks shared between ThreadSanitizer, MemorySanitizer, etc. memory
     11 // allocators.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef SANITIZER_ALLOCATOR_CHECKS_H
     16 #define SANITIZER_ALLOCATOR_CHECKS_H
     17 
     18 #include "sanitizer_internal_defs.h"
     19 #include "sanitizer_common.h"
     20 #include "sanitizer_platform.h"
     21 
     22 namespace __sanitizer {
     23 
     24 // The following is defined in a separate compilation unit to avoid pulling in
     25 // sanitizer_errno.h in this header, which leads to conflicts when other system
     26 // headers include errno.h. This is usually the result of an unlikely event,
     27 // and as such we do not care as much about having it inlined.
     28 void SetErrnoToENOMEM();
     29 
     30 // A common errno setting logic shared by almost all sanitizer allocator APIs.
     31 INLINE void *SetErrnoOnNull(void *ptr) {
     32   if (UNLIKELY(!ptr))
     33     SetErrnoToENOMEM();
     34   return ptr;
     35 }
     36 
     37 // In case of the check failure, the caller of the following Check... functions
     38 // should "return POLICY::OnBadRequest();" where POLICY is the current allocator
     39 // failure handling policy.
     40 
     41 // Checks aligned_alloc() parameters, verifies that the alignment is a power of
     42 // two and that the size is a multiple of alignment for POSIX implementation,
     43 // and a bit relaxed requirement for non-POSIX ones, that the size is a multiple
     44 // of alignment.
     45 INLINE bool CheckAlignedAllocAlignmentAndSize(uptr alignment, uptr size) {
     46 #if SANITIZER_POSIX
     47   return alignment != 0 && IsPowerOfTwo(alignment) &&
     48          (size & (alignment - 1)) == 0;
     49 #else
     50   return alignment != 0 && size % alignment == 0;
     51 #endif
     52 }
     53 
     54 // Checks posix_memalign() parameters, verifies that alignment is a power of two
     55 // and a multiple of sizeof(void *).
     56 INLINE bool CheckPosixMemalignAlignment(uptr alignment) {
     57   return alignment != 0 && IsPowerOfTwo(alignment) &&
     58          (alignment % sizeof(void *)) == 0; // NOLINT
     59 }
     60 
     61 // Returns true if calloc(size, n) call overflows on size*n calculation.
     62 INLINE bool CheckForCallocOverflow(uptr size, uptr n) {
     63   if (!size)
     64     return false;
     65   uptr max = (uptr)-1L;
     66   return (max / size) < n;
     67 }
     68 
     69 // Returns true if the size passed to pvalloc overflows when rounded to the next
     70 // multiple of page_size.
     71 INLINE bool CheckForPvallocOverflow(uptr size, uptr page_size) {
     72   return RoundUpTo(size, page_size) < size;
     73 }
     74 
     75 } // namespace __sanitizer
     76 
     77 #endif  // SANITIZER_ALLOCATOR_CHECKS_H
     78