Add sodium_{malloc,allocarray,free}() and sodium_mprotect_*()
ptr = sodium_malloc(size) returns a pointer from which exactly "size" bytes can be accessed. ptr = sodium_allocarray(count, size) allocates enough storage space for "count" pointers or scalars of unit size "size". In both cases, the region is immediately followed by a guard page. As a result, any attempt to access a memory location after ptr[size - 1] will immediately trigger a segmentation fault. The allocated region is mlock()ed and filled with 0xd0 bytes. A read-only page with the size, a guard page, as well as a canary are placed before the returned pointer. The canary is checked by sodium_free(); as a result, altering data right before ptr is likely to cause sodium_free() to kill the process. sodium_free() munlock()s the region and fills it with zeros before actually calling free(). sodium_mprotect_noaccess(), sodium_mprotect_readonly() and sodium_mprotect_readwrite() can be used to change the protection on the set of allocated pages. Reverting the protection to read+write is not required before calling sodium_free().
This commit is contained in:
parent
729a54f4a2
commit
473e1718cc
2
.gitignore
vendored
2
.gitignore
vendored
@ -100,6 +100,8 @@ test/default/shorthash
|
||||
test/default/sign
|
||||
test/default/sodium_core
|
||||
test/default/sodium_utils
|
||||
test/default/sodium_utils2
|
||||
test/default/sodium_utils3
|
||||
test/default/sodium_version
|
||||
test/default/stream
|
||||
test/default/stream2
|
||||
|
@ -187,6 +187,12 @@
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils.c">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils2.c">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils3.c">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_version.c">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
@ -118,6 +118,12 @@
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils.c">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils2.c">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils3.c">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_version.c">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
|
@ -187,6 +187,12 @@
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils.c">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils2.c">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils3.c">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_version.c">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
@ -118,6 +118,12 @@
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils.c">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils2.c">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils3.c">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_version.c">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
|
@ -187,6 +187,12 @@
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils.c">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils2.c">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils3.c">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_version.c">
|
||||
<ExcludedFromBuild>true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
@ -118,6 +118,12 @@
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils.c">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils2.c">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_utils3.c">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\..\test\default\sodium_version.c">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
|
@ -412,7 +412,7 @@ dnl Checks for functions and headers
|
||||
AS_IF([test "x$EMSCRIPTEN" = "x"],[
|
||||
AC_CHECK_FUNCS([arc4random arc4random_buf])
|
||||
])
|
||||
AC_CHECK_FUNCS([mlock explicit_bzero posix_memalign])
|
||||
AC_CHECK_FUNCS([mlock mprotect explicit_bzero posix_memalign])
|
||||
|
||||
AC_SUBST([LIBTOOL_EXTRA_FLAGS])
|
||||
|
||||
|
@ -43,6 +43,55 @@ int sodium_mlock(void * const addr, const size_t len);
|
||||
SODIUM_EXPORT
|
||||
int sodium_munlock(void * const addr, const size_t len);
|
||||
|
||||
/* WARNING: sodium_malloc() and sodium_allocarray() are not general-purpose
|
||||
* allocation functions.
|
||||
*
|
||||
* They return a pointer to a region filled with 0xd0 bytes and immediately
|
||||
* followed by a guard page.
|
||||
* As a result, accessing a single byte after the requested allocation size
|
||||
* will intentionally trigger a segmentation fault.
|
||||
*
|
||||
* A canary and an additional guard page placed before the beginning of the
|
||||
* region may also kill the process if a buffer underflow is detected.
|
||||
*
|
||||
* The memory layout is:
|
||||
* [unprotected region size (read only)][guard page (no access)][unprotected pages (read/write)][guard page (no access)]
|
||||
* With the layout of the unprotected pages being:
|
||||
* [optional padding][16-bytes canary][user region]
|
||||
*
|
||||
* However:
|
||||
* - These functions are significantly slower than standard functions
|
||||
* - Each allocation requires 3 or 4 additional pages
|
||||
* - The returned address will not be aligned if the allocation size is not
|
||||
* a multiple of the required alignment. For this reason, these functions
|
||||
* are designed to store data, such as secret keys and messages.
|
||||
* They should not be used to store pointers mixed with other types
|
||||
* in portable code unless extreme care is taken to ensure correct
|
||||
* pointers alignment.
|
||||
*/
|
||||
|
||||
SODIUM_EXPORT
|
||||
void *sodium_malloc(const size_t size);
|
||||
|
||||
SODIUM_EXPORT
|
||||
void *sodium_allocarray(size_t count, size_t size);
|
||||
|
||||
SODIUM_EXPORT
|
||||
void sodium_free(void *ptr);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_mprotect_noaccess(void *ptr);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_mprotect_readonly(void *ptr);
|
||||
|
||||
SODIUM_EXPORT
|
||||
int sodium_mprotect_readwrite(void *ptr);
|
||||
|
||||
/* -------- */
|
||||
|
||||
int _sodium_alloc_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "crypto_onetimeauth.h"
|
||||
#include "randombytes.h"
|
||||
#include "runtime.h"
|
||||
#include "utils.h"
|
||||
|
||||
static int initialized;
|
||||
|
||||
@ -17,6 +18,7 @@ sodium_init(void)
|
||||
return -1;
|
||||
}
|
||||
randombytes_stir();
|
||||
_sodium_alloc_init();
|
||||
initialized = 1;
|
||||
|
||||
return 0;
|
||||
|
@ -1,8 +1,10 @@
|
||||
#ifndef __STDC_WANT_LIB_EXT1__
|
||||
# define __STDC_WANT_LIB_EXT1__ 1
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@ -17,8 +19,32 @@
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# include <wincrypt.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define CANARY_SIZE 16U
|
||||
#define GARBAGE_VALUE 0xd0
|
||||
|
||||
#ifndef MAP_NOCORE
|
||||
# define MAP_NOCORE 0
|
||||
#endif
|
||||
#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS)
|
||||
# define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
#if defined(_WIN32) || defined(MAP_ANON) || defined(HAVE_POSIX_MEMALIGN)
|
||||
# define HAVE_ALIGNED_MALLOC
|
||||
#endif
|
||||
#if defined(HAVE_MPROTECT) && !(defined(PROT_NONE) && defined(PROT_READ) && defined(PROT_WRITE))
|
||||
# undef HAVE_MPROTECT
|
||||
#endif
|
||||
#if defined(HAVE_ALIGNED_MALLOC) && (defined(_WIN32) || defined(HAVE_MPROTECT))
|
||||
# define HAVE_PAGE_PROTECTION
|
||||
#endif
|
||||
|
||||
static size_t page_size;
|
||||
static unsigned char canary[CANARY_SIZE];
|
||||
|
||||
#ifdef HAVE_WEAK_SYMBOLS
|
||||
__attribute__((weak)) void
|
||||
__sodium_dummy_symbol_to_prevent_lto(void * const pnt, const size_t len)
|
||||
@ -174,3 +200,280 @@ sodium_munlock(void * const addr, const size_t len)
|
||||
return -1;
|
||||
#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;
|
||||
#endif
|
||||
if (page_size < CANARY_SIZE) {
|
||||
abort();
|
||||
}
|
||||
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)
|
||||
return mprotect(ptr, size, PROT_NONE);
|
||||
#elif defined(_WIN32)
|
||||
{
|
||||
DWORD old;
|
||||
return -(VirtualProtect(ptr, size, PAGE_NOACCESS, &old) == 0);
|
||||
}
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
_mprotect_readonly(void *ptr, size_t size)
|
||||
{
|
||||
#if defined(HAVE_MPROTECT) && defined(HAVE_PAGE_PROTECTION)
|
||||
return mprotect(ptr, size, PROT_READ);
|
||||
#elif defined(_WIN32)
|
||||
{
|
||||
DWORD old;
|
||||
return -(VirtualProtect(ptr, size, PAGE_READONLY, &old) == 0);
|
||||
}
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
_mprotect_readwrite(void *ptr, size_t size)
|
||||
{
|
||||
#if defined(HAVE_MPROTECT) && defined(HAVE_PAGE_PROTECTION)
|
||||
return mprotect(ptr, size, PROT_READ | PROT_WRITE);
|
||||
#elif defined(_WIN32)
|
||||
{
|
||||
DWORD old;
|
||||
return -(VirtualProtect(ptr, size, PAGE_READWRITE, &old) == 0);
|
||||
}
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
_out_of_bounds(void)
|
||||
{
|
||||
#ifdef SIGSEGV
|
||||
raise(SIGSEGV);
|
||||
#elif defined(SIGKILL)
|
||||
raise(SIGKILL);
|
||||
#endif
|
||||
abort();
|
||||
}
|
||||
|
||||
static __attribute__((malloc)) unsigned char *
|
||||
_alloc_aligned(const size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
#ifdef MAP_ANON
|
||||
if ((ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
|
||||
MAP_ANON | MAP_PRIVATE | MAP_NOCORE, -1, 0)) == MAP_FAILED) {
|
||||
ptr = NULL;
|
||||
}
|
||||
#elif defined(HAVE_POSIX_MEMALIGN)
|
||||
if (posix_memalign(&ptr, page_size, size) != 0) {
|
||||
ptr = NULL;
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
#elif !defined(HAVE_ALIGNED_MALLOC)
|
||||
ptr = malloc(size);
|
||||
#else
|
||||
# error Bug
|
||||
#endif
|
||||
return (unsigned char *) ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
_free_aligned(unsigned char * const ptr, const size_t size)
|
||||
{
|
||||
#ifdef MAP_ANON
|
||||
(void) munmap(ptr, size);
|
||||
#elif defined(HAVE_POSIX_MEMALIGN)
|
||||
free(ptr);
|
||||
#elif defined(_WIN32)
|
||||
VirtualFree(ptr, 0U, MEM_RELEASE);
|
||||
#else
|
||||
free(ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned char *
|
||||
_unprotected_ptr_from_user_ptr(const void *ptr)
|
||||
{
|
||||
uintptr_t unprotected_ptr_u;
|
||||
unsigned char *canary_ptr;
|
||||
unsigned char *unprotected_ptr;
|
||||
size_t page_mask;
|
||||
|
||||
canary_ptr = ((unsigned char *) ptr) - sizeof canary;
|
||||
page_mask = page_size - 1U;
|
||||
unprotected_ptr_u = ((uintptr_t) canary_ptr & (uintptr_t) ~page_mask);
|
||||
if (unprotected_ptr_u <= page_size * 2U) {
|
||||
abort();
|
||||
}
|
||||
return (unsigned char *) unprotected_ptr_u;
|
||||
}
|
||||
|
||||
static __attribute__((malloc)) void *
|
||||
_sodium_malloc(const size_t size)
|
||||
{
|
||||
void *user_ptr;
|
||||
unsigned char *base_ptr;
|
||||
unsigned char *canary_ptr;
|
||||
unsigned char *unprotected_ptr;
|
||||
size_t page_mask;
|
||||
size_t size_with_canary;
|
||||
size_t total_size;
|
||||
size_t unprotected_size;
|
||||
|
||||
if (size >= SIZE_MAX - page_size * 4U) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
if (page_size <= sizeof canary || page_size < sizeof unprotected_size) {
|
||||
abort();
|
||||
}
|
||||
size_with_canary = (sizeof canary) + size;
|
||||
unprotected_size = _page_round(size_with_canary);
|
||||
total_size = page_size + page_size + unprotected_size + page_size;
|
||||
if ((base_ptr = _alloc_aligned(total_size)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
unprotected_ptr = base_ptr + page_size * 2U;
|
||||
_mprotect_noaccess(base_ptr + page_size, page_size);
|
||||
#ifndef HAVE_PAGE_PROTECTION
|
||||
memcpy(unprotected_ptr + unprotected_size, canary, sizeof canary);
|
||||
#endif
|
||||
_mprotect_noaccess(unprotected_ptr + unprotected_size, page_size);
|
||||
sodium_mlock(unprotected_ptr, unprotected_size);
|
||||
page_mask = page_size - 1U;
|
||||
canary_ptr = unprotected_ptr + _page_round(size_with_canary) -
|
||||
size_with_canary;
|
||||
user_ptr = canary_ptr + sizeof canary;
|
||||
memcpy(canary_ptr, canary, sizeof canary);
|
||||
memcpy(base_ptr, &unprotected_size, sizeof unprotected_size);
|
||||
_mprotect_readonly(base_ptr, page_size);
|
||||
assert(_unprotected_ptr_from_user_ptr(user_ptr) == unprotected_ptr);
|
||||
|
||||
return user_ptr;
|
||||
}
|
||||
|
||||
__attribute__((malloc)) void *
|
||||
sodium_malloc(const size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
if ((ptr = _sodium_malloc(size)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memset(ptr, (int) GARBAGE_VALUE, size);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
__attribute__((malloc)) void *
|
||||
sodium_allocarray(size_t count, size_t size)
|
||||
{
|
||||
size_t total_size;
|
||||
|
||||
if (size >= SIZE_MAX / count) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
total_size = count * size;
|
||||
|
||||
return sodium_malloc(total_size);
|
||||
}
|
||||
|
||||
void
|
||||
sodium_free(void *ptr)
|
||||
{
|
||||
unsigned char *base_ptr;
|
||||
unsigned char *canary_ptr;
|
||||
unsigned char *unprotected_ptr;
|
||||
size_t total_size;
|
||||
size_t unprotected_size;
|
||||
|
||||
if (ptr == NULL) {
|
||||
return;
|
||||
}
|
||||
canary_ptr = ((unsigned char *) ptr) - sizeof canary;
|
||||
if (sodium_memcmp(canary_ptr, canary, sizeof canary) != 0) {
|
||||
_out_of_bounds();
|
||||
}
|
||||
unprotected_ptr = _unprotected_ptr_from_user_ptr(ptr);
|
||||
base_ptr = unprotected_ptr - page_size * 2U;
|
||||
memcpy(&unprotected_size, base_ptr, sizeof unprotected_size);
|
||||
total_size = page_size + page_size + unprotected_size + page_size;
|
||||
_mprotect_readwrite(base_ptr, total_size);
|
||||
#ifndef HAVE_PAGE_PROTECTION
|
||||
if (sodium_memcmp(unprotected_ptr + unprotected_size,
|
||||
canary, sizeof canary) != 0) {
|
||||
_out_of_bounds();
|
||||
}
|
||||
#endif
|
||||
sodium_munlock(unprotected_ptr, unprotected_size);
|
||||
_free_aligned(base_ptr, total_size);
|
||||
}
|
||||
|
||||
static int
|
||||
_sodium_mprotect(void *ptr, int (*cb)(void *ptr, size_t size))
|
||||
{
|
||||
unsigned char *base_ptr;
|
||||
unsigned char *unprotected_ptr;
|
||||
size_t unprotected_size;
|
||||
|
||||
unprotected_ptr = _unprotected_ptr_from_user_ptr(ptr);
|
||||
base_ptr = unprotected_ptr - page_size * 2U;
|
||||
memcpy(&unprotected_size, base_ptr, sizeof unprotected_size);
|
||||
|
||||
return cb(unprotected_ptr, unprotected_size);
|
||||
}
|
||||
|
||||
int
|
||||
sodium_mprotect_noaccess(void *ptr)
|
||||
{
|
||||
return _sodium_mprotect(ptr, _mprotect_noaccess);
|
||||
}
|
||||
|
||||
int
|
||||
sodium_mprotect_readonly(void *ptr)
|
||||
{
|
||||
return _sodium_mprotect(ptr, _mprotect_readonly);
|
||||
}
|
||||
|
||||
int
|
||||
sodium_mprotect_readwrite(void *ptr)
|
||||
{
|
||||
return _sodium_mprotect(ptr, _mprotect_readwrite);
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ EXTRA_DIST = \
|
||||
sign.exp \
|
||||
sodium_core.exp \
|
||||
sodium_utils.exp \
|
||||
sodium_utils2.exp \
|
||||
sodium_utils3.exp \
|
||||
sodium_version.exp \
|
||||
stream.exp \
|
||||
stream2.exp \
|
||||
@ -104,6 +106,8 @@ DISTCLEANFILES = \
|
||||
sign.res \
|
||||
sodium_core.res \
|
||||
sodium_utils.res \
|
||||
sodium_utils2.res \
|
||||
sodium_utils3.res \
|
||||
sodium_version.res \
|
||||
stream.res \
|
||||
stream2.res \
|
||||
@ -167,6 +171,8 @@ TESTS_TARGETS = \
|
||||
sign \
|
||||
sodium_core \
|
||||
sodium_utils \
|
||||
sodium_utils2 \
|
||||
sodium_utils3 \
|
||||
sodium_version \
|
||||
stream \
|
||||
stream2 \
|
||||
@ -322,6 +328,12 @@ sodium_core_LDADD = $(TESTS_LDADD)
|
||||
sodium_utils_SOURCE = cmptest.h sodium_utils.c
|
||||
sodium_utils_LDADD = $(TESTS_LDADD)
|
||||
|
||||
sodium_utils2_SOURCE = cmptest.h sodium_utils2.c
|
||||
sodium_utils2_LDADD = $(TESTS_LDADD)
|
||||
|
||||
sodium_utils3_SOURCE = cmptest.h sodium_utils3.c
|
||||
sodium_utils3_LDADD = $(TESTS_LDADD)
|
||||
|
||||
sodium_version_SOURCE = cmptest.h sodium_version.c
|
||||
sodium_version_LDADD = $(TESTS_LDADD)
|
||||
|
||||
|
70
test/default/sodium_utils2.c
Normal file
70
test/default/sodium_utils2.c
Normal file
@ -0,0 +1,70 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TEST_NAME "sodium_utils2"
|
||||
#include "cmptest.h"
|
||||
|
||||
static void
|
||||
segv_handler(int sig)
|
||||
{
|
||||
printf("Intentional segfault / bus error caught\n");
|
||||
printf("OK\n");
|
||||
#ifdef SIGSEGV
|
||||
signal(SIGSEGV, SIG_DFL);
|
||||
#endif
|
||||
#ifdef SIGBUS
|
||||
signal(SIGBUS, SIG_DFL);
|
||||
#endif
|
||||
#ifdef SIGABRT
|
||||
signal(SIGABRT, SIG_DFL);
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
void *buf;
|
||||
size_t size;
|
||||
unsigned int i;
|
||||
|
||||
if (sodium_allocarray(SIZE_MAX / 2U + 1U, SIZE_MAX / 2U) != NULL) {
|
||||
return 1;
|
||||
}
|
||||
sodium_free(sodium_malloc(0U));
|
||||
sodium_free(NULL);
|
||||
for (i = 0U; i < 10000U; i++) {
|
||||
size = randombytes_uniform(100000U);
|
||||
buf = sodium_malloc(size);
|
||||
memset(buf, i, size);
|
||||
sodium_mprotect_readonly(buf);
|
||||
sodium_free(buf);
|
||||
}
|
||||
printf("OK\n");
|
||||
|
||||
#ifdef SIGSEGV
|
||||
signal(SIGSEGV, segv_handler);
|
||||
#endif
|
||||
#ifdef SIGBUS
|
||||
signal(SIGBUS, segv_handler);
|
||||
#endif
|
||||
#ifdef SIGABRT
|
||||
signal(SIGABRT, segv_handler);
|
||||
#endif
|
||||
size = randombytes_uniform(100000U);
|
||||
buf = sodium_malloc(size);
|
||||
sodium_mprotect_readonly(buf);
|
||||
sodium_mprotect_readwrite(buf);
|
||||
sodium_memzero(((unsigned char *) buf) + size, 1U);
|
||||
sodium_mprotect_noaccess(buf);
|
||||
sodium_free(buf);
|
||||
printf("Overflow not caught\n");
|
||||
|
||||
return 0;
|
||||
}
|
3
test/default/sodium_utils2.exp
Normal file
3
test/default/sodium_utils2.exp
Normal file
@ -0,0 +1,3 @@
|
||||
OK
|
||||
Intentional segfault / bus error caught
|
||||
OK
|
55
test/default/sodium_utils3.c
Normal file
55
test/default/sodium_utils3.c
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TEST_NAME "sodium_utils3"
|
||||
#include "cmptest.h"
|
||||
|
||||
static void
|
||||
segv_handler(int sig)
|
||||
{
|
||||
printf("Intentional segfault / bus error caught\n");
|
||||
printf("OK\n");
|
||||
#ifdef SIGSEGV
|
||||
signal(SIGSEGV, SIG_DFL);
|
||||
#endif
|
||||
#ifdef SIGBUS
|
||||
signal(SIGBUS, SIG_DFL);
|
||||
#endif
|
||||
#ifdef SIGABRT
|
||||
signal(SIGABRT, SIG_DFL);
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
void *buf;
|
||||
size_t size;
|
||||
|
||||
#ifdef SIGSEGV
|
||||
signal(SIGSEGV, segv_handler);
|
||||
#endif
|
||||
#ifdef SIGBUS
|
||||
signal(SIGBUS, segv_handler);
|
||||
#endif
|
||||
#ifdef SIGABRT
|
||||
signal(SIGABRT, segv_handler);
|
||||
#endif
|
||||
size = randombytes_uniform(100000U);
|
||||
buf = sodium_malloc(size);
|
||||
sodium_mprotect_noaccess(buf);
|
||||
sodium_mprotect_readwrite(buf);
|
||||
sodium_memzero(((unsigned char *) buf) - 8, 8U);
|
||||
sodium_mprotect_readonly(buf);
|
||||
sodium_free(buf);
|
||||
printf("Underflow not caught\n");
|
||||
|
||||
return 0;
|
||||
}
|
2
test/default/sodium_utils3.exp
Normal file
2
test/default/sodium_utils3.exp
Normal file
@ -0,0 +1,2 @@
|
||||
Intentional segfault / bus error caught
|
||||
OK
|
Loading…
Reference in New Issue
Block a user