History

tccrun: Mark argv area as valid for bcheck

On my x86_64 box in i386 mode with address space randomization turned off, I've observed the following: tests$ ../tcc -B.. -b -run boundtest.c 1 Runtime error: dereferencing invalid pointer boundtest.c:222: at 0x808da73 main() With diagnostic patch (like in efd9d92b "lib/bcheck: Don't assume heap goes right after bss") and bcheck traces for __bound_new_region, __bound_ptr_indir, etc... here is how the program run looks like: >>> TCC etext: 0x8067ed8 edata: 0x807321d end: 0x807d95c brk: 0x807e000 stack: 0xffffd0b4 &errno: 0xf7dbd688 mark_invalid 0xfff80000 - (nil) mark_invalid 0x80fa000 - 0x100fa000 new 808fdb0 808ff40 101 101 fd0 ff0 new 808ff44 808ff48 101 101 ff0 ff0 new 808ff49 8090049 101 101 ff0 1000 new 808fd20 808fd29 101 101 fd0 fd0 new 808fd2c 808fd6c 101 101 fd0 fd0 new 808fd6d 808fda0 101 101 fd0 fd0 E: __bound_ptr_indir4(0xffffd184, 0x4) Runtime error: dereferencing invalid pointer boundtest.c:222: at 0x808ea83 main() So we are accessing something on stack, above stack entry for compiled main. Investigating with gdb shows that this is argv: tests$ gdb ../tcc Reading symbols from /home/kirr/src/tools/tinycc/tcc...done. (gdb) set args -B.. -b -run boundtest.c 1 (gdb) r Starting program: /home/kirr/src/tools/tinycc/tests/../tcc -B.. -b -run boundtest.c 1 warning: Could not load shared library symbols for linux-gate.so.1. Do you need "set solib-search-path" or "set sysroot"? >>> TCC etext: 0x8067ed8 edata: 0x807321d end: 0x807d95c brk: 0x807e000 stack: 0xffffd074 &errno: 0xf7dbd688 mark_invalid 0xfff80000 - (nil) mark_invalid 0x80fa000 - 0x100fa000 new 808fdb0 808ff40 101 101 fd0 ff0 new 808ff44 808ff48 101 101 ff0 ff0 new 808ff49 8090049 101 101 ff0 1000 new 808fd20 808fd29 101 101 fd0 fd0 new 808fd2c 808fd6c 101 101 fd0 fd0 new 808fd6d 808fda0 101 101 fd0 fd0 E: __bound_ptr_indir4(0xffffd144, 0x4) Program received signal SIGSEGV, Segmentation fault. 0x0808ea83 in ?? () (gdb) bt #0 0x0808ea83 in ?? () #1 0x080639b3 in tcc_run (s1=s1@entry=0x807e008, argc=argc@entry=2, argv=argv@entry=0xffffd144) at tccrun.c:132 #2 0x080492b0 in main (argc=6, argv=0xffffd134) at tcc.c:346 (gdb) f 1 #1 0x080639b3 in tcc_run (s1=s1@entry=0x807e008, argc=argc@entry=2, argv=argv@entry=0xffffd144) at tccrun.c:132 132 ret = (*prog_main)(argc, argv); 132 ret = (*prog_main)(argc, argv); (gdb) p argv $1 = (char **) 0xffffd144 So before running compiled program, mark argv as valid region and we are done - now the test passes. P.S. maybe it would be better to just mark the whole vector kernel passes to program (argv, env, auxv, etc...) as valid all at once...

Kirill Smelkov committed 12 years ago

Commit 75118781 parent 262eec31 file · +17 −0Browse files

Unified · Split

tccrun.c+17−0
@@ -110,13 +110,30 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 109 unmodified lines
110 if (s1->do_bounds_check) {110 if (s1->do_bounds_check) {
111 void (*bound_init)(void);111 void (*bound_init)(void);
112 void (*bound_exit)(void);112 void (*bound_exit)(void);
113 void (*bound_new_region)(void *p, unsigned long size);
114 int (*bound_delete_region)(void *p);
115 int i;
116
113 /* set error function */117 /* set error function */
114 rt_bound_error_msg = tcc_get_symbol_err(s1, "__bound_error_msg");118 rt_bound_error_msg = tcc_get_symbol_err(s1, "__bound_error_msg");
115 /* XXX: use .init section so that it also work in binary ? */119 /* XXX: use .init section so that it also work in binary ? */
116 bound_init = tcc_get_symbol_err(s1, "__bound_init");120 bound_init = tcc_get_symbol_err(s1, "__bound_init");
117 bound_exit = tcc_get_symbol_err(s1, "__bound_exit");121 bound_exit = tcc_get_symbol_err(s1, "__bound_exit");
122 bound_new_region = tcc_get_symbol_err(s1, "__bound_new_region");
123 bound_delete_region = tcc_get_symbol_err(s1, "__bound_delete_region");
118 bound_init();124 bound_init();
125 /* mark argv area as valid */
126 bound_new_region(argv, argc*sizeof(argv[0]));
127 for (i=0; i<argc; ++i)
128 bound_new_region(argv[i], strlen(argv[i]));
129
119 ret = (*prog_main)(argc, argv);130 ret = (*prog_main)(argc, argv);
131
132 /* unmark argv area */
133 for (i=0; i<argc; ++i)
134 bound_delete_region(argv[i]);
135 bound_delete_region(argv);
136
120 bound_exit();137 bound_exit();
121 } else138 } else
122#endif139#endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t