diff options
author | Alex Shlyapnikov <alekseys@google.com> | 2017-07-14 21:17:16 +0000 |
---|---|---|
committer | Alex Shlyapnikov <alekseys@google.com> | 2017-07-14 21:17:16 +0000 |
commit | e474b1c4087b0b9f9f2edaa514a256c42f345db6 (patch) | |
tree | 98623766693e2c815dd59c6fe88f5afad3f5d1dd | |
parent | 12d16901ebba5bc7185298e9efa3c4d265fa52ce (diff) |
[Sanitizers] Scudo allocator set errno on failure.
Summary:
Set proper errno code on alloction failure and change pvalloc and
posix_memalign implementation to satisfy their man-specified
requirements.
Reviewers: cryptoad
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D35429
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@308053 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/scudo/scudo_allocator.cpp | 50 | ||||
-rw-r--r-- | test/scudo/memalign.cpp | 8 |
2 files changed, 33 insertions, 25 deletions
diff --git a/lib/scudo/scudo_allocator.cpp b/lib/scudo/scudo_allocator.cpp index 057db6281..102d1d0df 100644 --- a/lib/scudo/scudo_allocator.cpp +++ b/lib/scudo/scudo_allocator.cpp @@ -20,9 +20,9 @@ #include "scudo_utils.h" #include "sanitizer_common/sanitizer_allocator_interface.h" +#include "sanitizer_common/sanitizer_errno.h" #include "sanitizer_common/sanitizer_quarantine.h" -#include <errno.h> #include <string.h> namespace __scudo { @@ -638,8 +638,14 @@ void ScudoThreadContext::commitBack() { Instance.commitBack(this); } +INLINE void *checkPtr(void *Ptr) { + if (UNLIKELY(!Ptr)) + errno = errno_ENOMEM; + return Ptr; +} + void *scudoMalloc(uptr Size, AllocType Type) { - return Instance.allocate(Size, MinAlignment, Type); + return checkPtr(Instance.allocate(Size, MinAlignment, Type)); } void scudoFree(void *Ptr, AllocType Type) { @@ -652,54 +658,56 @@ void scudoSizedFree(void *Ptr, uptr Size, AllocType Type) { void *scudoRealloc(void *Ptr, uptr Size) { if (!Ptr) - return Instance.allocate(Size, MinAlignment, FromMalloc); + return checkPtr(Instance.allocate(Size, MinAlignment, FromMalloc)); if (Size == 0) { Instance.deallocate(Ptr, 0, FromMalloc); return nullptr; } - return Instance.reallocate(Ptr, Size); + return checkPtr(Instance.reallocate(Ptr, Size)); } void *scudoCalloc(uptr NMemB, uptr Size) { - return Instance.calloc(NMemB, Size); + return checkPtr(Instance.calloc(NMemB, Size)); } void *scudoValloc(uptr Size) { - return Instance.allocate(Size, GetPageSizeCached(), FromMemalign); + return checkPtr(Instance.allocate(Size, GetPageSizeCached(), FromMemalign)); } void *scudoPvalloc(uptr Size) { uptr PageSize = GetPageSizeCached(); - Size = RoundUpTo(Size, PageSize); - if (Size == 0) { - // pvalloc(0) should allocate one page. - Size = PageSize; - } - return Instance.allocate(Size, PageSize, FromMemalign); + // pvalloc(0) should allocate one page. + Size = Size ? RoundUpTo(Size, PageSize) : PageSize; + return checkPtr(Instance.allocate(Size, PageSize, FromMemalign)); } void *scudoMemalign(uptr Alignment, uptr Size) { - if (UNLIKELY(!IsPowerOfTwo(Alignment))) + if (UNLIKELY(!IsPowerOfTwo(Alignment))) { + errno = errno_EINVAL; return ScudoAllocator::FailureHandler::OnBadRequest(); - return Instance.allocate(Size, Alignment, FromMemalign); + } + return checkPtr(Instance.allocate(Size, Alignment, FromMemalign)); } int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size) { if (UNLIKELY(!IsPowerOfTwo(Alignment) || (Alignment % sizeof(void *)) != 0)) { - *MemPtr = ScudoAllocator::FailureHandler::OnBadRequest(); - return EINVAL; + ScudoAllocator::FailureHandler::OnBadRequest(); + return errno_EINVAL; } - *MemPtr = Instance.allocate(Size, Alignment, FromMemalign); - if (!*MemPtr) - return ENOMEM; + void *Ptr = Instance.allocate(Size, Alignment, FromMemalign); + if (!Ptr) + return errno_ENOMEM; + *MemPtr = Ptr; return 0; } void *scudoAlignedAlloc(uptr Alignment, uptr Size) { // Alignment must be a power of 2, Size must be a multiple of Alignment. - if (UNLIKELY(!IsPowerOfTwo(Alignment) || (Size & (Alignment - 1)) != 0)) + if (UNLIKELY(!IsPowerOfTwo(Alignment) || (Size & (Alignment - 1)) != 0)) { + errno = errno_EINVAL; return ScudoAllocator::FailureHandler::OnBadRequest(); - return Instance.allocate(Size, Alignment, FromMalloc); + } + return checkPtr(Instance.allocate(Size, Alignment, FromMalloc)); } uptr scudoMallocUsableSize(void *Ptr) { diff --git a/test/scudo/memalign.cpp b/test/scudo/memalign.cpp index 856128f24..82c54af8b 100644 --- a/test/scudo/memalign.cpp +++ b/test/scudo/memalign.cpp @@ -65,15 +65,15 @@ int main(int argc, char **argv) // Size is not a multiple of alignment. p = aligned_alloc(alignment, size >> 1); assert(!p); - p = (void *)0x42UL; + void *p_unchanged = (void *)0x42UL; + p = p_unchanged; // Alignment is not a power of 2. err = posix_memalign(&p, 3, size); - assert(!p); + assert(p == p_unchanged); assert(err == EINVAL); - p = (void *)0x42UL; // Alignment is a power of 2, but not a multiple of size(void *). err = posix_memalign(&p, 2, size); - assert(!p); + assert(p == p_unchanged); assert(err == EINVAL); } return 0; |