Hi.

I encountered a memory corruption bug in libtcc. It seems to put
random data into random data structures of the program that are
unrelated to libtcc. I've been able to reproduce the bug using a
simple test-case, which is attached. The output of what I get when I
run the test-case is also attached.

I encountered the bug on a x86_64 linux system, and the test case was
compiled using gcc 4.6.2. It was linked against the latest git version
of tcc. What optimization flag you use with gcc seem to affect how the
bug manifests itself. The output I've attached is what I get when I
compile using -O2, if I compile using -O1 I get a segfault instead.

I can't debug this any further due to lack of knowledge of tcc
internals, but hopefully one of you can figure it out from this. If
you need any more information from me let me know.

Regards

Andreas Eriksson
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This works fine: A
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: @
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: @
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: @
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: @
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up:  
This time its messed up: @
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: "
This time its messed up: @
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: $
This time its messed up: @
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: Ą
This time its messed up: 
This time its messed up: @
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: ­
This time its messed up: ž
This time its messed up: Č
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: 
This time its messed up: #
This time its messed up: ³
This time its messed up: «
#include <stdio.h>
#include <stdlib.h>
#include <libtcc.h>

int main(void) {
	char *storage;
	char *program;
	TCCState *tccstate;
	double (*run_code)(double*);
	double result;
	int i;
	double numbers[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

	storage = malloc(1000 * sizeof(char*));
	if (storage == NULL) {
		printf("Malloc failed\n");
		exit(1);
	}
	for (i=0; i<100; ++i) {
		storage[i] = 'A';
	}

	program = malloc(1000 * sizeof(char*));
	if (program == NULL) {
		printf("Malloc failed\n");
		exit(1);
	}
	sprintf(program, "double divide(double x, double y) {\nif (y == 0) { return 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.000000; } else { return x / y; }\n}\ndouble min(double x, double y) {\nif (x < y) { return x; } else { return y; }\n}\ndouble max(double x, double y) {\nif (x > y) { return x; } else { return y; }\n}\ndouble run_code(double *data) {\nreturn (min(data[3], min((-562.222050 + data[5]), -459.583080)) - -339.751960);\n}"); // nothing in this program should be able to touch the memory of anything else

	tccstate = tcc_new();
	if (!tccstate) {
		printf("ERROR: Couldn't create TCC state\n");
		exit(1);
	}
	tcc_set_output_type(tccstate, TCC_OUTPUT_MEMORY);
	if (tcc_compile_string(tccstate, program) < 0) {
		printf("ERROR when compiling TCC string\n");
		exit(1);
	}
	if (tcc_relocate(tccstate) < 0) {
		printf("ERROR: unable to relocate tcc code\n");
		exit(1);
	}
	run_code = tcc_get_symbol(tccstate, "run_code");
	if (!run_code) {
		printf("ERROR: Did not get function pointer from tcc\n");
		exit(1);
	}

	free(program);

	for(i=0; i<100; ++i) {
		printf("This works fine: %c\n", storage[i]);
	}
	result = run_code(numbers);
	for(i=0; i<100; ++i) {
		printf("This time its messed up: %c\n", storage[i]);
	}

	//free(storage); // this should work, but produces a "invalid pointer" error from glibc
	return 0;
}
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to