mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-08 08:26:14 +00:00
74 lines
1.9 KiB
C
74 lines
1.9 KiB
C
/* Reproduces bug 321960 (based on test from Daniel Stodden).
|
|
At least on Ubuntu 12 and 13, causes invalid write errors
|
|
in __yell or the memset call (due to some part of the main
|
|
stack being marked as not addressable in memcheck).
|
|
Bug seems extremely sensitive to initial conditions:
|
|
Depending on the size of the env, bug is triggered or not.
|
|
Also, a high nr of threads in thr[] is needed to get
|
|
the problem. */
|
|
#include <pthread.h>
|
|
#include <alloca.h>
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
|
|
void *
|
|
nop(void *nil)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
__yell(void)
|
|
{
|
|
char buf[256];
|
|
memset(buf, 0, sizeof(buf));
|
|
}
|
|
|
|
/* Without argument, executes once.
|
|
Otherwise first arg indicates nr of times the process will exec
|
|
itself, each time increasing the size of the environment
|
|
by about 50 characters. */
|
|
int main(int argc, char **argv, char** envp)
|
|
{
|
|
pthread_t thr[50];
|
|
int i, err;
|
|
|
|
for (i = 0; i < sizeof(thr) / sizeof(*thr); i++) {
|
|
err = pthread_create(&thr[i], NULL, nop, NULL);
|
|
assert(!err);
|
|
}
|
|
|
|
alloca(4096);
|
|
__yell();
|
|
|
|
for (i = 0; i < sizeof(thr) / sizeof(*thr); i++)
|
|
pthread_join(thr[i], NULL);
|
|
|
|
if ( argc == 2 && atoi(argv[1]) > 0) {
|
|
/* exec ourselves with some more env */
|
|
char** new_env;
|
|
char more_env[100];
|
|
char n[10];
|
|
int j;
|
|
|
|
sprintf(more_env, "N%d=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ", atoi(argv[1]));
|
|
for (j = 0; envp[j]; j++)
|
|
;
|
|
new_env = malloc((j+2) * sizeof(char*));
|
|
assert (new_env != NULL);
|
|
for (i = 0; i < j; i++)
|
|
new_env[i] = envp[i];
|
|
new_env[i++] = more_env;
|
|
new_env[i++] = NULL;
|
|
assert(i == j+2);
|
|
sprintf (n, "%d", atoi(argv[1]) - 1);
|
|
// system ("env | wc");
|
|
execle(argv[0], argv[0], n, (char *) NULL, new_env);
|
|
assert(0);
|
|
} else
|
|
return 0;
|
|
}
|