blob: 2d5e1d0b53187e5abb8e7afda6b1fdc1c3d548a2 [file] [log] [blame]
#include <string.h>
#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include <setjmp.h>
#include "vtv_malloc.h"
#include "../../../include/vtv-change-permission.h"
volatile static int signal_count = 0;
sigjmp_buf before_segv;
unsigned int vtv_debug = 0;
static void
handler(int sig, siginfo_t *si, void *unused)
{
signal_count++;
/* You are not supposed to longjmp out of a signal handler but it seems
to work for this test case and it simplifies it */
siglongjmp(before_segv, 1);
}
/* Try to modify the memory pointed by "s" but dont actually change the values.
Assumes and verifies the memory to be modified is mprotected */
void mempoke(void * s, size_t n)
{
volatile char * p = (char *)s;
int ret;
signal_count = 0;
ret = sigsetjmp(before_segv, 1);
if (ret == 0)
p[0] = p[0];
assert(ret == 1 && signal_count == 1);
ret = sigsetjmp(before_segv, 1);
if (ret == 0)
p[n - 1] = p[n - 1];
assert(ret == 1 && signal_count == 2);
}
int main()
{
char * ptr;
int size;
/* Set up handler for SIGSEGV. */
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = handler;
if (sigaction(SIGSEGV, &sa, NULL) == -1)
assert(0);
/* Make the 'bookkeeping' vars read-write. */
__VLTChangePermission (__VLTP_READ_WRITE);
__vtv_malloc_init();
size = 10;
/* Verify not writable after unprotect */
__vtv_malloc_unprotect();
ptr = (char *)__vtv_malloc(size);
memset(ptr, 'a', size);
__vtv_malloc_protect();
mempoke(ptr, size);
__vtv_free(ptr);
/* verify not-writable after protect, unprotect */
__vtv_malloc_unprotect();
ptr = (char *)__vtv_malloc(size);
memset(ptr, 'a', size);
__vtv_malloc_protect();
__vtv_malloc_unprotect();
memset(ptr, 'a', size);
assert(ptr[size - 1] == 'a');
__vtv_malloc_protect();
assert(ptr[size - 1] == 'a');
mempoke(ptr,size);
__vtv_free(ptr);
/* Allocate a bunch of small objects.
Make sure the alignment is correct.
Verify data has not been corrupted.
Make sure the data cannot modified */
{
int s;
for (s = 3; s < 28; s += 3)
{
size = s;
{
int i;
#define ITERS 1000
char * ptrs[ITERS];
__vtv_malloc_unprotect();
for (i = 0; i < ITERS; i++)
{
ptr = (char *)__vtv_malloc(size);
assert(((long)ptr & VTV_ALIGNMENT_MASK) == 0);
memset(ptr, (i & 127), size);
assert(ptr[size - 1] == (i & 127));
ptrs[i] = ptr;
}
__vtv_malloc_protect();
for (i = 0; i < ITERS; i++)
mempoke(ptrs[i], size);
__vtv_malloc_unprotect();
for (i = 0; i < ITERS; i++)
__vtv_free(ptrs[i]);
__vtv_malloc_protect();
}
}
}
/* Allocate a bunch of medium size objects.
Make sure the alignment is correct.
Verify data has not been corrupted.
Try to modify the data to verify everything gets unprotected */
{
int s;
for (s = 501; s < 2500; s += 91)
{
size = s;
{
int i;
#define ITERS2 100
char * ptrs[ITERS2];
__vtv_malloc_unprotect();
for (i = 0; i < ITERS2; i++)
{
ptr = (char *)__vtv_malloc(size);
assert(((long)ptr & VTV_ALIGNMENT_MASK) == 0);
memset(ptr, i & 127, size);
assert(ptr[size - 1] == i & 127);
ptrs[i] = ptr;
}
__vtv_malloc_protect();
for (i = 0; i < ITERS2; i++)
mempoke(ptrs[i], size);
__vtv_malloc_unprotect();
for (i = 0; i < ITERS2; i++)
__vtv_free(ptrs[i]);
__vtv_malloc_protect();
}
}
}
/* Allocate a bunch of medium size objects. Make sure the alignment is correct */
{
int s;
for (s = 3001; s < 15000; s += 307)
{
size = s;
{
int i;
#define ITERS3 50
char * ptrs[ITERS3];
__vtv_malloc_unprotect();
for (i = 0; i < ITERS3; i++)
{
ptr = (char *)__vtv_malloc(size);
assert(((long)ptr & VTV_ALIGNMENT_MASK) == 0);
memset(ptr, i & 127, size);
assert(ptr[size - 1] == i & 127);
ptrs[i] = ptr;
}
__vtv_malloc_protect();
for (i = 0; i < ITERS3; i++)
mempoke(ptrs[i], size);
__vtv_malloc_unprotect();
for (i = 0; i < ITERS3; i++)
__vtv_free(ptrs[i]);
__vtv_malloc_protect();
}
}
}
return 0;
}