Skip to content

Commit

Permalink
Ensure posix_memalign() is never called with bad alignment values
Browse files Browse the repository at this point in the history
  • Loading branch information
biojppm committed Jul 6, 2024
1 parent f739367 commit 0ae9e6d
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 14 deletions.
3 changes: 2 additions & 1 deletion changelog/current.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@

- Fix [rapidyaml#445](https://github.com/biojppm/biojppm/pull/445): Amalgamate: fix include of `<charconv>`.
- Amalgamate: fix include of `<charconv>` (see [rapidyaml#445](https://github.com/biojppm/biojppm/pull/445)).
- Add `C4_MINGW` ([PR#139](https://github.com/biojppm/c4core/pull/139))
- Annotate `c4::handle_error()` with `[[noreturn]]` ([PR#137](https://github.com/biojppm/c4core/pull/137))
- Add `bool from_chars(csubstr s, fmt::overflow_checked_<T> *wrapper)`. There was already a function receiving `&wrapper`, but `*wrapper` was missing for use with generic code.
- Ensure `posix_memalign()` is never called with bad alignment values ([PR#138](https://github.com/biojppm/c4core/pull/138))
- Update fast_float to v6.1.1 ([PR#136](https://github.com/biojppm/c4core/pull/136))


Expand Down
25 changes: 12 additions & 13 deletions src/c4/memory_resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ void afree_impl(void *ptr)

void* aalloc_impl(size_t size, size_t alignment)
{
// alignment must be nonzero and a power of 2
C4_CHECK(alignment > 0 && (alignment & (alignment - 1u)) == 0);
// NOTE: alignment needs to be sized in multiples of sizeof(void*)
if(C4_UNLIKELY(alignment < sizeof(void*)))
{
alignment = sizeof(void*);
}
static_assert((sizeof(void*) & (sizeof(void*)-1u)) == 0, "sizeof(void*) must be a power of 2");
C4_CHECK(((alignment & (sizeof(void*) - 1u))) == 0u);
void *mem;
#if defined(C4_WIN) || defined(C4_XBOX)
mem = ::_aligned_malloc(size, alignment);
Expand All @@ -48,21 +57,11 @@ void* aalloc_impl(size_t size, size_t alignment)
mem = memalign(alignment, size);
C4_CHECK(mem != nullptr || size == 0);
#elif defined(C4_POSIX) || defined(C4_IOS) || defined(C4_MACOS)
// NOTE: alignment needs to be sized in multiples of sizeof(void*)
size_t amult = alignment;
if(C4_UNLIKELY(alignment < sizeof(void*)))
{
amult = sizeof(void*);
}
int ret = ::posix_memalign(&mem, amult, size);
int ret = ::posix_memalign(&mem, alignment, size);
if(C4_UNLIKELY(ret))
{
if(ret == EINVAL)
{
C4_ERROR("The alignment argument %zu was not a power of two, "
"or was not a multiple of sizeof(void*)", alignment);
}
else if(ret == ENOMEM)
C4_ASSERT(ret != EINVAL); // this was already handled above
if(ret == ENOMEM)
{
C4_ERROR("There was insufficient memory to fulfill the "
"allocation request of %zu bytes (alignment=%lu)", size, size);
Expand Down

0 comments on commit 0ae9e6d

Please sign in to comment.