Let sodium_malloc() and friends work on systems without protected memory.
On these systems, they become simple aliases for malloc() and friends. Canaries could be added, but adding too much bloat for these rare systems is probably not worth it, and malloc debuggers are better tools to use.
This commit is contained in:
parent
17932c782e
commit
26f87e266e
@ -172,6 +172,29 @@ sodium_hex2bin(unsigned char * const bin, const size_t bin_maxlen,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
_sodium_alloc_init(void)
|
||||
{
|
||||
#ifdef HAVE_ALIGNED_MALLOC
|
||||
# if defined(_SC_PAGESIZE)
|
||||
long page_size_ = sysconf(_SC_PAGESIZE);
|
||||
if (page_size_ > 0L) {
|
||||
page_size = (size_t) page_size_;
|
||||
}
|
||||
# elif defined(_WIN32)
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
page_size = (size_t) si.dwPageSize;
|
||||
# endif
|
||||
if (page_size < CANARY_SIZE || page_size < sizeof(size_t)) {
|
||||
abort(); /* LCOV_EXCL_LINE */
|
||||
}
|
||||
#endif
|
||||
randombytes_buf(canary, sizeof canary);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sodium_mlock(void * const addr, const size_t len)
|
||||
{
|
||||
@ -205,50 +228,14 @@ sodium_munlock(void * const addr, const size_t len)
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
_sodium_alloc_init(void)
|
||||
{
|
||||
#if defined(_SC_PAGESIZE)
|
||||
long page_size_ = sysconf(_SC_PAGESIZE);
|
||||
if (page_size_ > 0L) {
|
||||
page_size = (size_t) page_size_;
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
page_size = (size_t) si.dwPageSize;
|
||||
#else
|
||||
page_size = CANARY_SIZE;
|
||||
if (page_size < sizeof(size_t)) {
|
||||
page_size = sizeof(size_t);
|
||||
}
|
||||
#endif
|
||||
if (page_size < CANARY_SIZE || page_size < sizeof(size_t)) {
|
||||
abort(); /* LCOV_EXCL_LINE */
|
||||
}
|
||||
randombytes_buf(canary, sizeof canary);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline size_t
|
||||
_page_round(const size_t size)
|
||||
{
|
||||
const size_t page_mask = page_size - 1U;
|
||||
|
||||
return (size + page_mask) & ~page_mask;
|
||||
}
|
||||
|
||||
static int
|
||||
_mprotect_noaccess(void *ptr, size_t size)
|
||||
{
|
||||
#if defined(HAVE_MPROTECT) && defined(HAVE_PAGE_PROTECTION)
|
||||
#ifdef HAVE_MPROTECT
|
||||
return mprotect(ptr, size, PROT_NONE);
|
||||
#elif defined(_WIN32)
|
||||
{
|
||||
DWORD old;
|
||||
return -(VirtualProtect(ptr, size, PAGE_NOACCESS, &old) == 0);
|
||||
}
|
||||
DWORD old;
|
||||
return -(VirtualProtect(ptr, size, PAGE_NOACCESS, &old) == 0);
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@ -258,13 +245,11 @@ _mprotect_noaccess(void *ptr, size_t size)
|
||||
static int
|
||||
_mprotect_readonly(void *ptr, size_t size)
|
||||
{
|
||||
#if defined(HAVE_MPROTECT) && defined(HAVE_PAGE_PROTECTION)
|
||||
#ifdef HAVE_MPROTECT
|
||||
return mprotect(ptr, size, PROT_READ);
|
||||
#elif defined(_WIN32)
|
||||
{
|
||||
DWORD old;
|
||||
return -(VirtualProtect(ptr, size, PAGE_READONLY, &old) == 0);
|
||||
}
|
||||
DWORD old;
|
||||
return -(VirtualProtect(ptr, size, PAGE_READONLY, &old) == 0);
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
@ -274,66 +259,72 @@ _mprotect_readonly(void *ptr, size_t size)
|
||||
static int
|
||||
_mprotect_readwrite(void *ptr, size_t size)
|
||||
{
|
||||
#if defined(HAVE_MPROTECT) && defined(HAVE_PAGE_PROTECTION)
|
||||
#ifdef HAVE_MPROTECT
|
||||
return mprotect(ptr, size, PROT_READ | PROT_WRITE);
|
||||
#elif defined(_WIN32)
|
||||
{
|
||||
DWORD old;
|
||||
return -(VirtualProtect(ptr, size, PAGE_READWRITE, &old) == 0);
|
||||
}
|
||||
DWORD old;
|
||||
return -(VirtualProtect(ptr, size, PAGE_READWRITE, &old) == 0);
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_ALIGNED_MALLOC
|
||||
|
||||
static void
|
||||
_out_of_bounds(void)
|
||||
{
|
||||
#ifdef SIGSEGV
|
||||
# ifdef SIGSEGV
|
||||
raise(SIGSEGV);
|
||||
#elif defined(SIGKILL)
|
||||
# elif defined(SIGKILL)
|
||||
raise(SIGKILL);
|
||||
#endif
|
||||
# endif
|
||||
abort();
|
||||
} /* LCOV_EXCL_LINE */
|
||||
} /* LCOV_EXCL_LINE */
|
||||
|
||||
static inline size_t
|
||||
_page_round(const size_t size)
|
||||
{
|
||||
const size_t page_mask = page_size - 1U;
|
||||
|
||||
return (size + page_mask) & ~page_mask;
|
||||
}
|
||||
|
||||
static __attribute__((malloc)) unsigned char *
|
||||
_alloc_aligned(const size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
#if defined(MAP_ANON) && defined(HAVE_MMAP)
|
||||
# if defined(MAP_ANON) && defined(HAVE_MMAP)
|
||||
if ((ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
|
||||
MAP_ANON | MAP_PRIVATE | MAP_NOCORE, -1, 0)) == MAP_FAILED) {
|
||||
ptr = NULL; /* LCOV_EXCL_LINE */
|
||||
} /* LCOV_EXCL_LINE */
|
||||
#elif defined(HAVE_POSIX_MEMALIGN)
|
||||
# elif defined(HAVE_POSIX_MEMALIGN)
|
||||
if (posix_memalign(&ptr, page_size, size) != 0) {
|
||||
ptr = NULL; /* LCOV_EXCL_LINE */
|
||||
} /* LCOV_EXCL_LINE */
|
||||
#elif defined(_WIN32)
|
||||
# elif defined(_WIN32)
|
||||
ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
#elif !defined(HAVE_ALIGNED_MALLOC)
|
||||
# error Unsupported configuration
|
||||
#else
|
||||
# error Bug
|
||||
#endif
|
||||
# else
|
||||
# error Bug
|
||||
# endif
|
||||
return (unsigned char *) ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
_free_aligned(unsigned char * const ptr, const size_t size)
|
||||
{
|
||||
#if defined(MAP_ANON) && defined(HAVE_MMAP)
|
||||
# if defined(MAP_ANON) && defined(HAVE_MMAP)
|
||||
(void) munmap(ptr, size);
|
||||
#elif defined(HAVE_POSIX_MEMALIGN)
|
||||
# elif defined(HAVE_POSIX_MEMALIGN)
|
||||
free(ptr);
|
||||
#elif defined(_WIN32)
|
||||
# elif defined(_WIN32)
|
||||
VirtualFree(ptr, 0U, MEM_RELEASE);
|
||||
#else
|
||||
free(ptr);
|
||||
#endif
|
||||
# else
|
||||
# error Bug
|
||||
# endif
|
||||
}
|
||||
|
||||
static unsigned char *
|
||||
@ -352,6 +343,15 @@ _unprotected_ptr_from_user_ptr(const void *ptr)
|
||||
return (unsigned char *) unprotected_ptr_u;
|
||||
}
|
||||
|
||||
#endif /* HAVE_ALIGNED_MALLOC */
|
||||
|
||||
#ifndef HAVE_ALIGNED_MALLOC
|
||||
static __attribute__((malloc)) void *
|
||||
_sodium_malloc(const size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
#else
|
||||
static __attribute__((malloc)) void *
|
||||
_sodium_malloc(const size_t size)
|
||||
{
|
||||
@ -378,9 +378,9 @@ _sodium_malloc(const size_t size)
|
||||
}
|
||||
unprotected_ptr = base_ptr + page_size * 2U;
|
||||
_mprotect_noaccess(base_ptr + page_size, page_size);
|
||||
#ifndef HAVE_PAGE_PROTECTION
|
||||
# ifndef HAVE_PAGE_PROTECTION
|
||||
memcpy(unprotected_ptr + unprotected_size, canary, sizeof canary);
|
||||
#endif
|
||||
# endif
|
||||
_mprotect_noaccess(unprotected_ptr + unprotected_size, page_size);
|
||||
sodium_mlock(unprotected_ptr, unprotected_size);
|
||||
canary_ptr = unprotected_ptr + _page_round(size_with_canary) -
|
||||
@ -393,6 +393,7 @@ _sodium_malloc(const size_t size)
|
||||
|
||||
return user_ptr;
|
||||
}
|
||||
#endif /* !HAVE_ALIGNED_MALLOC */
|
||||
|
||||
__attribute__((malloc)) void *
|
||||
sodium_malloc(const size_t size)
|
||||
@ -421,6 +422,13 @@ sodium_allocarray(size_t count, size_t size)
|
||||
return sodium_malloc(total_size);
|
||||
}
|
||||
|
||||
#ifndef HAVE_ALIGNED_MALLOC
|
||||
void
|
||||
sodium_free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
#else
|
||||
void
|
||||
sodium_free(void *ptr)
|
||||
{
|
||||
@ -442,16 +450,27 @@ sodium_free(void *ptr)
|
||||
if (sodium_memcmp(canary_ptr, canary, sizeof canary) != 0) {
|
||||
_out_of_bounds();
|
||||
}
|
||||
#ifndef HAVE_PAGE_PROTECTION
|
||||
# ifndef HAVE_PAGE_PROTECTION
|
||||
if (sodium_memcmp(unprotected_ptr + unprotected_size,
|
||||
canary, sizeof canary) != 0) {
|
||||
_out_of_bounds();
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
sodium_munlock(unprotected_ptr, unprotected_size);
|
||||
_free_aligned(base_ptr, total_size);
|
||||
}
|
||||
#endif /* HAVE_ALIGNED_MALLOC */
|
||||
|
||||
#ifndef HAVE_PAGE_PROTECTION
|
||||
static int
|
||||
_sodium_mprotect(void *ptr, int (*cb)(void *ptr, size_t size))
|
||||
{
|
||||
(void) ptr;
|
||||
(void) cb;
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
static int
|
||||
_sodium_mprotect(void *ptr, int (*cb)(void *ptr, size_t size))
|
||||
{
|
||||
@ -465,6 +484,7 @@ _sodium_mprotect(void *ptr, int (*cb)(void *ptr, size_t size))
|
||||
|
||||
return cb(unprotected_ptr, unprotected_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
sodium_mprotect_noaccess(void *ptr)
|
||||
|
Loading…
Reference in New Issue
Block a user