55 lines
1.7 KiB
C
55 lines
1.7 KiB
C
|
|
#include "akerror.h"
|
||
|
|
#include "err_capture.h"
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Regression test for the stack-trace buffer overflow. Each frame appended a
|
||
|
|
* line with snprintf, but passed the *full* buffer length as the size rather
|
||
|
|
* than the space remaining, and advanced the cursor by snprintf's would-be
|
||
|
|
* return value. A trace that filled the buffer therefore wrote past the end of
|
||
|
|
* stacktracebuf and ran the cursor out of bounds.
|
||
|
|
*
|
||
|
|
* We place a context in a struct with a guard region right after it, position
|
||
|
|
* the trace cursor near the end of the buffer, append one more frame, and
|
||
|
|
* require that nothing was written past the buffer and the cursor stayed in
|
||
|
|
* bounds.
|
||
|
|
*/
|
||
|
|
|
||
|
|
static struct {
|
||
|
|
akerr_ErrorContext ctx;
|
||
|
|
unsigned char guard[512];
|
||
|
|
} probe;
|
||
|
|
|
||
|
|
akerr_ErrorContext *append_frame(akerr_ErrorContext *e)
|
||
|
|
{
|
||
|
|
FAIL_RETURN(e, AKERR_VALUE,
|
||
|
|
"an error message long enough to overflow a nearly full stack trace buffer");
|
||
|
|
}
|
||
|
|
|
||
|
|
int main(void)
|
||
|
|
{
|
||
|
|
akerr_init();
|
||
|
|
|
||
|
|
memset(&probe, 0x00, sizeof(probe));
|
||
|
|
memset(probe.guard, 0xAA, sizeof(probe.guard));
|
||
|
|
|
||
|
|
akerr_ErrorContext *e = &probe.ctx;
|
||
|
|
e->refcount = 1;
|
||
|
|
/* Two bytes short of full: any real frame would overflow the old code. */
|
||
|
|
e->stacktracebufptr = probe.ctx.stacktracebuf
|
||
|
|
+ AKERR_MAX_ERROR_STACKTRACE_BUF_LENGTH - 2;
|
||
|
|
|
||
|
|
(void)append_frame(e);
|
||
|
|
|
||
|
|
/* Nothing may have been written past the end of stacktracebuf. */
|
||
|
|
for ( unsigned i = 0; i < sizeof(probe.guard); i++ ) {
|
||
|
|
AKERR_CHECK(probe.guard[i] == 0xAA);
|
||
|
|
}
|
||
|
|
/* The cursor must remain within the buffer. */
|
||
|
|
AKERR_CHECK(e->stacktracebufptr
|
||
|
|
<= probe.ctx.stacktracebuf + AKERR_MAX_ERROR_STACKTRACE_BUF_LENGTH);
|
||
|
|
|
||
|
|
fprintf(stderr, "err_stacktrace_bounds ok\n");
|
||
|
|
return 0;
|
||
|
|
}
|