Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| shmsoc2011qgtt [2011/06/26 11:02] – MateuszKocielski | shmsoc2011qgtt [2017/09/18 14:03] (current) – Use local wiki LinkNames (remove absolute wiki urls) KubilayKocak | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Quick Guide to TESLA ====== | ====== Quick Guide to TESLA ====== | ||
| - | This is a quick write-up on what is TESLA and how to use it in order to verify temporal properties of running code. | + | This is a quick write-up on what is TESLA and how to use it in order to verify temporal properties of a running code. Guide is a part of the %%GSoC%% 2011 project - Testing temporal properties with Temporally Enhanced Security Logic Assertions (TESLA). More information on the project is available at [[ShmSoc2011|GSoC project page]]. Before you start, please beware that TESLA is under developement, |
| ===== What is the TESLA? ===== | ===== What is the TESLA? ===== | ||
| + | |||
| + | TESLA is a framework for testing temporal properties of a software written in the C language. Standard assertions i.e. assert(3) are able to test simple expressions which refer only to an actual state of a program, testing temporal properties in this case (e.g. conformance with the protocols, condition checks before usage etc.) is complex, requires additional code and data structures, thus it could be a source of unnecessary complexity and bugs. TESLA introduces assertions which test temporal expressions, | ||
| ===== Temporal Logic ===== | ===== Temporal Logic ===== | ||
| + | |||
| + | TESLA assertions are subset of the LTL logic, which is temporal logic expressive enough to check if something happend or will happen in the future. This makes LTL perfect to check properties of the code, imagine that you can validate if code checked if user has access to the object before using it by writing simple assertion in LTL language. To get more real life example consider network stack state machine i.e. 802.11 state machine, by using LTL it's possible to ensure that all transitions between states are done upon a fixed protocol by using statements like following one: | ||
| + | |||
| + | < | ||
| + | if current_state == IEEE80211_S_ASSOC, | ||
| + | previous_state == IEEE80211_S_AUTH and authentication was | ||
| + | successful | ||
| + | or | ||
| + | previous_state == IEEE80211_S_RUN and DisAssoc frame is received | ||
| + | </ | ||
| + | |||
| + | Fair description of the LTL logic could be found at [[http:// | ||
| ===== Building ===== | ===== Building ===== | ||
| + | |||
| + | TESLA framework contains following parts: | ||
| + | |||
| + | * llvm/clang - scans C code and instrument is | ||
| + | * CFA - automata compiler, TEAL automatas are used behind LTL expressions | ||
| + | * libtesla - responsible for handling TESLA events, multiplexing/ | ||
| ==== Pre-requirements ==== | ==== Pre-requirements ==== | ||
| - | TESLA relies on some 3rd party software (which you can install | + | TESLA relies on some 3rd party software (all required software is open-source and could be installed |
| - | * environment able to build llvm/clang (CMake, Python) | + | * environment able to build llvm/clang (CMake, Python, ...) |
| - | * OCaml | + | * OCaml (ports/ |
| - | * svn (in order to get sources) | + | * svn (best way to get sources) |
| + | |||
| + | ==== Getting sources ==== | ||
| + | |||
| + | In order to get all sources | ||
| + | |||
| + | < | ||
| + | > svn co https:// | ||
| + | </ | ||
| + | |||
| + | You can also browse sources at https:// | ||
| ==== clang/llvm ==== | ==== clang/llvm ==== | ||
| + | |||
| + | Use build_clang.sh script, which is in the TESLA directory to build llvm/clang. Script will download all needed sources or eventually sync them with repository if any updates are available. | ||
| + | |||
| + | < | ||
| + | $ ./ | ||
| + | </ | ||
| + | |||
| + | You could get now a cup of [[http:// | ||
| ==== CFA - TEAL compiler ==== | ==== CFA - TEAL compiler ==== | ||
| + | |||
| + | CFA sources are placed in cfa/ directory, building it is easy as: | ||
| + | |||
| + | < | ||
| + | > gmake | ||
| + | ... | ||
| + | > ./splc --help | ||
| + | Usage: splc < | ||
| + | -O Optimisation level [0|1] | ||
| + | -q Quiet mode | ||
| + | -v Verbose mode | ||
| + | -hdir HTML Template Directory [.] | ||
| + | -d Debug mode [false] | ||
| + | -t Output mode [tesla|ocaml|dot|promela] | ||
| + | -s Filename for statecalls output (backend specific) | ||
| + | -o Output file basename (without extension) | ||
| + | -help Display this list of options | ||
| + | --help | ||
| + | </ | ||
| + | |||
| + | %%=%%== libtesla == | ||
| + | |||
| + | libtesla sources are located in the TESLA/ | ||
| ===== Using TESLA ===== | ===== Using TESLA ===== | ||
| - | ==== Tesla assertions ==== | + | |
| ==== TEAL ==== | ==== TEAL ==== | ||
| - | ===== Example ===== | + | TEAL language is used to describe sequences of events which are used to verify assertions in the code. It's syntax is strongly based on C language. TEAL starts events from main function: |
| - | ===== Using TESLA with FreeBSD | + | < |
| + | automaton example() | ||
| + | { | ||
| + | void main(struct test *x) | ||
| + | { | ||
| + | x-> | ||
| + | abc(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Automata above describes event of assigning z to field y of x structure followed by abc invocation. Other functions could be declared inside automaton block and could be called from main as well as other functions. Following keywords could be used to build valid sequences of events: | ||
| + | |||
| + | * either { X } or { Y } - X or Y sequences are valid | ||
| + | * multiple { X } - multiple sequence X is valid | ||
| + | * optional { X } - sequence X is optional | ||
| + | |||
| + | Directory contains also a few examples of TEAL automata, it's at least worth to review them. | ||
| + | |||
| + | < | ||
| + | dhcp.spl tcp_connect.spl tcpc.spl | ||
| + | </ | ||
| + | |||
| + | ==== Instrumenter ==== | ||
| + | |||
| + | Tesla instrumenter is a clang/llvm plugin used to analyze C code, it looks for tesla assertions and generate teal code, then instrument code basing on *.spec file which includes two types of declarations: | ||
| + | |||
| + | * function, | ||
| + | * field_assign, | ||
| + | |||
| + | Script kernel/ | ||
| + | |||
| + | ===== Simple example ===== | ||
| + | |||
| + | Consider protocol where states could be described by following schema: | ||
| + | |||
| + | < | ||
| + | | ||
| + | | ||
| + | | ||
| + | P1 ----+ +---+ | ||
| + | | ||
| + | | ||
| + | | ||
| + | </ | ||
| + | |||
| + | I.e. P1, P2, P2, P3, P4, P6 is a valid sequence of protocol states, P1, P2, P4, P2 is invalid sequence, because state P2 cannot be folloed by state P4. Goal is to use TESLA to ensure in dynamic environment that protocol is not violated. | ||
| + | |||
| + | ==== TEAL automata ==== | ||
| + | |||
| + | First we need to write an TEAL specification for the protocol, it's pretty easy to express protocol states: | ||
| + | |||
| + | < | ||
| + | automaton simple_protocol() { | ||
| + | void main(struct test *t) { | ||
| + | t->state = P1; | ||
| + | multiple { | ||
| + | either { | ||
| + | t->state = P2; | ||
| + | } or { | ||
| + | t->state = P3; | ||
| + | } | ||
| + | } | ||
| + | either { | ||
| + | t->state = P4; | ||
| + | } or { | ||
| + | t->state = P5; | ||
| + | } | ||
| + | t->state = P6; | ||
| + | exit; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | If you're looking for more complex example, then few are available in the [[https:// | ||
| + | From TEAL, we need to generate validation automata: | ||
| + | |||
| + | < | ||
| + | > splc -t tesla -s example2 example2.spl | ||
| + | Input files: example2.spl | ||
| + | Processing example2.spl | ||
| + | Compiling function main (public) ... | ||
| + | 19 states | ||
| + | Optimising CFA... | ||
| + | 12 states eliminated | ||
| + | Input files: example2.spl | ||
| + | Output files: example2 | ||
| + | </ | ||
| + | |||
| + | CFA compiler creates two files: | ||
| + | |||
| + | * example2_automata.c - contains automata generated from TEAL specification, | ||
| + | * example2_defs.h - contains definitions of automata events and prototypes of state machine init/ | ||
| + | |||
| + | ==== Connecting automata | ||
| + | |||
| + | To get code guarded by TESLA it's needed to apply following steps: | ||
| + | |||
| + | < | ||
| + | *.c + *.spec --[clang, instrumentation]--> | ||
| + | *.spl --[cfa]--> | ||
| + | </ | ||
| + | |||
| + | For now, automata has been generated. To instrument code, following spec file is used: | ||
| + | |||
| + | < | ||
| + | field_assign, | ||
| + | </ | ||
| + | |||
| + | This declaration means, that compiler will instrument places where some expression is assigned to field state of struct test type. Let's check if TESLA instrumenter meets our expectations: | ||
| + | |||
| + | < | ||
| + | > kernel/ | ||
| + | ... | ||
| + | int __tesla_tmp_assign; | ||
| + | __tesla_tmp_assign | ||
| + | __tesla_event_field_assign_struct_test_state(t, | ||
| + | t-> | ||
| + | |||
| + | ... | ||
| + | </ | ||
| + | |||
| + | https:// | ||
| + | |||
| + | < | ||
| + | t-> | ||
| + | </ | ||
| + | |||
| + | tesla_event_field_assign_struct_test_state is a function which connects instrumented code with the state machine (in the future needed glue will be generated automatically). Most cases of your potential usage will be copy & pasted from https:// | ||
| + | |||
| + | < | ||
| + | void | ||
| + | __tesla_event_field_assign_struct_test_state(struct test *t, u_int state) | ||
| + | { | ||
| + | struct tesla_instance *tip; | ||
| + | int alloc; | ||
| + | int event; | ||
| + | printf(" | ||
| + | assert(tesla_instance_get1(example_state, | ||
| + | 0); | ||
| + | |||
| + | if (alloc == 1) | ||
| + | example2_automata_init(tip); | ||
| + | |||
| + | switch(state) | ||
| + | { | ||
| + | case P1: | ||
| + | event = EXAMPLE2_EVENT_T_STATE_ASSIGN_P1; | ||
| + | break; | ||
| + | case P2: | ||
| + | event = EXAMPLE2_EVENT_T_STATE_ASSIGN_P2; | ||
| + | break; | ||
| + | case P3: | ||
| + | event = EXAMPLE2_EVENT_T_STATE_ASSIGN_P3; | ||
| + | break; | ||
| + | case P4: | ||
| + | event = EXAMPLE2_EVENT_T_STATE_ASSIGN_P4; | ||
| + | break; | ||
| + | case P5: | ||
| + | event = EXAMPLE2_EVENT_T_STATE_ASSIGN_P5; | ||
| + | break; | ||
| + | case P6: | ||
| + | event = EXAMPLE2_EVENT_T_STATE_ASSIGN_P6; | ||
| + | break; | ||
| + | default: | ||
| + | printf(" | ||
| + | tesla_assert_fail(example_state, | ||
| + | } | ||
| + | |||
| + | if(example2_automata_prod(tip, | ||
| + | tesla_assert_fail(example_state, | ||
| + | |||
| + | tesla_instance_put(example_state, | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | tesla_* functions are well documented in [[https:// | ||
| + | |||
| + | We've got all needed pieces to test our code: | ||
| + | |||
| + | < | ||
| + | $ gmake | ||
| + | ../ | ||
| + | ../ | ||
| + | ../ | ||
| + | example2.c: | ||
| + | t->state = atoi(x[i]); | ||
| + | ^~~~~~~~~~~~~~~~~~~~~ | ||
| + | 1 warning generated. | ||
| + | ../ | ||
| + | </ | ||
| + | |||
| + | As mentioned before P1, | ||
| + | |||
| + | < | ||
| + | $ ./example2 1 2 2 3 4 6 | ||
| + | -> 1 | ||
| + | -> 2 | ||
| + | -> 2 | ||
| + | -> 3 | ||
| + | -> 4 | ||
| + | -> 6 | ||
| + | Processed 6 states | ||
| + | </ | ||
| + | |||
| + | While P1,P2,P4,P2 is invalid and should be recognized by state machine as a protocol violation: | ||
| + | |||
| + | < | ||
| + | $ ./example2 1 2 4 2 | ||
| + | -> 1 | ||
| + | -> 2 | ||
| + | -> 4 | ||
| + | -> 2 | ||
| + | example2: tesla_assert failed: TEAL automata example: this is just a simple example | ||
| + | </ | ||
| + | |||
| + | Source code for this example is located at https:// | ||
| ===== Further reading ===== | ===== Further reading ===== | ||
| + | |||
| + | * https:// | ||
| + | * [[BuildingFreeBSDWithClang|Building FreeBSD (world) using llvm/clang toolkit]] | ||
| + | * [[ShmSoc2011|GSoC 2011 TESLA]] - Testing temporal properties with Temporally Enhanced Security Logic Assertions (TESLA) | ||
| + | * http:// | ||