1 //===-- wrappers_c_checks.h -------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef SCUDO_CHECKS_H_
10 #define SCUDO_CHECKS_H_
11
12 #include "common.h"
13
14 #include <errno.h>
15
16 #ifndef __has_builtin
17 #define __has_builtin(X) 0
18 #endif
19
20 namespace scudo {
21
22 // A common errno setting logic shared by almost all Scudo C wrappers.
setErrnoOnNull(void * Ptr)23 inline void *setErrnoOnNull(void *Ptr) {
24 if (UNLIKELY(!Ptr))
25 errno = ENOMEM;
26 return Ptr;
27 }
28
29 // Checks return true on failure.
30
31 // Checks aligned_alloc() parameters, verifies that the alignment is a power of
32 // two and that the size is a multiple of alignment.
checkAlignedAllocAlignmentAndSize(uptr Alignment,uptr Size)33 inline bool checkAlignedAllocAlignmentAndSize(uptr Alignment, uptr Size) {
34 return Alignment == 0 || !isPowerOfTwo(Alignment) ||
35 !isAligned(Size, Alignment);
36 }
37
38 // Checks posix_memalign() parameters, verifies that alignment is a power of two
39 // and a multiple of sizeof(void *).
checkPosixMemalignAlignment(uptr Alignment)40 inline bool checkPosixMemalignAlignment(uptr Alignment) {
41 return Alignment == 0 || !isPowerOfTwo(Alignment) ||
42 !isAligned(Alignment, sizeof(void *));
43 }
44
45 // Returns true if calloc(Size, N) overflows on Size*N calculation. Use a
46 // builtin supported by recent clang & GCC if it exists, otherwise fallback to a
47 // costly division.
checkForCallocOverflow(uptr Size,uptr N,uptr * Product)48 inline bool checkForCallocOverflow(uptr Size, uptr N, uptr *Product) {
49 #if __has_builtin(__builtin_umull_overflow)
50 return __builtin_umull_overflow(Size, N, Product);
51 #else
52 *Product = Size * N;
53 if (!Size)
54 return false;
55 return (*Product / Size) != N;
56 #endif
57 }
58
59 // Returns true if the size passed to pvalloc overflows when rounded to the next
60 // multiple of PageSize.
checkForPvallocOverflow(uptr Size,uptr PageSize)61 inline bool checkForPvallocOverflow(uptr Size, uptr PageSize) {
62 return roundUpTo(Size, PageSize) < Size;
63 }
64
65 } // namespace scudo
66
67 #endif // SCUDO_CHECKS_H_
68