-
Notifications
You must be signed in to change notification settings - Fork 108
/
Copy pathNoninterference.thy
4089 lines (3706 loc) · 193 KB
/
Noninterference.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
*)
theory Noninterference
imports
Noninterference_Base
Noninterference_Base_Alternatives
ArchScheduler_IF
ArchADT_IF
Access.ArchADT_AC
begin
text \<open>
The top-level information flow theorems. (There are also theories for
example systems, which go on top of this one.)
We will instantiate the various unwinding systems, defined in
Noninterference_Base(_Alternative), with the actual kernel automaton
from ADT_IF. Then we consider the @{term noninterference_system.Nonleakage}
and @{term noninterference_system.Noninterference} properties over
our kernel big steps.
At the end of this file, we show the top-level Nonleakage theorem.
The Noninterference property does not hold on the kernel and is not
proven despite the name of the file, but a partial integrity result
holds in integrity_part.
\<close>
section \<open>sameFor : unwinding relation\<close>
datatype 'a partition = Partition 'a | PSched
fun scheduler_modes where
"scheduler_modes KernelPreempted = True"
| "scheduler_modes (KernelEntry Interrupt) = True"
| "scheduler_modes (KernelSchedule b) = b"
| "scheduler_modes _ = False"
(*Modes where thread context is valid*)
fun user_modes where
"user_modes KernelExit = False"
| "user_modes _ = True"
definition sameFor_subject ::
"'a subject_label auth_graph \<Rightarrow> 'a subject_label agent_map \<Rightarrow>
'a subject_label agent_irq_map \<Rightarrow> 'a subject_label agent_asid_map \<Rightarrow>
'a subject_label agent_domain_map \<Rightarrow> 'a \<Rightarrow> (observable_if \<times> observable_if) set" where
"sameFor_subject g ab irqab asidab domainab l \<equiv>
{(os,os') | os os' s s'.
s = internal_state_if os \<and> s' = internal_state_if os' \<and>
states_equiv_for (\<lambda>x. ab x \<in> subjectReads g (OrdinaryLabel l))
(\<lambda>x. irqab x \<in> subjectReads g (OrdinaryLabel l))
(\<lambda>x. asidab x \<in> subjectReads g (OrdinaryLabel l))
(\<lambda>x. domainab x \<inter> subjectReads g (OrdinaryLabel l) \<noteq> {}) s s' \<and>
((domainab (cur_domain s) \<inter> subjectReads g (OrdinaryLabel l) \<noteq> {} \<or>
domainab (cur_domain s') \<inter> subjectReads g (OrdinaryLabel l) \<noteq> {})
\<longrightarrow> (cur_domain s = cur_domain s' \<and> globals_equiv s s' \<and>
scheduler_action s = scheduler_action s' \<and>
work_units_completed s = work_units_completed s' \<and>
irq_state (machine_state s) = irq_state (machine_state s') \<and>
(user_modes (sys_mode_of os) \<longrightarrow> user_context_of os = user_context_of os') \<and>
sys_mode_of os = sys_mode_of os' \<and> equiv_for (\<lambda>x. ab x = SilcLabel) kheap s s'))}"
definition sameFor_scheduler ::
"'a subject_label auth_graph \<Rightarrow> 'a subject_label agent_map \<Rightarrow>
'a subject_label agent_irq_map \<Rightarrow> 'a subject_label agent_asid_map \<Rightarrow>
'a subject_label agent_domain_map \<Rightarrow> (observable_if \<times> observable_if) set" where
"sameFor_scheduler g ab irqab asidab domainab \<equiv>
{(os,os') | os os' s s'.
s = internal_state_if os \<and> s' = internal_state_if os' \<and> domain_fields_equiv s s' \<and>
idle_thread s = idle_thread s' \<and> globals_equiv_scheduler s s' \<and>
equiv_for (\<lambda>x. ab x = SilcLabel) kheap s s' \<and> irq_state_of_state s = irq_state_of_state s' \<and>
scheduler_modes (sys_mode_of os) = scheduler_modes (sys_mode_of os') \<and>
interrupted_modes (sys_mode_of os) = interrupted_modes (sys_mode_of os')}"
text \<open>
From the graph we define an equivalence relation on states for each partition.
This is the unwinding relation of domain d with the right parameters (cf uwr later in this file)
\<close>
definition sameFor ::
"'a subject_label auth_graph \<Rightarrow> 'a subject_label agent_map \<Rightarrow>
'a subject_label agent_irq_map \<Rightarrow> 'a subject_label agent_asid_map \<Rightarrow>
'a subject_label agent_domain_map \<Rightarrow> 'a partition \<Rightarrow> (observable_if \<times> observable_if) set" where
"sameFor g ab irqab asidab domainab d \<equiv>
case d of Partition l \<Rightarrow> sameFor_subject g ab irqab asidab domainab l
| PSched \<Rightarrow> sameFor_scheduler g ab irqab asidab domainab"
abbreviation same_for where
"same_for aag d \<equiv> sameFor (pasPolicy aag) (pasObjectAbs aag) (pasIRQAbs aag)
(pasASIDAbs aag) (pasDomainAbs aag) d"
text \<open>
We want @{term sameFor} to be an equivalence relation always.
\<close>
lemma sameFor_refl: "refl (sameFor g ab irqab asidab domainab d)"
by (auto intro!: refl_onI equiv_for_refl
simp: sameFor_def sameFor_subject_def sameFor_scheduler_def domain_fields_equiv_def
split: partition.splits
intro: states_equiv_for_refl globals_equiv_refl globals_equiv_scheduler_refl)
lemma domain_fields_equiv_sym:
"domain_fields_equiv s t \<Longrightarrow> domain_fields_equiv t s"
by (clarsimp simp: domain_fields_equiv_def)
lemma sameFor_sym:
"sym (sameFor g ab irqab asidab domainab d)"
by (fastforce intro: symI
simp: sameFor_def sameFor_subject_def sameFor_scheduler_def
split: partition.splits
intro: states_equiv_for_sym globals_equiv_sym equiv_for_sym domain_fields_equiv_sym)
lemma domain_fields_equiv_trans:
"\<lbrakk> domain_fields_equiv s t; domain_fields_equiv t u \<rbrakk>
\<Longrightarrow> domain_fields_equiv s u"
by (clarsimp simp: domain_fields_equiv_def)
lemma sameFor_trans:
"trans (sameFor g ab irqab asidab domainab d)"
apply (rule transI)
apply (auto simp: sameFor_def sameFor_subject_def sameFor_scheduler_def
split: partition.splits
intro: states_equiv_for_trans globals_equiv_trans
equiv_for_trans domain_fields_equiv_trans)
done
fun label_of where
"label_of (OrdinaryLabel l) = l"
lemma is_label[simp]:
"x \<noteq> SilcLabel \<Longrightarrow> OrdinaryLabel (label_of x) = x"
by (case_tac x, auto)
lemma pasSubject_not_SilcLabel:
"silc_inv aag s s' \<Longrightarrow> pasSubject aag \<noteq> SilcLabel"
by (auto simp: silc_inv_def)
(* needs silc_inv to ensure pasSubject is not SilcLabel *)
lemma sameFor_reads_equiv_f_g:
"\<lbrakk> reads_equiv_f_g aag s s'; silc_inv aag st' st'';
pasSubject aag \<in> pasDomainAbs aag (cur_domain s) \<union> pasDomainAbs aag (cur_domain s') \<rbrakk>
\<Longrightarrow> (((uc,s),mode),((uc,s'),mode)) \<in> same_for aag (Partition (label_of (pasSubject aag)))"
apply (clarsimp simp: reads_equiv_f_g_def reads_equiv_def2 sameFor_def silc_dom_equiv_def)
apply (simp add: sameFor_subject_def)
apply (frule pasSubject_not_SilcLabel)
apply (clarsimp)
done
lemma sameFor_reads_equiv_f_g':
"\<lbrakk> pas_cur_domain aag s \<or> pas_cur_domain aag s'; silc_inv aag st s;
(((uc,s),mode),((uc',s'),mode')) \<in> same_for aag (Partition (label_of (pasSubject aag))) \<rbrakk>
\<Longrightarrow> reads_equiv_f_g aag s s'"
apply (frule pasSubject_not_SilcLabel)
apply (auto simp: reads_equiv_f_g_def reads_equiv_def2 sameFor_def
sameFor_subject_def silc_dom_equiv_def globals_equiv_def)
done
lemma sameFor_scheduler_equiv:
"(s,s') \<in> same_for aag PSched
\<Longrightarrow> scheduler_equiv aag (internal_state_if s) (internal_state_if s')"
by (clarsimp simp: scheduler_equiv_def sameFor_def sameFor_scheduler_def silc_dom_equiv_def)
definition label_can_affect_partition where
"label_can_affect_partition g k l \<equiv> \<exists>d. d \<in> subjectAffects g k \<and> d \<in> subjectReads g l"
definition partsSubjectAffects where
"partsSubjectAffects g l \<equiv>
Partition ` {x. label_can_affect_partition g (OrdinaryLabel l) (OrdinaryLabel x)}"
lemma reads_g_affects_equiv_sameFor:
"\<lbrakk> reads_equiv_f_g aag s s' \<and> affects_equiv aag (OrdinaryLabel l) s s';
pas_cur_domain aag s; silc_inv aag st' st'';
Partition l \<in> partsSubjectAffects (pasPolicy aag) (label_of (pasSubject aag)) \<rbrakk>
\<Longrightarrow> (((uc,s),mode),((uc,s'),mode)) \<in> same_for aag (Partition l)"
apply (clarsimp simp: partsSubjectAffects_def)
apply (simp add: affects_equiv_def2 sameFor_def sameFor_subject_def)
apply (frule pasSubject_not_SilcLabel)
apply (simp add: reads_equiv_f_g_def reads_equiv_def2 silc_dom_equiv_def)
apply (erule states_equiv_for_guard_imp)
apply (simp add: aag_can_affect_label_def label_can_affect_partition_def)+
done
lemma schedule_reads_affects_equiv_sameFor_PSched:
"\<lbrakk> scheduler_equiv aag s s'; scheduler_modes mode = scheduler_modes mode';
interrupted_modes mode = interrupted_modes mode' \<rbrakk>
\<Longrightarrow> (((uc,s),mode),((uc',s'),mode')) \<in> same_for aag PSched"
by (simp add: sameFor_def sameFor_scheduler_def scheduler_equiv_def silc_dom_equiv_def)
lemma schedule_reads_affects_equiv_sameFor_PSched':
"\<lbrakk> scheduler_equiv aag (internal_state_if s) (internal_state_if s');
scheduler_modes (sys_mode_of s) = scheduler_modes (sys_mode_of s');
interrupted_modes (sys_mode_of s) = interrupted_modes (sys_mode_of s') \<rbrakk>
\<Longrightarrow> (s,s') \<in> same_for aag PSched"
apply (case_tac s)
apply (case_tac a)
apply (case_tac s')
apply (case_tac ab)
apply clarsimp
apply (rule schedule_reads_affects_equiv_sameFor_PSched; simp)
done
lemma observable_if_cases:
"P (s::observable_if) \<Longrightarrow> P (((user_context_of s),(internal_state_if s)),sys_mode_of s)"
by (case_tac s, case_tac "fst s", simp)
lemma sameFor_reads_f_g_affects_equiv:
"\<lbrakk> pas_cur_domain aag (internal_state_if s); silc_inv aag st (internal_state_if s);
(s,s') \<in> same_for aag (Partition (label_of (pasSubject aag)));
Partition l \<in> partsSubjectAffects (pasPolicy aag) (label_of (pasSubject aag));
(s,s') \<in> same_for aag (Partition l) \<rbrakk>
\<Longrightarrow> reads_equiv_f_g aag (internal_state_if s) (internal_state_if s') \<and>
affects_equiv aag (OrdinaryLabel l) (internal_state_if s) (internal_state_if s')"
apply (rule conjI)
apply (rule sameFor_reads_equiv_f_g')
apply blast
apply blast
apply (rule_tac s=s in observable_if_cases)
apply (erule_tac s=s' in observable_if_cases)
apply (simp add: partsSubjectAffects_def)
apply (frule pasSubject_not_SilcLabel)
apply clarsimp
apply (clarsimp simp: affects_equiv_def2 sameFor_def)
apply (clarsimp simp: sameFor_subject_def[where l=l])
apply (blast intro: states_equiv_for_guard_imp)
done
lemma schedule_reads_affects_equiv_sameFor:
"\<lbrakk> scheduler_equiv aag s s'; scheduler_affects_equiv aag (OrdinaryLabel l) s s';
user_modes mode \<longrightarrow> uc = uc' \<rbrakk>
\<Longrightarrow> (((uc,s),mode),((uc',s'),mode)) \<in> same_for aag (Partition l)"
by (auto simp: scheduler_equiv_def scheduler_affects_equiv_def sameFor_def sameFor_subject_def
silc_dom_equiv_def reads_scheduler_def domain_fields_equiv_def
disjoint_iff_not_equal Bex_def
intro: globals_equiv_from_scheduler)
lemma globals_equiv_to_scheduler_globals_frame_equiv:
"\<lbrakk> globals_equiv s t; invs s; invs t \<rbrakk>
\<Longrightarrow> scheduler_globals_frame_equiv s t"
by (simp add: globals_equiv_def scheduler_globals_frame_equiv_def)
lemma globals_equiv_to_cur_thread_eq:
"globals_equiv s t \<Longrightarrow> cur_thread s = cur_thread t"
by (simp add: globals_equiv_def)
lemma no_subject_affects_PSched:
"PSched \<notin> partsSubjectAffects g l"
by (auto simp: partsSubjectAffects_def elim: subjectAffects.cases)
section \<open>InfoFlow policy and partition integrity\<close>
text \<open>
We derive a noninterference policy from the authority graph
We exclude the silc label from the noninterference policy
since it exists in the authority graph solely to ensure that no actual subject's
label covers the inter label caps.
\<close>
inductive_set policyFlows :: "'a subject_label auth_graph \<Rightarrow> ('a partition \<times> 'a partition) set"
for g :: "'a subject_label auth_graph" where
policy_affects: "d \<in> partsSubjectAffects g l \<Longrightarrow> (Partition l, d) \<in> policyFlows g"
| policy_scheduler: "(PSched,d) \<in> policyFlows g"
lemma no_partition_flows_to_PSched:
"(Partition l, PSched) \<notin> policyFlows g"
apply (rule notI)
apply (erule policyFlows.cases)
apply (simp_all add: no_subject_affects_PSched)
done
lemma partsSubjectAffects_bounds_those_subject_not_allowed_to_affect:
"(Partition l,d) \<notin> policyFlows g \<Longrightarrow> d \<notin> partsSubjectAffects g l"
apply (clarify)
apply (drule policy_affects)
apply (blast)
done
lemma PSched_flows_to_all:
"(PSched,d) \<in> policyFlows g"
by (rule policyFlows.intros)
lemma policyFlows_refl:
"refl (policyFlows g)"
apply (rule refl_onI)
apply simp
apply (case_tac x)
apply simp
apply (rule policy_affects)
apply (simp add: partsSubjectAffects_def image_def)
apply (simp add: label_can_affect_partition_def)
apply (blast intro: affects_lrefl)
apply (blast intro: PSched_flows_to_all)
done
(* a more constrained integrity property for non-PSched transitions
TODO: can we constrain this further? *)
definition partitionIntegrity :: "'a subject_label PAS \<Rightarrow> det_ext state \<Rightarrow> det_ext state \<Rightarrow> bool"
where
"partitionIntegrity aag s s' \<equiv>
integrity (aag\<lparr>pasMayActivate := False, pasMayEditReadyQueues := False\<rparr>)
(scheduler_affects_globals_frame s) s s' \<and>
domain_fields_equiv s s' \<and> idle_thread s = idle_thread s' \<and>
globals_equiv_scheduler s s' \<and> silc_dom_equiv aag s s'"
lemma thread_set_tcb_context_update_ct_active[wp]:
"thread_set (tcb_arch_update (arch_tcb_context_set f)) t \<lbrace>\<lambda>s. P (ct_active s)\<rbrace>"
apply (simp add: thread_set_def ct_in_state_def | wp set_object_wp)+
apply (clarsimp simp: st_tcb_at_def obj_at_def get_tcb_def
split: option.splits kernel_object.splits)
done
lemma prop_of_two_valid:
assumes f: "\<And>P. m \<lbrace>\<lambda>s. P (f s)\<rbrace>"
assumes g: "\<And>P. m \<lbrace>\<lambda>s. P (g s)\<rbrace>"
shows "m \<lbrace>\<lambda>s. P (f s) (g s)\<rbrace>"
by (rule hoare_pre, wps f g, wp, simp)
lemma thread_set_tcb_context_update_wp:
"\<lbrace>\<lambda>s. P (s\<lparr>kheap := (kheap s)(t \<mapsto> TCB (tcb_arch_update f (the (get_tcb t s))))\<rparr>)\<rbrace>
thread_set (tcb_arch_update f) t
\<lbrace>\<lambda>_. P\<rbrace>"
apply (simp add: thread_set_def)
apply (wp set_object_wp)
apply simp
done
lemma dmo_device_update_respects_Write:
"\<lbrace>integrity aag X st and K (\<forall>p \<in> dom um'. aag_has_auth_to aag Write p)\<rbrace>
do_machine_op (device_memory_update um')
\<lbrace>\<lambda>_. integrity aag X st\<rbrace>"
apply (simp add: device_memory_update_def)
apply (rule hoare_pre)
apply (wp dmo_wp)
apply clarsimp
apply (simp cong: abstract_state.fold_congs)
apply (rule integrity_device_state_update)
apply simp
apply clarify
apply (drule (1) bspec)
apply simp
apply fastforce
done
lemma check_active_irq_if_integrity:
"check_active_irq_if tc \<lbrace>integrity aag X st\<rbrace>"
by (wpsimp wp: check_active_irq_if_wp simp: integrity_subjects_def)
lemma silc_dom_equiv_from_silc_inv_valid':
assumes "\<And>st. \<lbrace>P and silc_inv aag st\<rbrace> f \<lbrace>\<lambda>_. silc_inv aag st\<rbrace>"
shows "\<lbrace>P and silc_inv aag st and silc_dom_equiv aag sta\<rbrace> f \<lbrace>\<lambda>_. silc_dom_equiv aag sta\<rbrace>"
apply (rule hoare_pre)
apply (rule hoare_strengthen_post)
apply (rule assms)
apply (fastforce simp: silc_inv_def)
(* we can't use clarsimp below because it splits pairs unconditionally *)
apply (simp add: silc_inv_def silc_dom_equiv_def del: split_paired_All)
apply (elim conjE)
apply (intro allI impI notI)
apply (drule(1) equiv_forD)+
apply (frule(1) cte_wp_at_pspace'[THEN iffD1])
apply (drule spec, drule(1) mp, erule notE, erule(1) cte_wp_at_pspace'[THEN iffD2])
done
lemma ct_running_not_idle:
"\<lbrakk> ct_running s; valid_idle s \<rbrakk> \<Longrightarrow> cur_thread s \<noteq> idle_thread s"
by (clarsimp simp add: ct_in_state_def pred_tcb_at_def obj_at_def valid_idle_def)
lemma kernel_entry_if_globals_equiv_scheduler:
"\<lbrace>globals_equiv_scheduler st and valid_arch_state and invs
and (\<lambda>s. e \<noteq> Interrupt \<longrightarrow> ct_active s)
and (\<lambda>s. ct_idle s \<longrightarrow> tc = idle_context s)\<rbrace>
kernel_entry_if e tc
\<lbrace>\<lambda>_. globals_equiv_scheduler st\<rbrace>"
apply (wpsimp wp: globals_equiv_scheduler_inv' kernel_entry_if_globals_equiv)
apply assumption
apply clarsimp
done
lemma domain_fields_equiv_lift:
assumes a: "\<And>P. \<lbrace>domain_fields P and Q\<rbrace> f \<lbrace>\<lambda>_. domain_fields P\<rbrace>"
assumes b: "\<And>P. \<lbrace>(\<lambda>s. P (cur_domain s)) and R\<rbrace> f \<lbrace>\<lambda>_ s. P (cur_domain s)\<rbrace>"
shows "\<lbrace>domain_fields_equiv st and Q and R\<rbrace> f \<lbrace>\<lambda>_. domain_fields_equiv st\<rbrace>"
apply (clarsimp simp: valid_def domain_fields_equiv_def)
apply (erule use_valid, wp a b)
apply simp
done
lemma check_active_irq_if_partitionIntegrity:
"check_active_irq_if tc \<lbrace>partitionIntegrity aag st\<rbrace>"
apply (simp add: check_active_irq_if_def)
apply (wp dmo_getActiveIRQ_wp)
apply (simp add: partitionIntegrity_def integrity_subjects_def)
apply (simp add: silc_dom_equiv_def equiv_for_def globals_equiv_scheduler_def)
apply (fastforce simp: domain_fields_equiv_def)
done
lemma do_machine_op_globals_equiv_scheduler:
"(\<And>s sa. \<lbrakk> P sa; globals_equiv_scheduler s sa \<rbrakk>
\<Longrightarrow> \<forall>x \<in> fst (f (machine_state sa)).
globals_equiv_scheduler s (sa\<lparr>machine_state := snd x\<rparr>))
\<Longrightarrow> \<lbrace>globals_equiv_scheduler s and P\<rbrace>
do_machine_op f
\<lbrace>\<lambda>_. globals_equiv_scheduler s\<rbrace>"
unfolding do_machine_op_def by (wp | simp add: split_def)+
lemma dmo_user_memory_update_globals_equiv_scheduler:
"\<lbrace>globals_equiv_scheduler st and
(invs and (\<lambda>s. pl = ptable_lift t s |` {x. pr x \<noteq> {}} \<and> pr = ptable_rights t s))\<rbrace>
do_machine_op
(user_memory_update ((ba |` {y. \<exists>x. pl x = Some y \<and> AllowWrite \<in> pr x} \<circ> addrFromPPtr) |` S))
\<lbrace>\<lambda>_. globals_equiv_scheduler st\<rbrace>"
apply (rule do_machine_op_globals_equiv_scheduler)
apply clarsimp
apply (erule use_valid)
apply (simp add: user_memory_update_def)
apply (wp modify_wp)
apply (clarsimp simp: globals_equiv_scheduler_def split: option.splits)
done
lemma dmo_device_memory_update_globals_equiv_scheduler:
"\<lbrace>globals_equiv_scheduler st and (\<lambda>s. device_region s = S)\<rbrace>
do_machine_op
(device_memory_update ((ba |` {y. \<exists>x. pl x = Some y \<and> AllowWrite \<in> pr x} \<circ> addrFromPPtr) |` S))
\<lbrace>\<lambda>_. globals_equiv_scheduler st\<rbrace>"
apply (rule do_machine_op_globals_equiv_scheduler)
apply clarsimp
apply (simp add: device_memory_update_def simpler_modify_def)
apply (clarsimp simp: globals_equiv_scheduler_def split: option.splits)
done
lemma pas_refined_pasMayActivate_update[simp]:
"pas_refined (aag\<lparr>pasMayActivate := x, pasMayEditReadyQueues := x\<rparr>) s =
pas_refined (aag :: 'a subject_label PAS) s"
apply (simp add: pas_refined_def irq_map_wellformed_aux_def tcb_domain_map_wellformed_aux_def)
apply (simp add: state_asids_to_policy_pasMayActivate_update[simplified]
state_irqs_to_policy_pasMayActivate_update
state_asids_to_policy_pasMayEditReadyQueues_update[simplified]
state_irqs_to_policy_pasMayEditReadyQueues_update)
done
lemma activate_thread_globals_equiv_scheduler:
"\<lbrace>globals_equiv_scheduler st and valid_arch_state and valid_idle\<rbrace>
activate_thread
\<lbrace>\<lambda>_. globals_equiv_scheduler st\<rbrace>"
by (wp globals_equiv_scheduler_inv' activate_thread_globals_equiv | force | fastforce)+
lemma schedule_cur_domain:
"\<lbrace>\<lambda>s. P (cur_domain s) \<and> domain_time s \<noteq> 0\<rbrace>
schedule
\<lbrace>\<lambda>_ s. P (cur_domain s)\<rbrace>"
(is "\<lbrace>?PRE\<rbrace> _ \<lbrace>_\<rbrace>")
supply hoare_pre_cont[where f=next_domain, wp add]
ethread_get_wp[wp del] if_split[split del] if_cong[cong]
apply (simp add: schedule_def schedule_choose_new_thread_def | wp | wpc)+
apply (rule_tac Q'="\<lambda>_. ?PRE" in hoare_strengthen_post)
apply (simp | wp gts_wp | wp (once) hoare_drop_imps)+
apply (rule_tac Q'="\<lambda>_. ?PRE" in hoare_strengthen_post)
apply (simp | wp gts_wp | wp (once) hoare_drop_imps)+
apply (rule_tac Q'="\<lambda>_. ?PRE" in hoare_strengthen_post)
apply (simp | wp gts_wp | wp (once) hoare_drop_imps)+
apply (clarsimp split: if_split)
done
lemma schedule_domain_fields:
"\<lbrace>domain_fields P and (\<lambda>s. domain_time s \<noteq> 0)\<rbrace>
schedule
\<lbrace>\<lambda>_. domain_fields P\<rbrace>"
(is "\<lbrace>?PRE\<rbrace> _ \<lbrace>_\<rbrace>")
supply hoare_pre_cont[where f=next_domain, wp add]
ethread_get_wp[wp del] if_split[split del] if_cong[cong]
apply (simp add: schedule_def schedule_choose_new_thread_def | wp | wpc)+
apply (rule_tac Q'="\<lambda>_. ?PRE" in hoare_strengthen_post)
apply (simp | wp gts_wp | wp (once) hoare_drop_imps)+
apply (rule_tac Q'="\<lambda>_. ?PRE" in hoare_strengthen_post)
apply (simp | wp gts_wp | wp (once) hoare_drop_imps)+
apply (rule_tac Q'="\<lambda>_. ?PRE" in hoare_strengthen_post)
apply (simp | wp gts_wp | wp (once) hoare_drop_imps)+
apply (clarsimp split: if_split)
done
lemma schedule_if_partitionIntegrity:
assumes domains_distinct: "pas_domains_distinct aag"
shows "\<lbrace>partitionIntegrity aag st and guarded_pas_domain aag and pas_cur_domain aag and
(\<lambda>s. domain_time s \<noteq> 0) and silc_inv aag st and einvs and pas_refined aag\<rbrace>
schedule_if tc
\<lbrace>\<lambda>_. partitionIntegrity aag st\<rbrace>"
apply (simp add: schedule_if_def)
apply (rule_tac Q'="\<lambda>rv s. integrity (aag\<lparr>pasMayActivate := False, pasMayEditReadyQueues := False\<rparr>)
(scheduler_affects_globals_frame st) st s \<and>
domain_fields_equiv st s \<and> idle_thread s = idle_thread st \<and>
globals_equiv_scheduler st s \<and> silc_dom_equiv aag st s"
in hoare_strengthen_post)
apply (wpsimp wp: activate_thread_integrity activate_thread_globals_equiv_scheduler
silc_dom_equiv_from_silc_inv_valid'[where P="\<top>"] schedule_integrity
hoare_vcg_all_lift domain_fields_equiv_lift[where Q="\<top>" and R="\<top>"])
apply (rule_tac Q'="\<lambda>r s. guarded_pas_domain aag s \<and> pas_cur_domain aag s \<and>
domain_fields_equiv st s \<and> idle_thread s = idle_thread st \<and>
globals_equiv_scheduler st s \<and> silc_inv aag st s \<and>
silc_dom_equiv aag st s \<and> invs s" in hoare_strengthen_post)
apply (wp schedule_guarded_pas_domain schedule_cur_domain
silc_dom_equiv_from_silc_inv_valid'[where P="\<top>" and st=st]
domain_fields_equiv_lift schedule_cur_domain schedule_domain_fields
| simp add: silc_inv_def partitionIntegrity_def guarded_pas_domain_def
invs_valid_idle silc_dom_equiv_def)+
apply (fastforce simp: equiv_for_refl dest: domains_distinct[THEN pas_domains_distinct_inj])
apply (fastforce simp: partitionIntegrity_def globals_equiv_scheduler_def)+
done
lemma partitionIntegrity_integrity:
"partitionIntegrity aag s s'
\<Longrightarrow> integrity (aag\<lparr>pasMayActivate := False, pasMayEditReadyQueues := False\<rparr>)
(scheduler_affects_globals_frame s) s s'"
by (clarsimp simp: partitionIntegrity_def)
lemma receive_blocked_on_eq:
"\<lbrakk> receive_blocked_on ep ts; receive_blocked_on ep' ts \<rbrakk>
\<Longrightarrow> ep = ep'"
by (case_tac ts; simp)
lemma receive_blocked_on_eq':
"\<lbrakk> receive_blocked_on ep ts; blocked_on ep' ts \<rbrakk>
\<Longrightarrow> ep = ep'"
by (case_tac ts; simp)
lemma receive_blocked_on_contradiction:
"\<lbrakk> receive_blocked_on ep ts; send_blocked_on ep' ts \<rbrakk>
\<Longrightarrow> False"
by (case_tac ts; simp)
lemma pas_refined_tcb_st_to_auth:
"\<lbrakk> pas_refined aag s; (ep, auth) \<in> tcb_st_to_auth (tcb_state tcb); kheap s p = Some (TCB tcb) \<rbrakk>
\<Longrightarrow> (pasObjectAbs aag p, auth, pasObjectAbs aag ep) \<in> pasPolicy aag"
apply (rule pas_refined_mem)
apply (rule_tac s=s in sta_ts)
apply (simp add: thread_st_auth_def tcb_states_of_state_def get_tcb_def)
apply assumption
done
(* FIXME DO _state abreviation for all elements and use them to write rule explicitely *)
lemmas integrity_subjects_obj =
integrity_subjects_def[THEN meta_eq_to_obj_eq, THEN iffD1, THEN conjunct1]
lemmas integrity_subjects_eobj =
integrity_subjects_def[THEN meta_eq_to_obj_eq, THEN iffD1, THEN conjunct2, THEN conjunct1]
lemmas integrity_subjects_cdt =
integrity_subjects_def[THEN meta_eq_to_obj_eq, THEN iffD1, THEN conjunct2, THEN conjunct2, THEN conjunct1]
lemmas integrity_subjects_cdt_list =
integrity_subjects_def[THEN meta_eq_to_obj_eq, THEN iffD1, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct1]
lemmas integrity_subjects_interrupts =
integrity_subjects_def[THEN meta_eq_to_obj_eq, THEN iffD1, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct1]
lemmas integrity_subjects_ready_queues =
integrity_subjects_def[THEN meta_eq_to_obj_eq, THEN iffD1, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct1]
lemmas integrity_subjects_mem =
integrity_subjects_def[THEN meta_eq_to_obj_eq, THEN iffD1, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct1]
lemmas integrity_subjects_device =
integrity_subjects_def[THEN meta_eq_to_obj_eq, THEN iffD1, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct1]
lemmas integrity_subjects_asids =
integrity_subjects_def[THEN meta_eq_to_obj_eq, THEN iffD1, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2, THEN conjunct2]
lemma pas_wellformed_pasSubject_update_Control:
"\<lbrakk> pas_wellformed (aag\<lparr>pasSubject := pasObjectAbs aag p\<rparr>);
(pasObjectAbs aag p, Control, pasObjectAbs aag p') \<in> pasPolicy aag \<rbrakk>
\<Longrightarrow> pasObjectAbs aag p = pasObjectAbs aag p'"
by (fastforce simp: policy_wellformed_def)
lemma pas_wellformed_noninterference_policy_refl:
"\<lbrakk> pas_wellformed_noninterference aag; pasObjectAbs aag x \<noteq> SilcLabel \<rbrakk>
\<Longrightarrow> (pasObjectAbs aag x, auth, pasObjectAbs aag x) \<in> pasPolicy aag"
unfolding pas_wellformed_noninterference_def
by (fastforce intro!:aag_wellformed_refl)
lemma pas_wellformed_noninterference_control_to_eq:
"\<lbrakk> pas_wellformed_noninterference aag;
(pasObjectAbs aag x, Control, l) \<in> pasPolicy aag; pasObjectAbs aag x \<noteq> SilcLabel \<rbrakk>
\<Longrightarrow> pasObjectAbs aag x = l"
unfolding pas_wellformed_noninterference_def
by (erule aag_wellformed_Control; fastforce)
(* FIXME: MOVE *)
lemma fun_noteqD:
"f \<noteq> g \<Longrightarrow> \<exists>a. f a \<noteq> g a"
by blast
locale Noninterference_1 =
fixes current_aag :: "det_state \<Rightarrow> 'a subject_label PAS"
and arch_globals_equiv_strengthener :: "machine_state \<Rightarrow> machine_state \<Rightarrow> bool"
assumes do_user_op_if_integrity:
"\<lbrace>invs and integrity aag X st and is_subject aag \<circ> cur_thread and pas_refined aag\<rbrace>
do_user_op_if uop tc
\<lbrace>\<lambda>_. integrity aag X st\<rbrace>"
and do_user_op_if_globals_equiv_scheduler:
"\<lbrace>globals_equiv_scheduler st and invs\<rbrace>
do_user_op_if uop tc
\<lbrace>\<lambda>_. globals_equiv_scheduler st\<rbrace>"
and do_user_op_if_silc_dom_equiv[wp]:
"do_user_op_if uop tc \<lbrace>silc_dom_equiv (aag :: 'a subject_label PAS) st\<rbrace>"
and sameFor_scheduler_affects_equiv:
"\<And>s s'. \<lbrakk> (s,s') \<in> same_for aag PSched; (s,s') \<in> same_for aag (Partition l');
invs (internal_state_if s); invs (internal_state_if s') \<rbrakk>
\<Longrightarrow> scheduler_equiv aag (internal_state_if s) (internal_state_if s') \<and>
scheduler_affects_equiv aag (OrdinaryLabel l')
(internal_state_if s) (internal_state_if s')"
and do_user_op_if_partitionIntegrity:
"\<And>aag :: 'a subject_label PAS.
\<lbrace>partitionIntegrity aag st and pas_refined aag and invs and is_subject aag \<circ> cur_thread\<rbrace>
do_user_op_if uop tc
\<lbrace>\<lambda>_. partitionIntegrity aag st\<rbrace>"
and arch_activate_idle_thread_reads_respects_g[wp]:
"reads_respects_g aag l \<top> (arch_activate_idle_thread t)"
and dmo_storeWord_reads_respects_g[wp]:
"reads_respects_g aag l \<top> (do_machine_op (storeWord ptr w))"
and integrity_asids_update_reference_state:
"is_subject aag t
\<Longrightarrow> integrity_asids aag {pasSubject aag} x asid s (s\<lparr>kheap := (kheap s)(t \<mapsto> blah)\<rparr>)"
and partitionIntegrity_subjectAffects_aobj:
"\<lbrakk> partitionIntegrity aag s s'; kheap s x = Some (ArchObj ao); kheap s x \<noteq> kheap s' x;
silc_inv aag st s; pas_refined aag s; pas_wellformed_noninterference aag \<rbrakk>
\<Longrightarrow> subject_can_affect_label_directly aag (pasObjectAbs aag x)"
and partitionIntegrity_subjectAffects_asid:
"\<lbrakk> partitionIntegrity aag s s'; pas_refined aag s; valid_objs s; valid_arch_state s;
valid_arch_state s'; pas_wellformed_noninterference aag; silc_inv aag st s'; invs s';
\<not> equiv_asids (\<lambda>x. pasASIDAbs aag x = a) s s'\<rbrakk>
\<Longrightarrow> a \<in> subjectAffects (pasPolicy aag) (pasSubject aag)"
and arch_switch_to_thread_reads_respects_g':
"equiv_valid (reads_equiv_g aag) (affects_equiv aag l)
(\<lambda>s s'. affects_equiv aag l s s' \<and>
arch_globals_equiv_strengthener (machine_state s) (machine_state s'))
(\<lambda>s. is_subject aag t) (arch_switch_to_thread t)"
and arch_globals_equiv_strengthener_thread_independent:
"arch_globals_equiv_strengthener (machine_state s) (machine_state s')
\<Longrightarrow> \<forall>ct ct' it it'. arch_globals_equiv ct it (kheap s) (kheap s')
(arch_state s) (arch_state s') (machine_state s) (machine_state s') =
arch_globals_equiv ct' it' (kheap s) (kheap s')
(arch_state s) (arch_state s') (machine_state s) (machine_state s')"
and ev2_invisible':
"\<lbrakk> pas_domains_distinct aag; labels_are_invisible aag l L; labels_are_invisible aag l L';
modifies_at_most aag L Q f; modifies_at_most aag L' Q' g;
doesnt_touch_globals Q f; doesnt_touch_globals Q' g;
\<And>st :: det_state. f \<lbrace>\<lambda>s. arch_globals_equiv_strengthener (machine_state st) (machine_state s)\<rbrace>;
\<And>st :: det_state. g \<lbrace>\<lambda>s. arch_globals_equiv_strengthener (machine_state st) (machine_state s)\<rbrace>;
\<forall>s t. P s \<and> P' t \<longrightarrow> (\<forall>(rva,s') \<in> fst (f s). \<forall>(rvb,t') \<in> fst (g t). W rva rvb) \<rbrakk>
\<Longrightarrow> equiv_valid_2 (reads_equiv_g aag)
(\<lambda>s s'. affects_equiv aag l s s' \<and>
arch_globals_equiv_strengthener (machine_state s) (machine_state s'))
(\<lambda>s s'. affects_equiv aag l s s' \<and>
arch_globals_equiv_strengthener (machine_state s) (machine_state s'))
(W :: unit \<Rightarrow> unit \<Rightarrow> bool) (P and Q) (P' and Q') f g"
and arch_switch_to_idle_thread_reads_respects_g[wp]:
"reads_respects_g aag l \<top> (arch_switch_to_idle_thread)"
and arch_globals_equiv_threads_eq:
"arch_globals_equiv t' t'' kh kh' as as' ms ms'
\<Longrightarrow> arch_globals_equiv t t kh kh' as as' ms ms'"
and arch_globals_equiv_globals_equiv_scheduler[elim]:
"arch_globals_equiv (cur_thread s') (idle_thread s) (kheap s) (kheap s')
(arch_state s) (arch_state s') (machine_state s) (machine_state s')
\<Longrightarrow> arch_globals_equiv_scheduler (kheap s) (kheap s') (arch_state s) (arch_state s')"
and getActiveIRQ_ret_no_dmo[wp]:
"\<lbrace>\<top>\<rbrace> getActiveIRQ in_kernel \<lbrace>\<lambda>rv s. \<forall>x. rv = Some x \<longrightarrow> x \<le> maxIRQ\<rbrace>"
and dmo_getActive_IRQ_reads_respect_scheduler:
"reads_respects_scheduler aag l (\<lambda>s. irq_masks_of_state st = irq_masks_of_state s)
(do_machine_op (getActiveIRQ in_kernel))"
(* FIXME IF: precludes ARM_HYP *)
and getActiveIRQ_no_non_kernel_IRQs:
"getActiveIRQ True = getActiveIRQ False"
begin
lemma integrity_update_reference_state:
"\<lbrakk> is_subject aag t; integrity aag X st s; st = st'\<lparr>kheap := (kheap st')(t \<mapsto> blah)\<rparr> \<rbrakk>
\<Longrightarrow> integrity (aag :: 'a subject_label PAS) X st' s"
apply (erule integrity_trans[rotated])
apply (clarsimp simp: integrity_def opt_map_def integrity_asids_update_reference_state)
done
(* lots of ugly hackery because handle_event_integrity wants the reference state to
be identical to the initial one, but it isn't because we first update the
context of cur_thread *)
lemma kernel_entry_if_integrity:
"\<lbrace>einvs and schact_is_rct and pas_refined aag and is_subject aag \<circ> cur_thread
and domain_sep_inv (pasMaySendIrqs aag) st' and guarded_pas_domain aag
and (\<lambda>s. e \<noteq> Interrupt \<longrightarrow> ct_active s) and (=) st\<rbrace>
kernel_entry_if e tc
\<lbrace>\<lambda>_. integrity (aag :: 'a subject_label PAS) X st\<rbrace>"
unfolding kernel_entry_if_def
apply wp
apply (rule valid_validE)
apply (rule_tac Q'="\<lambda>_ s. integrity aag X (st\<lparr>kheap :=
(kheap st)(cur_thread st \<mapsto> TCB (tcb_arch_update (arch_tcb_context_set tc)
(the (get_tcb (cur_thread st) st))))\<rparr>) s
\<and> is_subject aag (cur_thread s)
\<and> cur_thread s = cur_thread st" in hoare_strengthen_post)
apply (wp handle_event_integrity handle_event_cur_thread | simp)+
apply (fastforce intro: integrity_update_reference_state)
apply (wp thread_set_integrity_autarch thread_set_pas_refined guarded_pas_domain_lift
thread_set_invs_trivial thread_set_not_state_valid_sched
| simp add: tcb_cap_cases_def schact_is_rct_def arch_tcb_update_aux2)+
apply (wp (once) prop_of_two_valid[where f="ct_active" and g="cur_thread"])
apply (wp | simp)+
apply (wp thread_set_tcb_context_update_wp)+
apply (clarsimp simp: schact_is_rct_def)
apply (rule conjI)
apply (erule integrity_update_reference_state[where blah="the (kheap st (cur_thread st))",
OF _ integrity_refl])
apply simp
apply (subgoal_tac "kheap st (cur_thread st) \<noteq> None")
apply clarsimp
apply (drule tcb_at_invs, clarsimp simp: tcb_at_def get_tcb_def
split: kernel_object.splits option.splits)
apply (clarsimp simp: invs_psp_aligned invs_vspace_objs invs_arch_state)
apply (rule conjI)
apply assumption
apply (rule state.equality, simp_all)
apply (rule ext, simp_all)
done
lemma kernel_entry_if_partitionIntegrity:
"\<lbrace>silc_inv aag st and pas_refined aag and einvs and schact_is_rct
and is_subject aag \<circ> cur_thread and domain_sep_inv (pasMaySendIrqs aag) st'
and guarded_pas_domain aag and (\<lambda>s. ev \<noteq> Interrupt \<and> ct_active s) and (=) st\<rbrace>
kernel_entry_if ev tc
\<lbrace>\<lambda>_. partitionIntegrity (aag :: 'a subject_label PAS) st\<rbrace>"
apply (rule_tac Q'="\<lambda>rv s. (\<forall>X. integrity (aag\<lparr>pasMayActivate := False,
pasMayEditReadyQueues := False\<rparr>) X st s) \<and>
domain_fields_equiv st s \<and> globals_equiv_scheduler st s \<and>
idle_thread s = idle_thread st \<and> silc_dom_equiv aag st s"
in hoare_strengthen_post)
apply (wp hoare_vcg_conj_lift)
apply (rule hoare_vcg_all_lift[OF kernel_entry_if_integrity[where st'=st']])
apply (wp kernel_entry_if_cur_thread kernel_entry_if_globals_equiv_scheduler
kernel_entry_if_cur_domain domain_fields_equiv_lift[where R="\<top>"]
kernel_entry_if_domain_fields | simp)+
apply (rule_tac P="pas_refined aag and einvs and schact_is_rct and
is_subject aag \<circ> cur_thread and domain_sep_inv (pasMaySendIrqs aag) st' and
(\<lambda> s. ev \<noteq> Interrupt \<longrightarrow> ct_active s)"
in silc_dom_equiv_from_silc_inv_valid')
apply (wp kernel_entry_silc_inv[where st'=st'], simp add: schact_is_rct_simple)
apply (fastforce simp: pas_refined_pasMayActivate_update pas_refined_pasMayEditReadyQueues_update
globals_equiv_scheduler_refl silc_dom_equiv_def equiv_for_refl
domain_fields_equiv_def ct_active_not_idle')
apply (fastforce simp: partitionIntegrity_def)
done
text \<open>
This a very important theorem that ensures that @{const subjectAffects} is
coherent with @{const integrity_obj}
\<close>
lemma partitionIntegrity_subjectAffects_obj:
assumes par_inte: "partitionIntegrity (aag :: 'a subject_label PAS) s s'"
assumes pas_ref: "pas_refined aag s"
assumes invs: "invs s"
assumes pwni: "pas_wellformed_noninterference aag"
assumes silc_inv: "silc_inv aag st s"
assumes kh_diff: "kheap s x \<noteq> kheap s' x"
notes inte_obj = par_inte[THEN partitionIntegrity_integrity, THEN integrity_subjects_obj,
THEN spec[where x=x], simplified integrity_obj_def, simplified]
shows "pasObjectAbs aag x \<in> subjectAffects (pasPolicy aag) (pasSubject aag)"
proof -
show ?thesis
using inte_obj
proof (induct "kheap s x" rule: converse_rtranclp_induct)
case base
thus ?case using kh_diff by force
next
case (step z)
note troa = step.hyps(1)
show ?case
proof (cases "z = kheap s x")
case True
thus ?thesis using step.hyps by blast
next
case False
note hyps = this pwni pas_ref invs silc_inv kh_diff
hence sym_helper: "\<And>auth tcb. kheap s x = Some (TCB tcb) \<Longrightarrow>
(pasObjectAbs aag x, auth, pasObjectAbs aag x) \<in> pasPolicy aag"
by (fastforce elim!: pas_wellformed_noninterference_policy_refl
silc_inv_cnode_onlyE obj_atE
simp: is_cap_table_def)
show ?thesis
using troa
proof (cases rule: integrity_obj_atomic.cases)
case troa_lrefl
thus ?thesis by (fastforce intro: subjectAffects.intros)
next
case (troa_ntfn ntfn ntfn' auth s)
thus ?thesis by (fastforce intro: affects_ep)
next
case (troa_ep ep ep' auth s)
thus ?thesis by (fastforce intro: affects_ep)
next
case (troa_ep_unblock ep ep' tcb ntfn)
thus ?thesis by (fastforce intro: affects_ep_bound_trans)
next
case (troa_tcb_send tcb tcb' ctxt' ep)
thus ?thesis using hyps
apply (clarsimp simp: direct_send_def indirect_send_def)
apply (erule disjE)
apply (clarsimp simp: receive_blocked_on_def2)
apply (frule (2) pas_refined_tcb_st_to_auth)
apply (fastforce intro!: affects_send sym_helper)
apply (fastforce intro!: affects_send bound_tcb_at_implies_receive
pred_tcb_atI sym_helper)
done
next
case (troa_tcb_call tcb tcb' caller R ctxt' ep)
thus ?thesis using hyps
apply (clarsimp simp add: direct_call_def ep_recv_blocked_def)
apply (rule affects_send[rotated 2])
apply (erule (1) pas_refined_tcb_st_to_auth[rotated 2]; force)
apply (fastforce intro: sym_helper)
apply assumption
apply blast
done
next
case (troa_tcb_reply tcb tcb' new_st ctxt')
thus ?thesis using hyps
apply clarsimp
apply (erule affects_reply)
by (rule sym_helper)
next
case (troa_tcb_receive tcb tcb' new_st ep)
thus ?thesis using hyps
by (auto intro: affects_recv pas_refined_tcb_st_to_auth simp: send_blocked_on_def2)
next
case (troa_tcb_restart tcb tcb' ep)
thus ?thesis using hyps
by (fastforce intro: affects_reset[where auth=Receive] affects_reset[where auth=SyncSend]
elim: blocked_on.elims pas_refined_tcb_st_to_auth[rotated 2]
intro!: sym_helper)
next
case (troa_tcb_unbind tcb tcb')
thus ?thesis using hyps
apply -
by (cases "tcb_bound_notification tcb" ;
fastforce intro: affects_reset[where auth=Receive] bound_tcb_at_implies_receive
pred_tcb_atI sym_helper)
next
case (troa_tcb_empty_ctable tcb tcb' cap')
thus ?thesis using hyps
apply (clarsimp simp:reply_cap_deletion_integrity_def; elim disjE; clarsimp)
apply (rule affects_delete_derived)
apply (rule aag_wellformed_delete_derived[rotated -1, OF pas_refined_wellformed],
assumption)
apply (frule cap_auth_caps_of_state[rotated,where p ="(x,tcb_cnode_index 0)"],
force simp: caps_of_state_def')
by (fastforce simp: aag_cap_auth_def cap_auth_conferred_def reply_cap_rights_to_auth_def
split: if_splits)
next
case (troa_tcb_empty_caller tcb tcb' cap')
thus ?thesis using hyps
apply (clarsimp simp:reply_cap_deletion_integrity_def)
apply (elim disjE; clarsimp)
apply (rule affects_delete_derived)
apply (rule aag_wellformed_delete_derived[rotated -1, OF pas_refined_wellformed],
assumption)
apply (frule cap_auth_caps_of_state[rotated,where p ="(x,tcb_cnode_index 3)"],
force simp: caps_of_state_def')
by (fastforce simp: aag_cap_auth_def cap_auth_conferred_def
reply_cap_rights_to_auth_def
split: if_splits)
next
case (troa_tcb_activate tcb tcb')
thus ?thesis by blast
next
case (troa_arch ao ao')
thus ?thesis
using assms by (fastforce dest: partitionIntegrity_subjectAffects_aobj)
next
case (troa_cnode n content content')
thus ?thesis
using hyps unfolding cnode_integrity_def
apply clarsimp
apply (drule fun_noteqD)
apply (erule exE, rename_tac l)
apply (drule_tac x=l in spec)
apply (clarsimp dest!:not_sym[where t=None])
apply (clarsimp simp:reply_cap_deletion_integrity_def)
apply (rule affects_delete_derived)
apply (rule aag_wellformed_delete_derived[rotated -1, OF pas_refined_wellformed],
assumption)
apply (frule_tac p="(x,l)" in cap_auth_caps_of_state[rotated])
apply (force simp: caps_of_state_def' intro:well_formed_cnode_invsI)
by (fastforce simp: aag_cap_auth_def cap_auth_conferred_def
reply_cap_rights_to_auth_def
split: if_splits)
qed
qed
qed
qed
end
lemma kheap_ep_tcb_states_of_state_eq:
"kheap s x = kheap s' x \<Longrightarrow> tcb_states_of_state s x = tcb_states_of_state s' x"
unfolding tcb_states_of_state_def get_tcb_def by simp
lemma partitionIntegrity_subjectAffects_mem:
assumes par_inte: "partitionIntegrity aag s s'"
assumes pas_ref: "pas_refined aag s"
assumes invs: "invs s"
assumes um_diff:
"underlying_memory (machine_state s) x \<noteq> underlying_memory (machine_state s') x"
notes inte_mem =
par_inte[THEN partitionIntegrity_integrity, THEN integrity_subjects_mem, THEN spec[where x=x]]
shows
"pasObjectAbs aag x \<in> subjectAffects (pasPolicy aag) (pasSubject aag)"
using inte_mem
proof (cases rule: integrity_mem.cases)
case trm_lrefl
thus ?thesis by (fastforce intro: affects_lrefl)
next
case trm_orefl
thus ?thesis using um_diff by blast
next
case trm_write
thus ?thesis by (fastforce intro: affects_write)
next
case trm_globals
thus ?thesis by blast
next
case (trm_ipc p) note trm_ipc_hyps = this
then obtain tcbst where "tcb_states_of_state s p = Some tcbst" "can_receive_ipc tcbst"
by (force split:option.splits)
note hyps = this trm_ipc_hyps(2-)[simplified] pas_ref invs um_diff
from par_inte[THEN partitionIntegrity_integrity, THEN integrity_subjects_obj,
THEN spec[where x=p], THEN tro_tro_alt]
show ?thesis
proof (cases rule: integrity_obj_alt.cases)
case (tro_alt_tcb_send tcb tcb' ccap' cap' ntfn' ep)
thus ?thesis using hyps
apply (clarsimp simp: direct_send_def indirect_send_def)
apply (erule disjE)
apply (clarsimp simp: receive_blocked_on_def2)
apply (frule (2) pas_refined_tcb_st_to_auth)
apply (fastforce intro!: affects_send auth_ipc_buffers_mem_Write')
apply clarsimp
apply (rule affects_send[rotated 2])
apply (fastforce intro!: affects_send bound_tcb_at_implies_receive pred_tcb_atI
dest: sym)
apply (fastforce intro!: auth_ipc_buffers_mem_Write')
apply assumption
apply blast
done
next
case (tro_alt_tcb_call tcb tcb' ccap' cap' ntfn' caller R ep)
thus ?thesis using hyps
apply (clarsimp simp add: direct_call_def ep_recv_blocked_def)
apply (rule affects_send[rotated 2])
apply (erule (1) pas_refined_tcb_st_to_auth[rotated 2]; force)
apply (fastforce intro!: auth_ipc_buffers_mem_Write')
apply assumption
apply blast
done
next
case (tro_alt_tcb_reply tcb tcb' ccap' cap' ntfn' new_st)
thus ?thesis using hyps
apply (clarsimp simp: direct_reply_def)
apply (erule affects_reply)
by (force intro: auth_ipc_buffers_mem_Write')
next
case (tro_alt_tcb_receive tcb tcb' ccap' cap' ntfn' new_st ep)
thus ?thesis using hyps
apply (clarsimp elim!: tcb_states_of_state_kheapE send_blocked_on.elims
can_receive_ipc.elims)
apply (frule (1) pas_refined_tcb_st_to_auth[rotated 2,where auth=Call and ep =ep])
apply force
apply (rule affects_reply)
apply (erule (1) aag_wellformed_reply, force)
apply (fastforce intro!: auth_ipc_buffers_mem_Write')
done
next
case (tro_alt_tcb_restart tcb tcb' ccap' cap' ntfn' ep)
thus ?thesis using hyps
by (fastforce intro: affects_reset[where auth=Receive] affects_reset[where auth=SyncSend]
elim: blocked_on.elims pas_refined_tcb_st_to_auth[rotated 2]
intro!: auth_ipc_buffers_mem_Write')
qed (insert hyps, force elim: tcb_states_of_state_kheapE)+
qed
lemma partitionIntegrity_subjectAffects_cdt:
"\<lbrakk> partitionIntegrity aag s s'; pas_refined aag s;