-
Notifications
You must be signed in to change notification settings - Fork 0
/
FinalCaps.thy
2875 lines (2572 loc) · 126 KB
/
FinalCaps.thy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
(*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: GPL-2.0-only
*)
text \<open>
The InfoFlow theorem needs that caps shared between labels cannot be deleted.
In order to do that, this file introduces a dummy label, SilcLabel that will
own all those caps. It then proves all the properties needed about SilcLabel
doing its job.
\<close>
theory FinalCaps
imports ArchInfoFlow_IF
begin
(* FIXME: arch_split: need to have a label on arch refs*)
fun pasGenAbs :: "'a PAS \<Rightarrow> gen_obj_ref \<Rightarrow> 'a" where
"pasGenAbs aag (ObjRef ref) = pasObjectAbs aag ref"
| "pasGenAbs aag (IRQRef ref) = pasIRQAbs aag ref"
(*FIXME REPLACE by alternative definition *)
definition cap_points_to_label where
"cap_points_to_label aag cap l \<equiv>
(\<forall>x \<in> obj_refs cap. (pasObjectAbs aag x = l)) \<and>
(\<forall>x \<in> cap_irqs cap. (pasIRQAbs aag x = l))"
(* WARNING: Reply cap will be considered as intra_label even if they are between labels *)
definition intra_label_cap where
"intra_label_cap aag slot s \<equiv>
(\<forall>cap. cte_wp_at ((=) cap) slot s
\<longrightarrow> (cap_points_to_label aag cap (pasObjectAbs aag (fst slot))))"
(*FIXME REPLACE by alternative definition *)
definition slots_holding_overlapping_caps :: "cap \<Rightarrow> ('z::state_ext) state \<Rightarrow> cslot_ptr set" where
"slots_holding_overlapping_caps cap s \<equiv>
{cref. \<exists>cap'. fst (get_cap cref s) = {(cap', s)} \<and>
(obj_refs cap \<inter> obj_refs cap' \<noteq> {} \<or>
cap_irqs cap \<inter> cap_irqs cap' \<noteq> {} \<or>
arch_gen_refs cap \<inter> arch_gen_refs cap' \<noteq> {})}"
(* FIXME MOVE *)
abbreviation subject_can_affect :: "'a PAS \<Rightarrow> obj_ref \<Rightarrow> bool" where
"subject_can_affect aag ptr \<equiv>
pasObjectAbs aag ptr \<in> subjectAffects (pasPolicy aag) (pasSubject aag)"
abbreviation subject_can_affect_label_directly :: "'a PAS \<Rightarrow> 'a \<Rightarrow> bool" where
"subject_can_affect_label_directly aag l \<equiv>
l \<in> subjectAffects (pasPolicy aag) (pasSubject aag)"
text \<open>We introduce a new label. The name 'silc' here stands for 'safe inter-label caps',
since the domain with this label holds copies of all inter-label caps to ensure that
any others remain 'safe' by never becoming final caps, which would otherwise introduce
a potential covert storage channel\<close>
datatype 'a subject_label = OrdinaryLabel 'a | SilcLabel
abbreviation(input) aag_can_read_not_silc where
"aag_can_read_not_silc aag ptr \<equiv> aag_can_read aag ptr \<and> pasObjectAbs aag ptr \<noteq> SilcLabel"
text\<open>We need to introduce an equivalence on the dummy domain, and add
it to the state that the current subject can read from (i.e.
effectively add it to the current subject's domain), to complete
the proof for is_final_cap. This will necessitate showing that
the dummy domain's state is never affected, but this should be
relatively easy. The annoying part is that now we end up proving
a different property; it will take some finesse to avoid having
to do a search/replace on @{term reads_respects} \<rightarrow> reads_respects_f\<close>
definition silc_dom_equiv where
"silc_dom_equiv aag \<equiv> equiv_for (\<lambda>x. pasObjectAbs aag x = SilcLabel) kheap"
text\<open>This is an invariant that ensures that the info leak due to is_final_cap doesn't
arise. Silc stands for 'safe inter label caps'.
We include a condition that the contents of SilcLabel wrt the kheap are unchanged from
some fixed reference state, since we invariably use this fact to reason that the
invariant is preserved anyway. Including it here saves duplicating essentially identical
reasoning.\<close>
definition silc_inv :: "'a subject_label PAS \<Rightarrow> det_ext state \<Rightarrow> det_ext state \<Rightarrow> bool" where
"silc_inv aag st s \<equiv>
(SilcLabel \<noteq> pasSubject aag) \<and>
(\<forall>x. pasObjectAbs aag x = SilcLabel \<longrightarrow> (\<exists>sz. cap_table_at sz x s)) \<and>
(\<forall>y auth. (y, auth, SilcLabel) \<in> pasPolicy aag \<longrightarrow> y = SilcLabel) \<and>
(\<forall>slot cap. cte_wp_at ((=) cap) slot s \<and>
\<not> intra_label_cap aag slot s
\<longrightarrow> (\<exists>lslot. lslot \<in> slots_holding_overlapping_caps cap s \<and>
(pasObjectAbs aag (fst lslot) = SilcLabel))) \<and>
all_children (\<lambda>x. pasObjectAbs aag (fst x) = SilcLabel) (cdt s) \<and>
silc_dom_equiv aag st s \<and>
\<comment> \<open>We want the following condition to hold on s as well,
but stating that here makes proofs more difficult.
It is shown below in silc_inv_no_transferable'.\<close>
(\<forall>slot. pasObjectAbs aag (fst slot) = SilcLabel \<and>
cte_wp_at (\<lambda>cap. cap \<noteq> NullCap \<and> is_transferable_cap cap) slot st
\<longrightarrow> False)"
(* FIXME MOVE *)
context strengthen_implementation begin
lemma strengthen_cte_wp_at[strg]:
"(\<And>x. st F (\<longrightarrow>) (P x) (Q x)) \<Longrightarrow> st F (\<longrightarrow>) (cte_wp_at P slot s) (cte_wp_at Q slot s)"
by (cases F, auto elim:cte_wp_at_weakenE)
end
lemma slots_holding_overlapping_caps_def':
"slots_holding_overlapping_caps cap s =
{cref. cte_wp_at (\<lambda>cap'. gen_obj_refs cap \<inter> gen_obj_refs cap' \<noteq> {}) cref s}"
unfolding slots_holding_overlapping_caps_def cte_wp_at_def gen_obj_refs_def
by blast
lemma silc_inv_exst[simp]:
"silc_inv aag st (trans_state f s) = silc_inv aag st s"
by (auto simp: silc_inv_def silc_dom_equiv_def intra_label_cap_def
equiv_for_def slots_holding_overlapping_caps_def)
lemma silc_inv_not_subject:
"silc_inv aag st s \<Longrightarrow> SilcLabel \<noteq> pasSubject aag"
unfolding silc_inv_def by force
lemma silc_inv_silc_dom_equiv:
"silc_inv aag st s \<Longrightarrow> silc_dom_equiv aag st s"
unfolding silc_inv_def by force
lemma silc_inv_cnode_only:
"\<lbrakk> silc_inv aag st s; pasObjectAbs aag x = SilcLabel \<rbrakk>
\<Longrightarrow> \<exists>sz. cap_table_at sz x s"
unfolding silc_inv_def by force
lemma silc_inv_cnode_onlyE:
assumes si: "silc_inv aag st s"
assumes posl: "pasObjectAbs aag x = SilcLabel"
obtains sz where "cap_table_at sz x s"
using si posl silc_inv_cnode_only by blast
lemma silc_inv_no_transferable:
"\<lbrakk> silc_inv aag st s; pasObjectAbs aag (fst slot) = SilcLabel;
cte_wp_at (\<lambda>cap. cap \<noteq> NullCap \<and> is_transferable_cap cap) slot st \<rbrakk>
\<Longrightarrow> False"
unfolding silc_inv_def by (force simp del: split_paired_All)
lemmas silc_inv_no_transferableD = silc_inv_no_transferable[where slot="(a,b)" for a b,simplified]
lemma cte_wp_at_pspace_specI:
"\<lbrakk> cte_wp_at P slot s; kheap s (fst slot) = kheap s' (fst slot) \<rbrakk>
\<Longrightarrow> cte_wp_at P slot s'"
by (simp add: cte_wp_at_cases)
lemma silc_inv_no_transferable':
"silc_inv aag st s \<Longrightarrow> pasObjectAbs aag (fst slot) = SilcLabel \<Longrightarrow>
cte_wp_at (\<lambda>cap. cap \<noteq> NullCap \<and> is_transferable_cap cap) slot s \<Longrightarrow> False"
apply (frule (1) silc_inv_no_transferable)
apply (drule silc_inv_silc_dom_equiv)
apply (simp add:silc_dom_equiv_def)
apply (drule (1) equiv_forD)
apply (elim cte_wp_at_pspace_specI)
by simp+
lemmas silc_inv_no_transferableD' =
silc_inv_no_transferable'[where slot="(a,b)" for a b, simplified]
lemma (in is_extended') silc_inv[wp]: "I (silc_inv aag st)" by (rule lift_inv,simp)
lemma get_cap_cte_wp_at':
"(fst (get_cap p s) = {(r,s)}) = cte_wp_at ((=) r) p s"
by (auto simp: cte_wp_at_def)
lemma silc_invD:
"\<lbrakk> silc_inv aag st s; cte_wp_at ((=) cap) slot s; \<not> intra_label_cap aag slot s \<rbrakk>
\<Longrightarrow> (\<exists>lslot. lslot \<in> slots_holding_overlapping_caps cap s \<and>
pasObjectAbs aag (fst lslot) = SilcLabel)"
apply (clarsimp simp: silc_inv_def)
apply (drule_tac x="fst slot" in spec, drule_tac x="snd slot" in spec, fastforce)
done
lemma is_final_cap'_def4:
"is_final_cap' cap s \<equiv> \<exists>a b. slots_holding_overlapping_caps cap s = {(a,b)}"
by (simp add: is_final_cap'_def slots_holding_overlapping_caps_def gen_obj_refs_Int)
(* I think this property is strong enough to give us a sane
confidentiality rule for is_final_cap. This is true, so long as
we include the dummy domain l in what the current subject can
read *)
(* FIXME DELETE *)
lemma silc_inv:
"silc_inv aag st s \<Longrightarrow>
(\<forall>cap slot. cte_wp_at ((=) cap) slot s \<and> is_final_cap' cap s \<longrightarrow>
(intra_label_cap aag slot s \<or> (pasObjectAbs aag (fst slot) = SilcLabel)))"
apply clarsimp
apply (erule contrapos_np)
apply (drule (2) silc_invD)
apply (subgoal_tac "(a,b) \<in> slots_holding_overlapping_caps cap s")
apply (clarsimp simp: is_final_cap'_def4 cte_wp_at_def)
apply (auto simp: slots_holding_overlapping_caps_def cte_wp_at_def)
done
lemma silc_inv_finalD:
"\<lbrakk> silc_inv aag st s; cte_wp_at ((=) cap) slot s; is_final_cap' cap s \<rbrakk>
\<Longrightarrow> intra_label_cap aag slot s \<or> (pasObjectAbs aag (fst slot) = SilcLabel)"
apply clarsimp
apply (erule contrapos_np)
apply (drule (2) silc_invD)
apply (subgoal_tac "slot \<in> slots_holding_overlapping_caps cap s")
apply (clarsimp simp: is_final_cap'_def4 cte_wp_at_def)
apply (auto simp: slots_holding_overlapping_caps_def cte_wp_at_def)
done
lemma silc_inv_finalE:
assumes hyp: "silc_inv aag st s" "cte_wp_at ((=) cap) slot s" "is_final_cap' cap s"
obtains "intra_label_cap aag slot s" | "pasObjectAbs aag (fst slot) = SilcLabel"
using hyp silc_inv_finalD by blast
lemma cte_wp_at_pspace':
"kheap s (fst p) = kheap s' (fst p) \<Longrightarrow> cte_wp_at P p s = cte_wp_at P p s'"
apply (rule iffI)
apply (erule cte_wp_atE)
apply (auto intro: cte_wp_at_cteI dest: sym)[1]
apply (auto intro: cte_wp_at_tcbI dest: sym)[1]
apply (erule cte_wp_atE)
apply (auto intro: cte_wp_at_cteI dest: sym)[1]
apply (auto intro: cte_wp_at_tcbI dest: sym)[1]
done
lemma caps_of_state_pspace':
assumes x: "kheap s (fst slot) = kheap s' (fst slot)"
shows "caps_of_state s slot = caps_of_state s' slot"
by (simp add: caps_of_state_cte_wp_at cte_wp_at_pspace'[OF x])
lemma caps_of_state_intra_label_cap:
"\<lbrakk> caps_of_state s slot = Some cap; caps_of_state t slot = Some cap; intra_label_cap aag slot s\<rbrakk>
\<Longrightarrow> intra_label_cap aag slot t"
by (fastforce simp: intra_label_cap_def cte_wp_at_caps_of_state)
lemma not_is_final_cap_caps_of_stateE:
assumes hyp: "\<not> is_final_cap' cap s" "caps_of_state s slot = Some cap" "gen_obj_refs cap \<noteq> {}"
obtains slot' where "slot' \<noteq> slot" "slot' \<in> slots_holding_overlapping_caps cap s"
using hyp
apply (simp add: is_final_cap'_def4)
apply (subgoal_tac "slot \<in> slots_holding_overlapping_caps cap s")
apply (drule_tac x="fst slot" in spec, drule_tac x="snd slot" in spec)
apply simp
apply fastforce
apply (auto simp: slots_holding_overlapping_caps_def' cte_wp_at_caps_of_state)
done
lemma is_final_then_nonempty_refs:
"is_final_cap' cap s \<Longrightarrow> gen_obj_refs cap \<noteq> {}"
by (auto simp add: is_final_cap'_def)
lemma caps_ref_single_objects:
"\<lbrakk> x \<in> obj_refs cap; y \<in> obj_refs cap \<rbrakk> \<Longrightarrow> x = y"
by (cases cap; simp)
lemma caps_ref_single_irqs:
"\<lbrakk> x \<in> cap_irqs cap; y \<in> cap_irqs cap \<rbrakk> \<Longrightarrow> x = y"
by (cases cap; simp)
lemma not_is_final_cap[rotated -1]:
"\<lbrakk> caps_of_state s slot = Some cap; caps_of_state s slot' = Some cap';
gen_obj_refs cap \<inter> gen_obj_refs cap' \<noteq> {}; slot' \<noteq> slot \<rbrakk>
\<Longrightarrow> \<not> is_final_cap' cap s"
apply (rule ccontr)
apply (clarsimp simp: is_final_cap'_def get_cap_cte_wp_at' cte_wp_at_caps_of_state)
apply (erule_tac B="{(a,b)}" in equalityE)
apply (frule_tac c=slot in subsetD; fastforce)
done
definition reads_equiv_f
where
"reads_equiv_f aag s s' \<equiv> reads_equiv aag s s' \<and> silc_dom_equiv aag s s'"
abbreviation reads_respects_f
where
"reads_respects_f aag l P f \<equiv> equiv_valid_inv (reads_equiv_f aag) (affects_equiv aag l) P f"
lemma intra_label_capD:
"\<lbrakk> intra_label_cap aag slot s; cte_wp_at ((=) cap) slot s \<rbrakk>
\<Longrightarrow> cap_points_to_label aag cap (pasObjectAbs aag (fst slot))"
by (auto simp: intra_label_cap_def)
lemma intra_label_capD':
"\<lbrakk> intra_label_cap aag slot s; caps_of_state s slot = Some cap \<rbrakk>
\<Longrightarrow> cap_points_to_label aag cap (pasObjectAbs aag (fst slot))"
by (auto simp: intra_label_cap_def cte_wp_at_caps_of_state)
lemma is_subject_kheap_eq:
"\<lbrakk> reads_equiv aag s t; is_subject aag ptr \<rbrakk>
\<Longrightarrow> kheap s ptr = kheap t ptr"
apply (clarsimp simp: reads_equiv_def2)
apply (erule states_equiv_forE_kheap)
apply (blast intro: aag_can_read_self)
done
lemma aag_can_read_kheap_eq:
"\<lbrakk> reads_equiv aag s t; aag_can_read aag ptr \<rbrakk>
\<Longrightarrow> kheap s ptr = kheap t ptr"
apply (clarsimp simp: reads_equiv_def2)
apply (erule states_equiv_forE_kheap)
apply blast
done
lemma caps_ref_either_an_object_or_irq':
"ref \<in> cap_irqs cap' \<Longrightarrow>
(obj_refs cap' = {} \<and> arch_gen_refs cap' = {})"
apply (case_tac cap', simp_all)
done
locale FinalCaps_1 =
fixes aag :: "'a subject_label PAS"
(* FIXME IF: precludes X64 *)
assumes FIXME_arch_gen_refs:
"arch_gen_refs cap = {}"
and aobj_ref_same_aobject:
"same_aobject_as cp cp' \<Longrightarrow> aobj_ref cp = aobj_ref cp'"
and arch_invoke_irq_handler_silc_inv[wp]:
"arch_invoke_irq_handler hi \<lbrace>silc_inv aag st\<rbrace>"
and arch_post_cap_deletion_silc_inv[wp]:
"arch_post_cap_deletion acap \<lbrace>silc_inv aag st\<rbrace>"
and arch_finalise_cap_silc_inv[wp]:
"arch_finalise_cap c x \<lbrace>silc_inv aag st\<rbrace>"
and prepare_thread_delete_silc_inv[wp]:
"prepare_thread_delete p \<lbrace>silc_inv aag st\<rbrace>"
and handle_reserved_irq_silc_inv[wp]:
"handle_reserved_irq irq \<lbrace>silc_inv aag st\<rbrace>"
and arch_mask_irq_signal_silc_inv[wp]:
"arch_mask_irq_signal irq \<lbrace>silc_inv aag st\<rbrace>"
and handle_vm_fault_silc_inv[wp]:
"handle_vm_fault t vmft \<lbrace>silc_inv aag st\<rbrace>"
and handle_vm_fault_cur_thread[wp]:
"\<And>P. handle_vm_fault t vmft \<lbrace>\<lambda>s :: det_state. P (cur_thread s)\<rbrace>"
and handle_hypervisor_fault_silc_inv[wp]:
"handle_hypervisor_fault t hvft \<lbrace>silc_inv aag st\<rbrace>"
and arch_activate_idle_threadt_silc_inv[wp]:
"arch_activate_idle_thread t \<lbrace>silc_inv aag st\<rbrace>"
and arch_switch_to_idle_thread_silc_inv[wp]:
"arch_switch_to_idle_thread \<lbrace>silc_inv aag st\<rbrace>"
and arch_switch_to_thread_silc_inv[wp]:
"arch_switch_to_thread t \<lbrace>silc_inv aag st\<rbrace>"
and init_arch_objects_silc_inv[wp]:
"init_arch_objects typ ptr num sz refs \<lbrace>silc_inv aag st\<rbrace>"
and init_arch_objects_cte_wp_at[wp]:
"\<And>P. init_arch_objects typ ptr num sz refs \<lbrace>\<lambda>s :: det_state. P (cte_wp_at P' slot s)\<rbrace>"
and finalise_cap_makes_halted:
"\<lbrace>invs and valid_cap cap and (\<lambda>s. ex = is_final_cap' cap s) and cte_wp_at ((=) cap) slot\<rbrace>
finalise_cap cap ex
\<lbrace>\<lambda>rv s :: det_state. \<forall>t \<in> obj_refs (fst rv). halted_if_tcb t s\<rbrace>"
and arch_post_modify_registers_silc_inv[wp]:
"arch_post_modify_registers cur t \<lbrace>silc_inv aag st\<rbrace>"
and arch_derive_cap_silc:
"\<lbrace>\<lambda>s :: det_state. cap = ArchObjectCap acap \<and>
(\<not> cap_points_to_label aag cap l \<longrightarrow> R (slots_holding_overlapping_caps cap s))\<rbrace>
arch_derive_cap acap
\<lbrace>\<lambda>cap' s. \<not> cap_points_to_label aag cap' l \<longrightarrow> R (slots_holding_overlapping_caps cap' s)\<rbrace>,-"
begin
lemma cap_points_to_label_def':
"cap_points_to_label aag cap l = (\<forall>x \<in> gen_obj_refs cap. pasGenAbs aag x = l)"
unfolding cap_points_to_label_def
by (simp add: gen_obj_refs_def ball_Un FIXME_arch_gen_refs)
lemma caps_ref_either_an_object_or_irq:
"ref \<in> obj_refs cap'
\<Longrightarrow> cap_irqs cap' = {} \<and> arch_gen_refs cap' = {}"
apply (clarsimp simp: FIXME_arch_gen_refs)
apply (case_tac cap'; clarsimp)
done
lemma caps_ref_either_an_object_or_irq'':
"ref \<in> arch_gen_refs cap'
\<Longrightarrow> obj_refs cap' = {} \<and> cap_irqs cap' = {}"
apply (clarsimp simp: FIXME_arch_gen_refs)
done
lemma arch_gen_refs_no_intersection[simp]:
"arch_gen_refs c \<inter> arch_gen_refs c' = {}"
by (cases c; auto simp: FIXME_arch_gen_refs)
lemma is_final_cap'_read_equiv_imp:
"\<lbrakk> silc_inv aag st s; cte_wp_at ((=) cap) slot s; silc_inv aag st t; cte_wp_at ((=) cap) slot t;
aag_can_read_not_silc aag (fst slot); reads_equiv aag s t; is_final_cap' cap s \<rbrakk>
\<Longrightarrow> is_final_cap' cap t"
unfolding F[symmetric]
subgoal premises prems
proof (rule ccontr)
assume not_final: "\<not> is_final_cap' cap t"
from prems have ilcs : "intra_label_cap aag slot s"
by (fastforce elim: silc_inv_finalE[OF _ caps_of_state_cteD, where s = s])
hence ilct: "intra_label_cap aag slot t"
using prems caps_of_state_intra_label_cap by blast
from prems have sdest: "silc_dom_equiv aag s t"
by (fastforce simp: silc_dom_equiv_def intro: equiv_for_trans
dest: silc_inv_silc_dom_equiv elim: equiv_for_sym)
(* if cap is non final, then there must exists another cap overlapping somewhere *)
from not_final prems obtain slot' where "slot' \<in> slots_holding_overlapping_caps cap t"
and diff: "slot' \<noteq> slot"
by (fastforce elim: not_is_final_cap_caps_of_stateE[OF _ _ is_final_then_nonempty_refs])
then obtain cap' where cap': "caps_of_state t slot' = Some cap'"
and cap_overlap_cap': "gen_obj_refs cap \<inter> gen_obj_refs cap' \<noteq> {}"
by (fastforce simp: slots_holding_overlapping_caps_def' cte_wp_at_caps_of_state)
note prems = prems not_final cap' cap_overlap_cap' diff
show False
proof (cases "aag_can_read aag (fst slot')")
case True
(* This case is easy: slot' is in subjectReads domain, so cap' is also in slot' in s.
Thus cap is not final: Direct contracticion*)
thus ?thesis using prems
apply -
apply (erule(1) not_is_final_cap[THEN notE])
apply (simp add: caps_of_state_pspace'[OF aag_can_read_kheap_eq])
by fastforce+
next
case False note cant_read = this
(* slot is in subjectRead, slot' isn't. However they hold overlaping caps. Thus: *)
hence not_intra : "\<not> intra_label_cap aag slot' t"
using prems ilct by (fastforce simp: cap_points_to_label_def' dest!: intra_label_capD')
(* Then, accroding to silc_inv, there is a third cap in SilcLabel overlapping cap and cap'*)
then obtain lslot where "lslot \<in> slots_holding_overlapping_caps cap' t"
and lslot_silc: "pasObjectAbs aag (fst lslot) = SilcLabel"
using prems silc_invD[simplified F[symmetric]] by blast
then obtain lcap where lcap_t: "caps_of_state t lslot = Some lcap"
and lcap_overlap_cap': "gen_obj_refs cap' \<inter> gen_obj_refs lcap \<noteq> {}"
by (fastforce simp: slots_holding_overlapping_caps_def' cte_wp_at_caps_of_state)
(* As lslot is in SilcLabel, kheap do not change between s and t and thus: *)
have lcap_s: "caps_of_state s lslot = Some lcap"
using lcap_t prems sdest
apply (unfold silc_dom_equiv_def)
apply (drule equiv_forD, rule lslot_silc)
by (subst caps_of_state_pspace'; assumption)
(* lcap thus overlaps cap in s but cap was final in s: contradiction *)
then show ?thesis (* TODO CLEANUP *)
using prems lslot_silc lcap_overlap_cap' lcap_s
apply -
apply (drule gen_obj_refs_distinct_or_equal)+
apply simp
apply (erule(1) not_is_final_cap[where slot' = lslot, THEN notE,rotated])
apply (blast dest:is_final_then_nonempty_refs)
apply assumption
apply force
done
qed
qed
done
lemma is_final_cap'_read_equiv_eq:
"\<lbrakk> silc_inv aag st s; cte_wp_at ((=) cap) slot s; silc_inv aag st t;
cte_wp_at ((=) cap) slot t; aag_can_read_not_silc aag (fst slot); reads_equiv aag s t \<rbrakk>
\<Longrightarrow> is_final_cap' cap s = is_final_cap' cap t"
apply (rule iffI)
subgoal by (rule is_final_cap'_read_equiv_imp)
apply (drule reads_equiv_sym)
subgoal by (rule is_final_cap'_read_equiv_imp)
done
lemma is_final_cap_reads_respects:
"reads_respects_f aag l (silc_inv aag st and (\<lambda>s. cte_wp_at ((=) cap) slot s \<and>
aag_can_read_not_silc aag (fst slot)))
(is_final_cap cap)"
unfolding is_final_cap_def
by (clarsimp simp: equiv_valid_def2 equiv_valid_2_def in_monad
reads_equiv_f_def is_final_cap'_read_equiv_eq)
end
definition ctes_wp_at
where
"ctes_wp_at P s \<equiv> {ptr. cte_wp_at P ptr s}"
lemma slots_holding_overlapping_caps_def2:
"slots_holding_overlapping_caps cap s =
ctes_wp_at (\<lambda>c. (obj_refs cap \<inter> obj_refs c \<noteq> {}) \<or>
(cap_irqs cap \<inter> cap_irqs c \<noteq> {}) \<or>
(arch_gen_refs cap \<inter> arch_gen_refs c \<noteq> {})) s"
by (simp add: slots_holding_overlapping_caps_def ctes_wp_at_def cte_wp_at_def)
lemma intra_label_cap_pres:
assumes cte: "\<And>P. \<lbrace>\<lambda> s. \<not> cte_wp_at P slot s\<rbrace> f \<lbrace>\<lambda> _ s. \<not> cte_wp_at P slot s\<rbrace>"
shows "\<lbrace>intra_label_cap aag slot\<rbrace> f \<lbrace>\<lambda>_. intra_label_cap aag slot\<rbrace>"
apply (clarsimp simp: valid_def intra_label_cap_def)
apply (drule_tac x=cap in spec)
apply (case_tac "cte_wp_at ((=) cap) slot s")
apply blast
apply (drule_tac use_valid[OF _ cte])
apply assumption
apply blast
done
lemma not_intra_label_cap_pres:
assumes cte: "\<And>P. \<lbrace>cte_wp_at P slot\<rbrace> f \<lbrace>\<lambda>_. cte_wp_at P slot\<rbrace>"
shows "\<lbrace>\<lambda>s. \<not> intra_label_cap aag slot s\<rbrace> f \<lbrace>\<lambda>_ s. \<not> intra_label_cap aag slot s\<rbrace>"
apply (clarsimp simp: valid_def intra_label_cap_def)
apply (rule_tac x=cap in exI)
apply (drule_tac use_valid[OF _ cte], assumption)
apply blast
done
lemma cte_wp_at_pres_from_kheap':
assumes l:
"\<And>ptr P.
\<lbrace>R and (\<lambda>s. P (kheap s ptr)) and K (pasObjectAbs aag ptr = l)\<rbrace>
f
\<lbrace>\<lambda>_ s. P (kheap s ptr)\<rbrace>"
shows "\<lbrace>(\<lambda>s. Q (cte_wp_at P slot s)) and R and K (pasObjectAbs aag (fst slot) = l)\<rbrace>
f
\<lbrace>(\<lambda>_ s. Q (cte_wp_at P slot s))\<rbrace>"
apply (rule hoare_gen_asm)
apply (simp add: valid_def | intro allI impI ballI)+
apply (rename_tac x, case_tac x, simp, rename_tac rv s')
apply (subgoal_tac "\<exists>x. kheap s (fst slot) = x")
apply (erule exE, rename_tac x)
apply (drule use_valid)
apply (rule_tac ptr="fst slot" and P="\<lambda> y. y = x" in l)
apply simp
apply (drule trans, erule sym)
apply (drule_tac P=P in cte_wp_at_pspace')
apply simp
apply blast
done
lemmas cte_wp_at_pres_from_kheap = cte_wp_at_pres_from_kheap'[where R="\<top>", simplified]
lemma hoare_contrapositive:
"\<lbrakk> \<lbrace>P\<rbrace> f \<lbrace>Q\<rbrace>; \<not> Q r s'; (r, s') \<in> fst (f s) \<rbrakk> \<Longrightarrow> \<not> P s"
apply (case_tac "P s")
apply (blast dest: use_valid)
apply assumption
done
lemma allI': "\<forall>x y. P x y \<Longrightarrow> \<forall>y x. P x y"
by simp
lemma silc_inv_pres:
assumes l: "\<And>ptr P.
\<lbrace>silc_inv aag st and (\<lambda>s. P (kheap s ptr)) and K (pasObjectAbs aag ptr = SilcLabel)\<rbrace>
f
\<lbrace>\<lambda>_ s. P (kheap s ptr)\<rbrace>"
assumes c: "\<And>P. \<lbrace>\<lambda>s. P (cdt s)\<rbrace> f \<lbrace>\<lambda>_ s. P (cdt s)\<rbrace>"
assumes ncte: "\<And>P slot. \<lbrace>\<lambda>s. \<not> cte_wp_at P slot s\<rbrace> f \<lbrace>\<lambda>_ s. \<not> cte_wp_at P slot s\<rbrace>"
shows "\<lbrace>silc_inv aag st\<rbrace> f \<lbrace>\<lambda>_. silc_inv aag st\<rbrace>"
apply (clarsimp simp: valid_def silc_inv_def)
apply (clarsimp simp: slots_holding_overlapping_caps_def2 ctes_wp_at_def)
apply (rule conjI)
apply (intro allI impI)
apply (frule_tac x=x in spec, erule (1) impE)
apply (erule exE, rename_tac sz, rule_tac x=sz in exI)
apply (simp add: obj_at_def)
apply (elim exE conjE, rename_tac ko)
apply (rule_tac x=ko in exI, simp)
apply (erule use_valid[OF _ l])
apply simp
apply (clarsimp simp: silc_inv_def obj_at_def slots_holding_overlapping_caps_def2 ctes_wp_at_def)
apply (rule conjI)
apply clarsimp
apply (frule_tac x=aa in spec, drule_tac x=ba in spec, drule_tac x=cap in spec)
apply (subgoal_tac "cte_wp_at ((=) cap) (aa, ba) s \<and> \<not> intra_label_cap aag (aa,ba) s")
apply (erule (1) impE)
apply (elim exE conjE)+
apply (rule_tac x=ab in exI, rule conjI, rule_tac x=bb in exI)
apply (erule use_valid[OF _ cte_wp_at_pres_from_kheap'[where R="silc_inv aag st"]])
apply (rule l)
apply simp
apply (clarsimp simp: silc_inv_def tcb_at_typ obj_at_def
slots_holding_overlapping_caps_def2 ctes_wp_at_def)
apply assumption
apply (rule conjI)
apply (erule (1) hoare_contrapositive[OF ncte, simplified])
apply (rule hoare_contrapositive[OF intra_label_cap_pres, simplified, OF ncte], assumption+)
apply (rule conjI)
apply (erule use_valid[OF _ c])
apply simp
apply (simp add: silc_dom_equiv_def)
apply (rule equiv_forI)
apply (erule use_valid[OF _ l])
apply (fastforce simp: silc_inv_def obj_at_def slots_holding_overlapping_caps_def2
ctes_wp_at_def silc_dom_equiv_def
elim: equiv_forE)
done
(* if we don't touch any caps or modify any object-types, then
silc_inv is preserved *)
lemma silc_inv_triv:
assumes kheap: "\<And>P x. \<lbrace>\<lambda>s. P (kheap s x)\<rbrace> f \<lbrace>\<lambda>_ s. P (kheap s x)\<rbrace>"
assumes c: "\<And>P. \<lbrace>\<lambda>s. P (cdt s)\<rbrace> f \<lbrace>\<lambda> _ s. P (cdt s)\<rbrace>"
assumes cte: "\<And>Q P slot. \<lbrace>\<lambda>s. Q (cte_wp_at P slot s)\<rbrace> f \<lbrace>\<lambda>_ s. Q (cte_wp_at P slot s)\<rbrace>"
assumes typ_at: "\<And>P T p. \<lbrace>\<lambda>s. P (typ_at T p s)\<rbrace> f \<lbrace>\<lambda>_ s. P (typ_at T p s)\<rbrace>"
shows "\<lbrace>silc_inv aag st\<rbrace> f \<lbrace>\<lambda>_. silc_inv aag st\<rbrace>"
apply (clarsimp simp: valid_def silc_inv_def)
apply (rule conjI)
apply (intro allI impI)
apply (erule use_valid)
apply (rule hoare_vcg_ex_lift)
apply (rule cap_table_at_lift_valid[OF typ_at])
apply blast
apply (rule conjI)
apply (clarsimp simp: slots_holding_overlapping_caps_def2 ctes_wp_at_def)
apply (drule_tac x=aa in spec, drule_tac x=ba in spec, drule_tac x=cap in spec)
apply (subgoal_tac "cte_wp_at ((=) cap) (aa, ba) s \<and> \<not> intra_label_cap aag (aa,ba) s")
apply (elim exE conjE | simp)+
apply (rule_tac x=ab in exI, rule conjI, rule_tac x=bb in exI)
apply (erule (1) use_valid[OF _ cte])
apply (assumption)
apply (rule conjI)
apply (case_tac "cte_wp_at ((=) cap) (aa, ba) s")
apply assumption
apply (drule use_valid[OF _ cte[where Q="\<lambda> x. \<not> x"]])
apply assumption
apply blast
apply (case_tac "intra_label_cap aag (aa, ba) s")
apply (drule_tac use_valid[OF _ intra_label_cap_pres[OF cte]])
apply assumption
apply blast
apply assumption
apply (simp add: silc_dom_equiv_def)
apply (rule conjI)
apply (erule use_valid[OF _ c])
apply simp
apply (rule equiv_forI)
apply (erule use_valid[OF _ kheap])
apply (fastforce elim: equiv_forE)
done
lemma set_cap_well_formed_cnode_helper:
"\<lbrakk> well_formed_cnode_n x xa; xa (snd slot) = Some y \<rbrakk>
\<Longrightarrow> well_formed_cnode_n x (\<lambda>a. if a = snd slot then Some cap else xa a)"
apply (simp add: well_formed_cnode_n_def)
apply (rule equalityI)
apply (drule equalityD1)
apply (fastforce dest: subsetD split: if_splits)
apply (drule equalityD2)
apply (fastforce dest: subsetD split: if_splits)
done
lemma set_cap_slots_holding_overlapping_caps_helper:
"\<lbrakk> x \<in> slots_holding_overlapping_caps cap s; fst x \<noteq> fst slot;
obj_refs cap = {} \<longrightarrow> cap_irqs cap \<noteq> {};
ko_at (TCB tcb) (fst slot) s; tcb_cap_cases (snd slot) = Some (getF, setF, blah) \<rbrakk>
\<Longrightarrow> x \<in> slots_holding_overlapping_caps cap
(s\<lparr>kheap := kheap s(fst slot \<mapsto>
TCB (setF (\<lambda> x. capa) tcb))\<rparr>)"
apply (clarsimp simp: slots_holding_overlapping_caps_def)
apply (rule_tac x=cap' in exI)
apply (clarsimp simp: get_cap_cte_wp_at')
apply (erule (1) upd_other_cte_wp_at)
done
lemma set_cap_slots_holding_overlapping_caps_other:
"\<lbrace>\<lambda>s. x \<in> slots_holding_overlapping_caps capa s \<and>
pasObjectAbs aag (fst x) \<noteq> pasObjectAbs aag (fst slot)\<rbrace>
set_cap cap slot
\<lbrace>\<lambda>rv s. x \<in> slots_holding_overlapping_caps capa s\<rbrace>"
unfolding set_cap_def
apply (wpsimp wp: set_object_wp get_object_wp)+
apply (case_tac "obj_refs capa = {} \<and> cap_irqs capa = {}")
apply (clarsimp simp: slots_holding_overlapping_caps_def)
apply (fastforce simp: get_cap_def get_object_def bind_def split_def gets_def get_def
return_def assert_def assert_opt_def fail_def
split: kernel_object.splits if_splits option.splits)
apply (subgoal_tac "fst x \<noteq> fst slot")
apply (intro allI impI conjI)
apply (clarsimp simp: slots_holding_overlapping_caps_def)
apply (rule_tac x=cap' in exI)
apply clarsimp
apply (subst get_cap_cte_wp_at')
apply (rule upd_other_cte_wp_at)
apply (simp add: cte_wp_at_def)
apply assumption
apply (clarsimp simp: get_cap_caps_of_state)
apply ((drule set_cap_slots_holding_overlapping_caps_helper[where slot=slot], simp+)+)[5]
apply clarsimp
done
lemma set_cap_cte_wp_at_triv:
"\<lbrace>\<top>\<rbrace> set_cap cap slot \<lbrace>\<lambda>_. cte_wp_at ((=) cap) slot\<rbrace>"
unfolding set_cap_def
apply (wpsimp wp: set_object_wp get_object_wp)
apply (intro impI conjI allI)
apply (rule cte_wp_at_cteI)
apply fastforce
apply clarsimp
apply (drule set_cap_well_formed_cnode_helper[where slot=slot], simp+)
apply (fastforce intro: cte_wp_at_tcbI simp: tcb_cap_cases_def)+
done
lemma set_cap_silc_inv:
"\<lbrace>(\<lambda>s. \<not> cap_points_to_label aag cap (pasObjectAbs aag (fst slot))
\<longrightarrow> (\<exists>lslot. lslot \<in> slots_holding_overlapping_caps cap s \<and>
pasObjectAbs aag (fst lslot) = SilcLabel)) and
silc_inv aag st and K (pasObjectAbs aag (fst slot) \<noteq> SilcLabel)\<rbrace>
set_cap cap slot
\<lbrace>\<lambda>_. silc_inv aag st\<rbrace>"
apply (rule hoare_gen_asm)
apply (clarsimp simp: valid_def silc_inv_def)
apply (intro conjI impI allI)
apply (erule use_valid)
apply (rule hoare_vcg_ex_lift)
apply (rule cap_table_at_lift_valid[OF set_cap_typ_at])
apply blast
apply (case_tac "slot = (a,ba)")
apply (subgoal_tac "cap = capa")
apply (simp)
apply (erule impE)
apply (simp add: intra_label_cap_def)
apply (elim conjE exE)
apply (blast dest: cte_wp_at_eqD2)
apply (elim exE conjE)
apply (rule_tac x=aa in exI, simp)
apply (rule_tac x=bb in exI)
apply (erule use_valid[OF _ set_cap_slots_holding_overlapping_caps_other[where aag=aag]])
apply fastforce
apply (rule cte_wp_at_eqD2)
apply blast
apply (drule_tac s=slot in sym, simp)
apply (erule use_valid[OF _ set_cap_cte_wp_at_triv], rule TrueI)
apply (drule_tac x=a in spec, drule_tac x=ba in spec, drule_tac x= capa in spec)
apply (erule impE, rule conjI)
apply (fastforce elim!: hoare_contrapositive[OF set_cap_neg_cte_wp_at_other, simplified])
apply (rule_tac P="\<lambda> s. intra_label_cap aag (a, ba) s" in hoare_contrapositive)
apply (rule intra_label_cap_pres)
apply (erule set_cap_neg_cte_wp_at_other)
apply (erule conjE, assumption)
apply assumption
apply clarsimp
apply (rule_tac x=aa in exI, simp)
apply (rule_tac x=bb in exI)
apply (erule use_valid[OF _ set_cap_slots_holding_overlapping_caps_other[where aag=aag]])
apply fastforce
apply (erule use_valid[OF _ set_cap_rvk_cdt_ct_ms(4)],simp)
apply (simp add: silc_dom_equiv_def)
apply (rule equiv_forI)
apply (erule use_valid)
unfolding set_cap_def
apply (wp set_object_wp get_object_wp static_imp_wp | simp add: split_def | wpc)+
apply clarsimp
apply (rule conjI)
apply fastforce
apply (fastforce elim: equiv_forE)
done
lemma slots_holding_overlapping_caps_hold_caps:
"slot \<in> slots_holding_overlapping_caps cap s \<Longrightarrow> \<exists>cap'. cte_wp_at ((=) cap') slot s"
by (fastforce simp: slots_holding_overlapping_caps_def get_cap_cte_wp_at')
crunch silc_inv[wp]: set_original "silc_inv aag st"
(wp: silc_inv_triv wp_del:set_original_wp)
lemma nonempty_refs:
"\<not> cap_points_to_label aag cap l \<Longrightarrow> obj_refs cap \<noteq> {} \<or> cap_irqs cap \<noteq> {}"
by (auto simp: cap_points_to_label_def)
lemma set_cdt_silc_inv:
"\<lbrace>silc_inv aag st and K (all_children (\<lambda>x. pasObjectAbs aag (fst x) = SilcLabel) m)\<rbrace>
set_cdt m
\<lbrace>\<lambda>_. silc_inv aag st\<rbrace>"
apply (simp add: set_cdt_def)
apply wp
apply (simp add: intra_label_cap_def slots_holding_overlapping_caps_def
silc_inv_def silc_dom_equiv_def equiv_for_def)
done
lemma update_cdt_silc_inv:
"\<lbrace>silc_inv aag st and (\<lambda>s. all_children (\<lambda>x. pasObjectAbs aag (fst x) = SilcLabel) (f (cdt s)))\<rbrace>
update_cdt f
\<lbrace>\<lambda>_. silc_inv aag st\<rbrace>"
apply (simp add: update_cdt_def)
apply (wp set_cdt_silc_inv | simp)+
done
lemma silc_inv_all_children:
"silc_inv aag st s \<Longrightarrow> all_children (\<lambda>x. pasObjectAbs aag (fst x) = SilcLabel) (cdt s)"
by (simp add: silc_inv_def)
lemma cap_irqs_max_free_index_update[simp]:
"cap_irqs (max_free_index_update cap) = cap_irqs cap"
apply (case_tac cap, simp_all add: free_index_update_def)
done
lemma cap_points_to_label_max_free_index_update[simp]:
"cap_points_to_label aag (max_free_index_update cap) l = cap_points_to_label aag cap l"
apply (simp add: cap_points_to_label_def)
done
crunch silc_inv': set_untyped_cap_as_full "silc_inv aag st"
(wp: set_cap_silc_inv)
lemmas set_untyped_cap_as_full_silc_inv[wp] = set_untyped_cap_as_full_silc_inv'[simplified]
lemma set_untyped_cap_as_full_slots_holding_overlapping_caps_other:
"\<lbrace>\<lambda>s. x \<in> slots_holding_overlapping_caps capa s \<and>
pasObjectAbs aag (fst x) \<noteq> pasObjectAbs aag (fst slot)\<rbrace>
set_untyped_cap_as_full src_cap cap slot
\<lbrace>\<lambda>_ s. x \<in> slots_holding_overlapping_caps capa s\<rbrace>"
unfolding set_untyped_cap_as_full_def
apply (rule hoare_pre)
apply (wp set_cap_slots_holding_overlapping_caps_other[where aag=aag])
apply clarsimp
done
lemma is_derived_overlaps':
"\<lbrakk> is_derived (cdt s) slot cap cap';
(obj_refs cap' \<noteq> {} \<or> cap_irqs cap' \<noteq> {}) \<or>
(obj_refs cap \<noteq> {} \<or> cap_irqs cap \<noteq> {}) \<rbrakk>
\<Longrightarrow> obj_refs cap \<inter> obj_refs cap' \<noteq> {} \<or>
cap_irqs cap \<inter> cap_irqs cap' \<noteq> {}"
apply (simp add: is_derived_def)
apply (case_tac cap', simp_all add: cap_master_cap_def split: cap.splits)
apply (fastforce dest: master_arch_cap_obj_refs)
done
lemma is_derived_overlaps:
"\<lbrakk> cte_wp_at (is_derived (cdt s) slot cap) slot s;
obj_refs cap \<noteq> {} \<or> cap_irqs cap \<noteq> {} \<rbrakk>
\<Longrightarrow> slot \<in> slots_holding_overlapping_caps cap s"
apply (simp add: slots_holding_overlapping_caps_def get_cap_cte_wp_at')
apply (drule cte_wp_at_norm)
apply (erule exE, rename_tac cap')
apply (rule_tac x=cap' in exI)
apply (blast dest: is_derived_overlaps')
done
lemma is_derived_overlaps2:
"\<lbrakk> cte_wp_at ((=) cap') slot s;
is_derived (cdt s) slot cap cap';
obj_refs cap' \<noteq> {} \<or> cap_irqs cap' \<noteq> {} \<rbrakk>
\<Longrightarrow> slot \<in> slots_holding_overlapping_caps cap' s"
apply (simp add: slots_holding_overlapping_caps_def get_cap_cte_wp_at')
apply (blast dest: cte_wp_at_norm is_derived_overlaps')
done
lemma disj_dup: "A \<and> B \<and> C \<and> C'\<Longrightarrow> A \<and> B \<and> C \<and> A \<and> B \<and> C'"
by simp
context FinalCaps_1 begin
lemma weak_derived_overlaps':
"\<lbrakk> weak_derived cap cap'; obj_refs cap \<noteq> {} \<or> cap_irqs cap \<noteq> {} \<rbrakk>
\<Longrightarrow> obj_refs cap \<inter> obj_refs cap' \<noteq> {} \<or>
cap_irqs cap \<inter> cap_irqs cap' \<noteq> {}"
apply (simp add: weak_derived_def)
apply (erule disjE)
prefer 2
apply simp
apply (simp add: copy_of_def split: if_split_asm add: same_object_as_def split: cap.splits)
apply ((case_tac cap; simp)+)[5]
apply (clarsimp simp: aobj_ref_same_aobject)
done
lemma weak_derived_overlaps:
"\<lbrakk> cte_wp_at (weak_derived cap) slot s;
obj_refs cap \<noteq> {} \<or> cap_irqs cap \<noteq> {} \<rbrakk>
\<Longrightarrow> slot \<in> slots_holding_overlapping_caps cap s"
apply (simp add: slots_holding_overlapping_caps_def get_cap_cte_wp_at')
apply (drule cte_wp_at_norm)
apply (erule exE, rename_tac cap')
apply (rule_tac x=cap' in exI)
apply (blast dest: weak_derived_overlaps')
done
lemma not_cap_points_to_label_transfers_across_overlapping_caps:
"\<lbrakk> \<not> cap_points_to_label aag cap (pasObjectAbs aag (fst slot));
slot \<in> slots_holding_overlapping_caps cap s \<rbrakk>
\<Longrightarrow> \<not> intra_label_cap aag slot s"
apply (simp add: slots_holding_overlapping_caps_def get_cap_cte_wp_at')
apply (elim exE conjE, rename_tac cap')
apply (simp add: intra_label_cap_def)
apply (rule_tac x=cap' in exI)
apply (auto simp: cap_points_to_label_def
dest: caps_ref_single_objects caps_ref_single_irqs caps_ref_either_an_object_or_irq)
done
lemma overlapping_transfers_across_overlapping_caps:
"\<lbrakk> slot \<in> slots_holding_overlapping_caps cap s;
cte_wp_at ((=) cap') slot s;
lslot \<in> slots_holding_overlapping_caps cap' s \<rbrakk>
\<Longrightarrow> lslot \<in> slots_holding_overlapping_caps cap s"
apply (simp add: slots_holding_overlapping_caps_def get_cap_cte_wp_at')
apply (elim exE conjE)
apply (drule (1) cte_wp_at_eqD2)+
apply clarsimp
apply (rename_tac lcap)
apply (rule_tac x=lcap in exI)
apply (auto dest: caps_ref_single_objects caps_ref_single_irqs caps_ref_either_an_object_or_irq)
done
lemma overlapping_slots_have_labelled_overlapping_caps:
"\<lbrakk> slot \<in> slots_holding_overlapping_caps cap s; silc_inv aag st s;
\<not> cap_points_to_label aag cap (pasObjectAbs aag (fst slot)) \<rbrakk>
\<Longrightarrow> (\<exists>lslot. lslot \<in> slots_holding_overlapping_caps cap s \<and>
pasObjectAbs aag (fst lslot) = SilcLabel)"
apply (drule not_cap_points_to_label_transfers_across_overlapping_caps)
apply assumption
apply (frule slots_holding_overlapping_caps_hold_caps)
apply (erule exE, rename_tac cap')
apply (drule silc_invD)
apply assumption
apply assumption
apply (blast dest: overlapping_transfers_across_overlapping_caps)
done
lemma cap_swap_silc_inv:
"\<lbrace>silc_inv aag st and cte_wp_at (weak_derived cap) slot and
cte_wp_at (weak_derived cap') slot' and
K(pasObjectAbs aag (fst slot) = pasObjectAbs aag (fst slot') \<and>
pasObjectAbs aag (fst slot') \<noteq> SilcLabel)\<rbrace>
cap_swap cap slot cap' slot'
\<lbrace>\<lambda>_. silc_inv aag st\<rbrace>"
apply (rule hoare_gen_asm)
unfolding cap_swap_def
apply (rule hoare_pre)
apply (wp set_cap_silc_inv hoare_vcg_ex_lift static_imp_wp
set_cap_slots_holding_overlapping_caps_other[where aag=aag] set_cdt_silc_inv
| simp split del: if_split)+
apply (rule conjI)
apply (rule impI, elim conjE)
apply (drule weak_derived_overlaps)
apply (erule nonempty_refs)
apply (drule overlapping_slots_have_labelled_overlapping_caps)
apply assumption
apply simp
apply fastforce
apply (rule conjI)
apply (rule impI, elim conjE)
apply (drule weak_derived_overlaps, erule nonempty_refs)
apply (drule overlapping_slots_have_labelled_overlapping_caps)
apply assumption
apply simp
apply fastforce
apply (elim conjE)
apply (drule silc_inv_all_children)
apply simp
apply (intro impI conjI)
by (fastforce simp: all_children_def simp del: split_paired_All
| simp add: all_children_def del: split_paired_All)+ (*slow*)
lemma cap_move_silc_inv:
"\<lbrace>silc_inv aag st and cte_wp_at (weak_derived cap) slot and
K(pasObjectAbs aag (fst slot) = pasObjectAbs aag (fst slot') \<and>
pasObjectAbs aag (fst slot') \<noteq> SilcLabel)\<rbrace>
cap_move cap slot slot'
\<lbrace>\<lambda>_. silc_inv aag st\<rbrace>"
apply (rule hoare_gen_asm)
unfolding cap_move_def
apply (rule hoare_pre)
apply (wp set_cap_silc_inv hoare_vcg_ex_lift
set_cap_slots_holding_overlapping_caps_other[where aag=aag]
set_cdt_silc_inv static_imp_wp
| simp)+
apply (rule conjI)
apply (fastforce simp: cap_points_to_label_def)
apply (rule conjI)
apply (rule impI, elim conjE)
apply (drule weak_derived_overlaps)
apply (erule nonempty_refs)
apply (drule overlapping_slots_have_labelled_overlapping_caps)
apply assumption
apply simp
apply fastforce
apply (elim conjE)
apply (drule silc_inv_all_children)
apply (fastforce simp: all_children_def simp del: split_paired_All)
done
lemma slots_holding_overlapping_caps_max_free_index_update[simp]:
"slots_holding_overlapping_caps (max_free_index_update cap) s =
slots_holding_overlapping_caps cap s"
by (simp add: slots_holding_overlapping_caps_def)
lemma cap_insert_silc_inv:
"\<lbrace>silc_inv aag st and (\<lambda>s. cte_wp_at (is_derived (cdt s) slot cap) slot s) and
K (pasObjectAbs aag (fst slot) = pasObjectAbs aag (fst slot') \<and>
pasObjectAbs aag (fst slot') \<noteq> SilcLabel)\<rbrace>
cap_insert cap slot slot'
\<lbrace>\<lambda>_. silc_inv aag st\<rbrace>"
unfolding cap_insert_def
(* The order here matters. The first two need to be first. *)
apply (wp assert_wp static_imp_conj_wp set_cap_silc_inv hoare_vcg_ex_lift
set_untyped_cap_as_full_slots_holding_overlapping_caps_other[where aag=aag]
get_cap_wp update_cdt_silc_inv | simp | wp (once) hoare_drop_imps)+
apply clarsimp
apply (rule disj_dup)
apply (rule conjI)
apply (rule impI)
apply (drule is_derived_overlaps)
apply (erule nonempty_refs)
apply (drule overlapping_slots_have_labelled_overlapping_caps)
apply assumption
apply simp
apply fastforce