Presentation is loading. Please wait.

Presentation is loading. Please wait.

Formal reasoning about runtime code update Billiejoe (Nathaniel) Charlton Ben Horsfall Bernhard Reus HotSWUp 2011.

Similar presentations


Presentation on theme: "Formal reasoning about runtime code update Billiejoe (Nathaniel) Charlton Ben Horsfall Bernhard Reus HotSWUp 2011."— Presentation transcript:

1 Formal reasoning about runtime code update Billiejoe (Nathaniel) Charlton Ben Horsfall Bernhard Reus HotSWUp 2011

2 Outline Discuss how to do formal proofs about safety of runtime code updates -Using a (relatively) new variant of Hoare logic -specifically, Hoare logic with nested Hoare triples

3 Outline Discuss how to do formal proofs about safety of runtime code updates -Using a (relatively) new variant of Hoare logic -specifically, Hoare logic with nested Hoare triples Example of formally specifying safety of a runtime update -for a model of an updateable web server from: “Formalizing Dynamic Software Updating” (Gavin Bierman, Michael Hicks, Peter Sewell, Gareth Stoyle)

4 Outline Discuss how to do formal proofs about safety of runtime code updates -Using a (relatively) new variant of Hoare logic -specifically, Hoare logic with nested Hoare triples Example of formally specifying safety of a runtime update -for a model of an updateable web server from: “Formalizing Dynamic Software Updating” (Gavin Bierman, Michael Hicks, Peter Sewell, Gareth Stoyle) -(time permitting) glimpse of this proof done in Crowfoot, our semi-automated verification tool

5 Hoare logic A formal logic for proving things - triples - about programs, e.g. Meaning: if we run the program in a state where the precondition holds -then the program doesn’t crash -and if it terminates, the postcondition will hold

6 Hoare logic A formal logic for proving things - triples - about programs, e.g. Meaning: if we run the program in a state where the precondition holds -then the program doesn’t crash -and if it terminates, the postcondition will hold [ ] = heap access (indirection)

7 Hoare logic A formal logic for proving things - triples - about programs, e.g. Meaning: if we run the program in a state where the precondition holds -then the program doesn’t crash -and if it terminates, the postcondition will hold BUT: Conventional Hoare logic assumes that program’s code is fixed -because pre- and post-condition talk only about data, not code -so how can one reason about dynamic software updates? 

8 Key idea: nested Hoare triples Writing code onto the heap:

9 Key idea: nested Hoare triples Writing code onto the heap:

10 Key idea: nested Hoare triples Writing code onto the heap:

11 Key idea: nested Hoare triples Writing code onto the heap: Invoking code stored on the heap:

12 Key idea: nested Hoare triples Writing code onto the heap: Invoking code stored on the heap:

13 Key idea: nested Hoare triples Writing code onto the heap: Invoking code stored on the heap:

14 Nested Hoare triples Only understood recently -because underlying mathematics is complicated -started with [Honda, Yoshida, Berger - LICS 05] -further developed by others since then

15 Nested Hoare triples Only understood recently -because underlying mathematics is complicated -started with [Honda, Yoshida, Berger - LICS 05] -further developed by others since then Now we have the theory, can we use it to reason about programs? -We thought: let’s give it a go

16 Nested Hoare triples Only understood recently -because underlying mathematics is complicated -started with [Honda, Yoshida, Berger - LICS 05] -further developed by others since then Now we have the theory, can we use it to reason about programs? -We thought: let’s give it a go We borrowed an example from the literature: a model of an updateable web server -One particular runtime update: adding logging to the web server -Code on slides is mercilessly pruned compared to our paper

17 heapcell loop_h; heapcell version; proc main() { locals q; [version] := 1; q := new 0; call mkQueue(q); [loop_h] := loop(_); eval [loop_h](q) } proc loop(q) { locals e; e := new 0; call getEvent(q,e); call handleEvent(e); call maybe_update(); eval [loop_h](q) } proc handleEvent(e) {...} proc getEvent(q,e) {...} proc mkQueue(q) {...} This slide: initial version of model web server

18 heapcell loop_h; heapcell version; proc main() { locals q; [version] := 1; q := new 0; call mkQueue(q); [loop_h] := loop(_); eval [loop_h](q) } proc loop(q) { locals e; e := new 0; call getEvent(q,e); call handleEvent(e); call maybe_update(); eval [loop_h](q) } proc handleEvent(e) {...} proc getEvent(q,e) {...} proc mkQueue(q) {...}

19 heapcell loop_h; heapcell version; proc main() { locals q; [version] := 1; q := new 0; call mkQueue(q); [loop_h] := loop(_); eval [loop_h](q) } proc loop(q) { locals e; e := new 0; call getEvent(q,e); call handleEvent(e); call maybe_update(); eval [loop_h](q) } proc handleEvent(e) {...} proc getEvent(q,e) {...} proc mkQueue(q) {...} Record that we start at version 1

20 heapcell loop_h; heapcell version; proc main() { locals q; [version] := 1; q := new 0; call mkQueue(q); [loop_h] := loop(_); eval [loop_h](q) } proc loop(q) { locals e; e := new 0; call getEvent(q,e); call handleEvent(e); call maybe_update(); eval [loop_h](q) } proc handleEvent(e) {...} proc getEvent(q,e) {...} proc mkQueue(q) {...} Create a queue for events

21 heapcell loop_h; heapcell version; proc main() { locals q; [version] := 1; q := new 0; call mkQueue(q); [loop_h] := loop(_); eval [loop_h](q) } proc loop(q) { locals e; e := new 0; call getEvent(q,e); call handleEvent(e); call maybe_update(); eval [loop_h](q) } proc handleEvent(e) {...} proc getEvent(q,e) {...} proc mkQueue(q) {...} ‘loop’ procedure kept on the heap, so we can update it later

22 heapcell loop_h; heapcell version; proc main() { locals q; [version] := 1; q := new 0; call mkQueue(q); [loop_h] := loop(_); eval [loop_h](q) } proc loop(q) { locals e; e := new 0; call getEvent(q,e); call handleEvent(e); call maybe_update(); eval [loop_h](q) } proc handleEvent(e) {...} proc getEvent(q,e) {...} proc mkQueue(q) {...}

23 heapcell loop_h; heapcell version; proc main() { locals q; [version] := 1; q := new 0; call mkQueue(q); [loop_h] := loop(_); eval [loop_h](q) } proc loop(q) { locals e; e := new 0; call getEvent(q,e); call handleEvent(e); call maybe_update(); eval [loop_h](q) } proc handleEvent(e) {...} proc getEvent(q,e) {...} proc mkQueue(q) {...}

24 heapcell loop_h; heapcell version; proc main() { locals q; [version] := 1; q := new 0; call mkQueue(q); [loop_h] := loop(_); eval [loop_h](q) } proc loop(q) { locals e; e := new 0; call getEvent(q,e); call handleEvent(e); call maybe_update(); eval [loop_h](q) } proc handleEvent(e) {...} proc getEvent(q,e) {...} proc mkQueue(q) {...}

25 heapcell loop_h; heapcell version; proc main() { locals q; [version] := 1; q := new 0; call mkQueue(q); [loop_h] := loop(_); eval [loop_h](q) } proc loop(q) { locals e; e := new 0; call getEvent(q,e); call handleEvent(e); call maybe_update(); eval [loop_h](q) } proc handleEvent(e) {...} proc getEvent(q,e) {...} proc mkQueue(q) {...}

26 heapcell loop_h; heapcell version; proc main() { locals q; [version] := 1; q := new 0; call mkQueue(q); [loop_h] := loop(_); eval [loop_h](q) } proc loop(q) { locals e; e := new 0; call getEvent(q,e); call handleEvent(e); call maybe_update(); eval [loop_h](q) } proc handleEvent(e) {...} proc getEvent(q,e) {...} proc mkQueue(q) {...}

27 What does our update do? Add logging to server – every event will be logged Overwrite ‘loop’ code with a new version Add three new procedures: -loopPrime – the new event-handling loop -logEvent – creates a log entry for a given event -mkEmptyLog – used during transition to create an empty log

28 heapcell loopPrime_h; heapcell logEvent_h; heapcell mkEmptyLog_h; proc mkEmptyLog_2(log) {...} proc logEvent_2(e,log) {...} proc loop_2(q) { locals log; log := new 0; eval [mkEmptyLog_h](log); eval [loopPrime_h](q,log) } proc loopPrime_2(q,log) { locals e; e := new 0; call getEvent(q,e); eval [logEvent_h](e,log); call handleEvent(e); call maybe_update(); eval [loopPrime_h](q,log) }

29 heapcell loopPrime_h; heapcell logEvent_h; heapcell mkEmptyLog_h; proc mkEmptyLog_2(log) {...} proc logEvent_2(e,log) {...} proc loop_2(q) { locals log; log := new 0; eval [mkEmptyLog_h](log); eval [loopPrime_h](q,log) } proc loopPrime_2(q,log) { locals e; e := new 0; call getEvent(q,e); eval [logEvent_h](e,log); call handleEvent(e); call maybe_update(); eval [loopPrime_h](q,log) } Replacement for ‘loop’: “transitional function” to take system into new version

30 heapcell loopPrime_h; heapcell logEvent_h; heapcell mkEmptyLog_h; proc mkEmptyLog_2(log) {...} proc logEvent_2(e,log) {...} proc loop_2(q) { locals log; log := new 0; eval [mkEmptyLog_h](log); eval [loopPrime_h](q,log) } proc loopPrime_2(q,log) { locals e; e := new 0; call getEvent(q,e); eval [logEvent_h](e,log); call handleEvent(e); call maybe_update(); eval [loopPrime_h](q,log) } Set up an empty Log structure

31 heapcell loopPrime_h; heapcell logEvent_h; heapcell mkEmptyLog_h; proc mkEmptyLog_2(log) {...} proc logEvent_2(e,log) {...} proc loop_2(q) { locals log; log := new 0; eval [mkEmptyLog_h](log); eval [loopPrime_h](q,log) } proc loopPrime_2(q,log) { locals e; e := new 0; call getEvent(q,e); eval [logEvent_h](e,log); call handleEvent(e); call maybe_update(); eval [loopPrime_h](q,log) } Pass control to the new event handling loop

32 heapcell loopPrime_h; heapcell logEvent_h; heapcell mkEmptyLog_h; proc mkEmptyLog_2(log) {...} proc logEvent_2(e,log) {...} proc loop_2(q) { locals log; log := new 0; eval [mkEmptyLog_h](log); eval [loopPrime_h](q,log) } proc loopPrime_2(q,log) { locals e; e := new 0; call getEvent(q,e); eval [logEvent_h](e,log); call handleEvent(e); call maybe_update(); eval [loopPrime_h](q,log) } new event handling loop The new behaviour: Log every event before processing

33 proc maybe_update() { if [version] = 1 then { if nondet then { skip } else { [version] := 2; [loop_h] := loop_2(_); [loopPrime_h] := loopPrime_2(_,_); [logEvent_h] := logEvent_2(_,_); [mkEmptyLog_h] := mkEmptyLog_2(_) } else { skip } } Non-deterministically decide whether to update or not

34 proc maybe_update() { if [version] = 1 then { if nondet then { skip } else { [version] := 2; [loop_h] := loop_2(_); [loopPrime_h] := loopPrime_2(_,_); [logEvent_h] := logEvent_2(_,_); [mkEmptyLog_h] := mkEmptyLog_2(_) } else { skip } } Increment version number

35 proc maybe_update() { if [version] = 1 then { if nondet then { skip } else { [version] := 2; [loop_h] := loop_2(_); [loopPrime_h] := loopPrime_2(_,_); [logEvent_h] := logEvent_2(_,_); [mkEmptyLog_h] := mkEmptyLog_2(_) } else { skip } } Overwrite ‘loop’ with new version

36 proc maybe_update() { if [version] = 1 then { if nondet then { skip } else { [version] := 2; [loop_h] := loop_2(_); [loopPrime_h] := loopPrime_2(_,_); [logEvent_h] := logEvent_2(_,_); [mkEmptyLog_h] := mkEmptyLog_2(_) } else { skip } } Load new procedures onto heap

37 What are we trying to prove? We need to say what we are trying to prove! -For each procedure we give a specification e.g. for ‘getEvent’: -Concentrate on memory safety -i.e. the right kind of data structures are present in the right place -We won’t go into details of Queue, Event, Log predicates...

38 To specify the effect of maybe_update(), we need this monster definition

39 Code(v) describes the kind of code present on the heap in version v

40 Code(v) is nested inside itself!

41 Specifications For ‘loop’:

42 Specifications For ‘loop’: For ‘logEvent_2’:

43 Specifications For ‘loop’: For ‘logEvent_2’: For ‘maybe_update’:

44 With these specifications we can prove the update safe Proof done semi-automatically by our verification tool

45 Summary Discussed how to do formal proofs about safety of runtime code updates -using Hoare logic with nested triples Talked through how to formally specify safety of an update -for a model of an updateable web server from: “Formalizing Dynamic Software Updating” (Bierman, Hicks, Sewell, Stoyle) (maybe) glimpsed Crowfoot, our semi-automated verification tool for such safety proofs

46 The End


Download ppt "Formal reasoning about runtime code update Billiejoe (Nathaniel) Charlton Ben Horsfall Bernhard Reus HotSWUp 2011."

Similar presentations


Ads by Google