[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 llvm-svn: 308053
This commit is contained in:
parent
e4b97459f1
commit
df18cbba55
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue