/* Copyright (c) 2014-2018 Dovecot authors, see the included COPYING file */
#include "test-lib.h"
#include "data-stack.h"
static void test_ds_buffers(void)
{
test_begin("data-stack buffer growth");
T_BEGIN {
size_t i;
unsigned char *p;
while (left < 10000) {
}
p = t_buffer_get(1);
p[0] = 1;
for (i = 2; i <= left; i++) {
/* grow it */
test_assert_idx(p == p2, i);
p[i-1] = i;
}
/* now fix it permanently */
} T_END;
test_end();
test_begin("data-stack buffer interruption");
T_BEGIN {
void *b = t_buffer_get(1000);
void *a = t_malloc_no0(1);
test_assert(a == b); /* expected, not guaranteed */
test_assert(b2 != b);
} T_END;
test_end();
test_begin("data-stack buffer with reallocs");
T_BEGIN {
size_t i;
unsigned char *p, *p2;
t_malloc_no0(i);
/* The most useful idx for the assert is 'left' */
} T_END;
} T_END;
test_end();
}
static void test_ds_realloc()
{
test_begin("data-stack realloc");
T_BEGIN {
size_t i;
unsigned char *p;
while (left < 10000) {
}
p = t_malloc_no0(1);
p[0] = 1;
for (i = 2; i <= left; i++) {
/* grow it */
test_assert_idx(t_try_realloc(p, i), i);
p[i-1] = i;
}
} T_END;
test_end();
}
{
int i;
char **ps;
int try_fails = 0;
t_buffer_alloc(sizeof(char *) * number);
for (i = 0; i < number; i++) {
if (!re) {
try_fails++;
}
/* drop our own canaries */
}
/* Do not expect a high failure rate from t_try_realloc */
/* Now recurse... */
if(depth>0)
/* Test our canaries are still intact */
for (i = 0; i < number; i++) {
}
}
{
int i;
test_begin("data-stack recursive");
} T_END;
test_end();
}
void test_data_stack(void)
{
}
{
#ifdef DEBUG
/* If we abort, then we'll be left with a dangling t_push()
keep a record of our temporary stack id, so we can clean up. */
static unsigned char undo_data;
if (stage != 0) {
/* Presume that we need to clean up from the prior test:
undo the evil write, then we will be able to t_pop cleanly,
and finally we can end the test stanza. */
return FATAL_TEST_ABORT; /* abort, things are messed up with t_pop */
/* t_pop mustn't abort, that would cause recursion */
return FATAL_TEST_ABORT; /* abort, things are messed up with us */
test_end();
}
switch(stage) {
case 0: {
unsigned char *p;
test_begin("fatal data-stack underrun");
int seek = 0;
/* Seek back for the canary, don't assume endianness */
while(seek > -60 &&
seek--;
if (seek <= -60)
return FATAL_TEST_ABORT; /* abort, couldn't find header */
*undo_ptr = '*';
/* t_malloc_no0 will panic block header corruption */
test_expect_fatal_string("Corrupted data stack canary");
(void)t_malloc_no0(10);
return FATAL_TEST_FAILURE;
}
case 1: case 2: {
t_id = t_push_named(stage == 1 ? "fatal t_malloc_no0 overrun first" : "fatal t_malloc_no0 overrun far");
unsigned char *p = t_malloc_no0(10);
*undo_ptr = '*';
/* t_pop will now fail */
test_expect_fatal_string("buffer overflow");
return FATAL_TEST_FAILURE;
}
case 3: case 4: {
unsigned char *p = t_buffer_get(10);
*undo_ptr = '*';
/* t_pop will now fail */
test_expect_fatal_string("buffer overflow");
return FATAL_TEST_FAILURE;
}
default:
return FATAL_TEST_FINISHED;
}
#else
#endif
}