c - Order of variable declaration in asm x86? -
here piece of code :
int main() { char buffer[64]; int check; ...
as can see, check
declared after buffer
, in stack, must have check
above buffer
in stack right?
however, when disassembly (x86) gdb, got :
--> check
@ 0xbffff4f8
--> buffer
@ 0xbffff4b8
my question : there specific order in stack local variable?
also, have tell tried same thing on computer (x86 too, same gcc compilation options, different gdb version , linux distrib), , order not same...:s
thanks !
ps: if want more details, please see screenshot : (left computer 1 , right computer 2)
there -fstack-protect
in gcc reorder stack variables, turned on default in linux os variant 10 years, ubuntu, redhat, gentoo. default since gcc 4.8.3 ("4.9 , later enable -fstack-protector-strong.")
ubuntu page gcc defaults: https://wiki.ubuntu.com/toolchain/compilerflags
ubuntu-specific default compiler flags in toolchain used provide additional security features ubuntu. ... default flags
-fstack-protector
... first enabled in ubuntu 6.10.
ubuntu page stack protection https://wiki.ubuntu.com/gccssp
gcc 4.1 comes ssp now, nice technology mitigate exploitability of many buffer overflows. ... ssp provides technology stop exploitability of class of vulnerabilities (1) reordering stack variables ... redhat , gentoo using ssp default years
this reordering requires several o(n^2)
walks on local variables of function make compilation slower long functions, example "why compiling on 100,000 lines of std::vector::push_back take long time?" - https://stackoverflow.com/a/14034393/196561
deferred allocation forced when
-fstack-protect
enabled (sometimes needs reorder stack variables). .. cfgexpand.c
969 /* subroutine of expand_one_var. var variable 970 allocated local stack frame. return true if wish 971 add var stack_vars coalesced other 972 variables. return false allocate var immediately. 973 974 function used reduce number of variables considered 975 coalescing, reduces size of quadratic problem. */ 976 977 static bool 978 defer_stack_allocation (tree var, bool toplevel) 980 /* if stack protection enabled, *all* stack variables must deferred, 981 can re-order strings top of frame. */
so, gcc reorder stack variables, , strings @ top of frame. try -fno-stack-protector
option disable.
as usual, gcc's author don't document how -fstack-protect
works in public documentation https://gcc.gnu.org/onlinedocs/gcc/instrumentation-options.html:
-fstack-protector
emit code check buffer overflows, such stack smashing attacks. done adding guard variable functions vulnerable objects. includes functions callalloca
, , functions buffers larger 8 bytes. guards initialized when function entered , checked when function exits. if guard check fails, error message printed , program exits.
-fstack-protector-all
-fstack-protector
except functions protected.
-fstack-protector-strong
-fstack-protector
includes additional functions protected — have local array definitions, or have references local frame addresses.
-fstack-protector-explicit
-fstack-protector
protects functions havestack_protect
attribute.
and documentation of array-before-locals see real, best documentation: source code
https://gcc.gnu.org/viewcvs/gcc/branches/gcc-4_6-branch/gcc/cfgexpand.c?revision=175029&view=markup#l1526 - expand_used_vars()
1533 if (has_protected_decls) 1534 { 1535 /* phase 1 contains character arrays. */ 1536 expand_stack_vars (stack_protect_decl_phase_1); 1537 1538 /* phase 2 contains other kinds of arrays. */ 1539 if (flag_stack_protect == 2) 1540 expand_stack_vars (stack_protect_decl_phase_2); 1541 } 1542 1543 expand_stack_vars (null);
phase 1 , phase 2 vars separated stack_protect_decl_phase()
https://gcc.gnu.org/viewcvs/gcc/branches/gcc-4_6-branch/gcc/cfgexpand.c?revision=175029&view=markup#l1235
1235 /* return nonzero if decl should segregated "vulnerable" upper 1236 part of local stack frame. remember if ever return nonzero 1237 variable in function. return value phase number in 1238 variable should allocated. */ 1239 1240 static int 1241 stack_protect_decl_phase (tree decl) ... 1243 unsigned int bits = stack_protect_classify_type (tree_type (decl)); ... 1249 if (flag_stack_protect == 2) 1250 { 1251 if ((bits & (spct_has_small_char_array | spct_has_large_char_array)) 1252 && !(bits & spct_has_aggregate)) 1253 ret = 1; 1254 else if (bits & spct_has_array) 1255 ret = 2; 1256 }
stack_protect_classify_type
return bits has_array
has_*_char_array
arrays of char (both char, unsigned char , signed char)
Comments
Post a Comment