Executable Ada code on the stack -


i've watched talk on security considerations railway systems last year's 32c3. @ minute 25 speaker briefly talks ada. says:

typical ada implementations have mechanism called "(tramp / trunk / ?) lines". , means execute code on [the] stack not c programs. , [...] if want link ada code c libraries, 1 of security mechanisms won't work.

here link (youtube) respective part of talk. this slide in background. see unsure 1 of words. perhaps it's trampolines?


now blunt question: there truth in statement? if so, can elaborate on mysterious feature of ada language , security mechanism apparently influences?

until assumed code lives in code segment (aka "text") whereas data (including stack) placed in data segment @ different memory location (as depicted in this graphic). , reading memory management in ada suggests should not different there.

while there ways circumvent such layout (see e.g. "c on stack" question , "c on heap" answer), believe modern oses commonly prevent such attempts via executable space protection unless stack explicitly made executable. - however, embedded systems may still issue if code not kept on rom (can clarify?).

they're called "trampolines". here's understanding of they're for, although i'm not gnat expert, of understanding mistaken.

background: ada (unlike c) supports nested subprograms. nested subprogram able access local variables of enclosing subprograms. example:

procedure outer     some_variable : integer;      procedure inner     begin         ...         some_variable := some_variable + 1;         ... 

since each procedure has own stack frame holds own local variables, there has way inner @ outer's stack frame, can access some_variable, either when outer calls inner, or outer calls other nested subprograms call inner. typical implementation pass hidden parameter inner, called "static link", points outer's stack frame. inner can use access some_variable.

the fun starts when use inner'access, access procedure type. can used store address of inner in variable of access procedure type. other subprograms can later use variable call prodcedure indirectly. if use 'access, variable has declared inside outer--you can't store procedure access in variable outside outer, because call later, after outer has exited , local variables no longer exist. gnat , other ada compilers have 'unrestricted_access attribute gets around restriction, outer call outside subprogram indirectly calls inner. have careful when using it, because if call @ wrong time, result havoc.

anyway, problem arises because when inner'access stored in variable , later used call inner indirectly, hidden parameter static link has used when calling inner. how indirect caller know static link pass?

one solution (irvine compiler's, , others) make variables of access type have 2 values--the procedure address, , static link (so access procedure "fat pointer", not simple pointer). call procedure pass static link, in addition other parameters (if any). [in irvine compiler's implementation, static link inside pointer null if it's pointing global procedure, code knows not pass hidden parameter in case.] drawback doesn't work when passing procedure address callback parameter c routine (something commonly done in ada libraries sit on top of c graphics libraries gtk). c library routines don't know how handle fat pointers this.

gnat uses, or @ 1 time used, trampolines around this. basically, when sees inner'unrestricted_access', generate new code (a "trampoline") on fly. trampoline calls inner correct static link (the value of link embedded in code). access value thin pointer, 1 address, address of trampoline. thus, when c code calls callback, calls trampoline, adds hidden parameter parameter list , calls inner.

this solves problem, creates security issue when trampoline generated on stack.

edit: erred when referring gnat's implementation in present tense. last looked @ few years ago, , don't know whether gnat still things way. [simon has better information this.] way, think it's possible use trampolines not put them on stack, think reduce security issues. when last investigated this, if recall correctly, windows had started preventing code on stack being executed, allowed programs request memory used dynamically generate code executed.


Comments