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 20namespace scudo { 21 22// A common errno setting logic shared by almost all Scudo C wrappers. 23inline 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. 33inline 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 *). 40inline 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. 48inline bool checkForCallocOverflow(uptr Size, uptr N, uptr *Product) { 49#if __has_builtin(__builtin_umull_overflow) && (SCUDO_WORDSIZE == 64U) 50 return __builtin_umull_overflow(Size, N, 51 reinterpret_cast<unsigned long *>(Product)); 52#elif __has_builtin(__builtin_umul_overflow) && (SCUDO_WORDSIZE == 32U) 53 // On, e.g. armv7, uptr/uintptr_t may be defined as unsigned long 54 return __builtin_umul_overflow(Size, N, 55 reinterpret_cast<unsigned int *>(Product)); 56#else 57 *Product = Size * N; 58 if (!Size) 59 return false; 60 return (*Product / Size) != N; 61#endif 62} 63 64// Returns true if the size passed to pvalloc overflows when rounded to the next 65// multiple of PageSize. 66inline bool checkForPvallocOverflow(uptr Size, uptr PageSize) { 67 return roundUp(Size, PageSize) < Size; 68} 69 70} // namespace scudo 71 72#endif // SCUDO_CHECKS_H_ 73