Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --- FastVerifier.v 2017-05-27 18:45:35.000000000 -0500
- +++ FastVerifier_new.v 2017-06-07 19:36:57.000000000 -0500
- @@ -114,6 +114,25 @@
- end
- end.
- +(* --------------------------------- *)
- +Fixpoint process_buffer_align (loc: int32) (n: nat) (tokens:list token_id)
- + (curr_res: Int32Set.t * Int32Set.t) :=
- + let (start_instrs, check_list) := curr_res in
- + match tokens with
- + | nil => Some curr_res
- + | _ => (* There are left over bytes in the buffer *)
- + match n with
- + | O => None
- + | S p =>
- + match process_buffer_aux loc n tokens (start_instrs, check_list) with
- + | None => None
- + | Some (start_instrs_new, check_list_new) => process_buffer_align ( loc +32_n Z.to_nat chunkSize) p (skipn (Z.to_nat chunkSize) tokens)
- + (start_instrs_new, check_list_new)
- + end
- + end
- + end.
- +(* --------------------------------- *)
- +
- (* The idea here is, given a list of int8s representing the code,
- we call process_buffer_aux with n := length of the list;
- since each instruction is at least one byte long, this should
- @@ -123,7 +142,7 @@
- at least one byte.
- *)
- Definition process_buffer (buffer: list int8) :=
- - process_buffer_aux (Word.repr 0) (length buffer) (List.map byte2token buffer)
- + process_buffer_align (Word.repr 0) (length buffer) (List.map byte2token buffer)
- (Int32Set.empty, Int32Set.empty).
- Definition aligned_bool (a:int32):bool :=
- @@ -179,11 +198,18 @@
- (checkJmpTargets check_addrs start_addrs),
- start_addrs)
- end.
- -
- +(*
- +Compute process_buffer_aux (Word.repr 0) (length buffer) (List.map byte2token buffer)
- + (Int32Set.empty, Int32Set.empty).
- +Compute (checkProgram (nil) ).
- +*)
- End BUILT_DFAS.
- Definition ncflow := make_dfa non_cflow_grammar.
- Definition dbranch := make_dfa (alts dir_cflow).
- Definition ibranch := make_dfa (alts nacljmp_mask).
- -
- +(*
- +Check checkProgram.
- +Variable initial_state : ParseState_t.
- +(*Compute (checkProgram ncflow dbranch ibranch initial_state ( (repr 55) ::nil)).*) *)
- (*Extraction "fastverif.ml" checkProgram ncflow dbranch ibranch.*)
- --- VerifierCorrectness.v 2017-05-27 18:45:35.000000000 -0500
- +++ VerifierCorrectness_new.v 2017-06-07 19:36:57.000000000 -0500
- @@ -388,6 +388,12 @@
- FastVerifier.process_buffer non_cflow_dfa dir_cflow_dfa nacljmp_dfa
- initial_state.
- +(*---------------------------------------*)
- + Definition process_buffer_align :=
- + FastVerifier.process_buffer_align non_cflow_dfa dir_cflow_dfa nacljmp_dfa
- + initial_state.
- +(*---------------------------------------------*)
- +
- (* Checks whether the memory of s starting at addr_offset is equal
- to buffer *)
- Definition eqMemBuffer (buffer: list int8) (s: rtl_state) (addr_offset: int32) :=
- @@ -836,6 +842,15 @@
- int32_to_Z_tac. crush.
- Qed.
- + Lemma Int32Set_diff_diff_dichotomy : forall x A B C,
- + Int32Set.In x (Int32Set.diff A C)
- + -> (Int32Set.In x (Int32Set.diff A B) \/
- + Int32Set.In x (Int32Set.diff B C)).
- + Proof.
- + intros. do 2 rewrite Int32Set.diff_spec in *.
- + tauto.
- + Qed.
- +
- (** *** Properties of process_buffer *)
- (* process buffer prover *)
- @@ -951,7 +966,299 @@
- apply IHn with (pc:=pc) in H; try (assumption || omega). clear IHn.
- int32_simplify. lia.
- Qed.
- +(*------------------------------*)
- +
- +(* The way _align uses skipn seems to require some more "obvious" facts
- + about skipn than already exist in Coqlib.v: *)
- +
- +(* It would seem to me the intuitive way to reason about skipn to have
- + an induction scheme that decrements n and cdrs down l in lockstep.
- + But I don't know how to do that in Coq yet, so the next three lemmas
- + (only the 3rd of which turns out to be needed) all do nested induction
- + where we use the outer hypothesis in the inner case. *)
- +
- +(*
- +Lemma skipn_empty1 : forall (A : Type) (n:nat) (l : list A),
- + (skipn n l) = nil -> (n >= (length l))%nat.
- +Proof.
- + intros A.
- + induction n as [| n'].
- + Case "n = 0". intros l. simpl. intros H. rewrite H. simpl. apply le_n.
- + Case "n = S n".
- + intros l.
- + induction l as [| a r].
- + SCase "l = nil". simpl. omega.
- + SCase "l = a :: r". simpl.
- + intros Hnil.
- + generalize (IHn' r). intros Ihnr.
- + pose (Ihnr Hnil).
- + omega.
- +Qed.
- +
- +Lemma skipn_empty2 : forall (A : Type) (l : list A) (n : nat),
- + (n >= (length l))%nat -> (skipn n l) = nil.
- +Proof.
- + intros A.
- + induction l as [| a r].
- + Case "l = nil". simpl. intros n H.
- + destruct n as [| n']; reflexivity.
- + Case "l = a :: r".
- + simpl. intros n Hlen.
- + destruct n as [| n'].
- + SCase "n = 0".
- + contradict Hlen. omega.
- + SCase "n = S n'".
- + simpl. apply IHr. omega.
- +Qed.
- +*)
- +Lemma skipn_nonempty1: forall (A : Type) (l : list A) (n : nat),
- + (skipn n l) <> nil -> (n < length l)%nat.
- +Proof.
- + intros A.
- + induction l as [| a r].
- + Case "l = nil".
- + simpl. intros n. destruct n as [| n'].
- + SCase "n = 0". intros H. contradict H. reflexivity.
- + SCase "n = S n'". intros H. contradict H. reflexivity.
- + Case "l = a :: r".
- + simpl. intros n Hlen.
- + destruct n as [| n'].
- + SCase "n = 0". omega.
- + SCase "n = S n'".
- + simpl in Hlen.
- + assert (n' < length r)%nat by (apply IHr; assumption).
- + omega.
- +Qed.
- +
- +Lemma skipn_length2 : forall (k n:nat) (A : Type) (l : list A),
- + (length (skipn n l)) = S k -> (length l) = (S k + n)%nat.
- +Proof.
- + intros k n A l.
- + generalize (firstn_skipn n l). intros Hfnsn.
- + assert(Hlfs: length (firstn n l ++ skipn n l) = length l)
- + by (f_equal; assumption).
- + rewrite app_length in Hlfs.
- + generalize (firstn_length n l). intros Hlf.
- + intros Hminlen.
- + replace (min n (length l)) with n in Hlf.
- + omega.
- + Case "Length condition".
- + symmetry. apply min_l.
- + generalize (skipn_nonempty1 _ l n). intros Hsne.
- + assert(Hnonempty: skipn n l <> nil).
- + SCase "skipn nonempty".
- + destruct (skipn n l) eqn:Hskipnl.
- + SSCase "skipn is empty (can't happen)".
- + contradict Hminlen. discriminate.
- + SSCase "skipn nonempty". discriminate.
- + generalize(Hsne Hnonempty).
- + omega.
- +Qed.
- +
- +(* The next two lemmas let you reason about inequalities in terms of
- + the existentially-quantified difference between the sides. I presume
- + there must be something like somewhere in Coq's libraries, but it
- + was easier to recreate than search for. *)
- +Lemma ge_to_ex : forall n m : nat,
- + (n >= m)%nat <-> (exists d, n = m + d)%nat.
- +Proof.
- + intros n m.
- + split.
- + Case "->".
- + intros Hge.
- + exists (n - m)%nat.
- + omega.
- + Case "<-".
- + intros Hexd.
- + destruct Hexd as [d].
- + omega.
- +Qed.
- +
- +Lemma gt_to_ex : forall n m : nat,
- + (n > m)%nat <-> (exists d, n = S (m + d))%nat.
- +Proof.
- + intros n m.
- + split.
- + Case "->".
- + intros Hgt.
- + exists (n - m - 1)%nat.
- + omega.
- + Case "<-".
- + intros Hexd.
- + destruct Hexd as [d].
- + omega.
- +Qed.
- +
- +Lemma skipn_length3 : forall (n : nat) (A : Type) (l : list A),
- + (length (skipn n l) >= 1)%nat -> ((length l) > n)%nat.
- +Proof.
- + intros n A l.
- + intros Hskipn.
- + rewrite ge_to_ex in Hskipn.
- + destruct Hskipn as [d].
- + replace (1+d)%nat with (S d) in H by reflexivity.
- + rewrite gt_to_ex.
- + exists d.
- + replace (S (n + d)) with (S d + n)%nat by omega.
- + apply skipn_length2. assumption.
- +Qed.
- +
- +(*
- +Lemma Z_of_to_nat : forall z,
- + (0 <= z) -> Z.of_nat (Z.to_nat z) = z.
- +Proof.
- + intros z.
- + intros Hzge0.
- + apply Z2Nat.id. assumption.
- +Qed.
- +*)
- +
- +(* An apparent gap in the existing tactics for reasoning about mixtures
- + of naturals and integers. *)
- +Lemma misc_z_n_conv_rewrite : forall n z1 z2,
- + (z2 >= 0) -> z1 + Z.of_nat (Z.to_nat z2 + n) = z1 + z2 + Z.of_nat n.
- +Proof.
- + intros n z1 z2.
- + intros Hz2ge0.
- + autorewrite with nat_to_Z.
- + rewrite Z2Nat.id. lia. lia.
- +Qed.
- +
- +Lemma process_buffer_align_addrRange :
- + forall n start tokens currStartAddrs currJmpTargets
- + allStartAddrs allJmpTargets pc,
- + process_buffer_align start n tokens (currStartAddrs, currJmpTargets) =
- + Some(allStartAddrs, allJmpTargets)
- + -> noOverflow (start :: int32_of_nat (length tokens - 1) :: nil)
- + -> Z_of_nat (length tokens) <= w32modulus
- + -> Int32Set.In pc (Int32Set.diff allStartAddrs currStartAddrs)
- + -> unsigned start <= unsigned pc
- + < unsigned start + Z_of_nat (length tokens).
- + Proof. induction n. intros.
- + Case "n=0". intros. destruct tokens; pbprover.
- + Case "S n".
- + intros until 0. intros HretSome HnoOverF HtokBound HpcAdded.
- + destruct tokens as [| t tokens']. SCase "tokens=nil". pbprover.
- + SCase "tokens<>nil".
- + assert (HtokensLen: ((length (t::tokens') >= 1))%nat) by (simpl; omega).
- + destruct (FastVerifier.process_buffer_aux non_cflow_dfa dir_cflow_dfa
- + nacljmp_dfa initial_state start (S n) (t :: tokens')
- + (currStartAddrs, currJmpTargets)) as [res_pair|] eqn:Hpb_aux.
- + SSCase "pb_aux = Some".
- + destruct res_pair as [start_instrs_new check_list_new].
- + destruct (@Int32Set_diff_diff_dichotomy
- + pc _ start_instrs_new _ HpcAdded)
- + as [Hdiff1|Hdiff2].
- + SSSCase "pc added in recursion".
- + use_lemma (IHn (start +32_n Z.to_nat chunkSize)
- + (skipn (Z.to_nat chunkSize) (t :: tokens'))
- + start_instrs_new check_list_new
- + allStartAddrs allJmpTargets pc) by assumption.
- + rename H into IH.
- + (* Most of the work in using the induction hypothesis has
- + to do with the side conditions that avoid overflow, and
- + proving that the address range condition translates properly,
- + which I haven't been able to automate very much. The
- + process_buffer_arith_facts lemma applies, but you need to
- + establish its hypotheses. Here I do that mostly by assert()s,
- + which was convenient for debugging but is not the
- + most concise. *)
- + assert(HskipLen: (length (skipn (Z.to_nat chunkSize)
- + (t :: tokens')) >= 1)%nat).
- + SSSSCase "skipn chunkSize >= 1".
- + unfold process_buffer_align,
- + FastVerifier.process_buffer_align in HretSome.
- + rewrite Hpb_aux in HretSome.
- + assert(HnoPcContra:
- + ~(Some (start_instrs_new, check_list_new) =
- + Some (allStartAddrs, allJmpTargets))).
- + SSSSSCase "Proof of HnoPcContra".
- + injection. intros HnoCLN HnoSIN.
- + rewrite HnoSIN in Hdiff1. contradict Hdiff1.
- + rewrite Int32Set.diff_spec. tauto.
- + destruct n as [| p],
- + (skipn (Z.to_nat chunkSize) (t :: tokens'))
- + as [|tokens''] eqn:Hskipped.
- + SSSSSCase "n = 0, skipn = nil".
- + contradict HnoPcContra. assumption.
- + SSSSSCase "n = 0, skipn <> nil".
- + contradict HretSome. discriminate.
- + SSSSSCase "n = S p, skipn = nil".
- + contradict HnoPcContra. assumption.
- + SSSSSCase "n = Sp, skipn <> nil".
- + simpl. omega.
- + generalize
- + (skipn_length3 (Z.to_nat chunkSize) _ (t :: tokens')).
- + intros Hlen3.
- + generalize (Hlen3 HskipLen). intros Hgt32.
- + assert(H32pskip: (length (t :: tokens') = (Z.to_nat chunkSize +
- + length (skipn (Z.to_nat chunkSize) (t :: tokens'))))%nat).
- + SSSSCase "|tokens|=32+|rest|".
- + use_lemma (@skipn_length (Z.to_nat chunkSize)
- + _ (t :: tokens')) by assumption.
- + rename H into Hskipnl.
- + rewrite plus_comm. symmetry. apply Hskipnl.
- + use_lemma (process_buffer_arith_facts start
- + (Z.to_nat chunkSize) (t :: tokens')
- + (skipn (Z.to_nat chunkSize) (t :: tokens')))
- + by assumption.
- + break_hyp.
- + rename H into HnoOverFStartP32.
- + rename H0 into HnoOverFStartPlen.
- + rename H1 into HrestBound.
- + assert(IHC: unsigned (start +32_n Z.to_nat chunkSize)
- + <= unsigned pc
- + < unsigned (start +32_n Z.to_nat chunkSize) +
- + Z.of_nat (length (skipn (Z.to_nat chunkSize)
- + (t :: tokens')))).
- + SSSSCase "Proof of IH conclusion".
- + apply IH.
- + SSSSSCase "pba returns Some".
- + unfold process_buffer_align,
- + FastVerifier.process_buffer_align in HretSome.
- + rewrite Hpb_aux in HretSome. exact HretSome.
- + SSSSSCase "noOverflow". assumption.
- + SSSSSCase "|rem. tokens|<2**32". assumption.
- + SSSSSCase "pc added in recursion". exact Hdiff1.
- + assert(Hadd: unsigned start + chunkSize =
- + (unsigned (start +32_n Z.to_nat chunkSize))).
- + SSSSCase "Proving no overflow".
- + symmetry. apply noOverflow_2_iff. assumption.
- + rewrite <- Hadd in IHC.
- + destruct IHC as [IHC1 IHC2].
- + split.
- + SSSSCase "start <= pc".
- + generalize (chunkSize_gt_0). omega.
- + SSSSCase "pc < start + length".
- + replace (length (t :: tokens')) with
- + (Z.to_nat chunkSize +
- + (length (skipn (Z.to_nat chunkSize)
- + (t :: tokens'))))%nat
- + by apply skipn_length.
- + assert(HcsGt0: chunkSize >= 0)
- + by (generalize chunkSize_gt_0; omega).
- + rewrite misc_z_n_conv_rewrite by assumption.
- + exact IHC2.
- + SSSCase "pc added in aux".
- + apply process_buffer_aux_addrRange with (n:=(S n))
- + (currStartAddrs:=currStartAddrs)
- + (currJmpTargets:=currJmpTargets)
- + (allStartAddrs:=start_instrs_new)
- + (allJmpTargets:=check_list_new).
- + SSSSCase "pba returns Some".
- + unfold process_buffer_aux. exact Hpb_aux.
- + SSSSCase "noOverflow". exact HnoOverF.
- + SSSSCase "|tokens|<2**32". exact HtokBound.
- + SSSSCase "pc added in aux". exact Hdiff2.
- + SSCase "pb_aux = None".
- + unfold process_buffer_align,
- + FastVerifier.process_buffer_align in HretSome.
- + rewrite Hpb_aux in HretSome.
- + contradict HretSome. discriminate.
- +Qed.
- +
- +(*--------------------------*)
- Lemma process_buffer_addrRange : forall buffer startAddrs jmpTargets pc,
- process_buffer buffer = Some (startAddrs, jmpTargets)
- -> Z_of_nat (length buffer) <= w32modulus
- @@ -967,7 +1274,7 @@
- int32_simplify. simpl. rewrite int32_modulus_constant. omega.
- assert (length (b::buffer') >= 1)%nat by (simpl; omega).
- int32_prover.
- - apply process_buffer_aux_addrRange with (pc:=pc) in H;
- + apply process_buffer_align_addrRange with (pc:=pc) in H;
- [idtac | assumption | (rewrite list_length_map; trivial) | pbprover].
- rewrite list_length_map in *; int32_prover.
- Qed.
- @@ -1020,7 +1327,38 @@
- apply Int32Set_subset_add.
- Qed.
- - Lemma process_buffer_aux_start_in :
- + Lemma process_buffer_align_subset :
- + forall n start tokens currStartAddrs currJmpTargets allStartAddrs allJmpTargets,
- + process_buffer_align start n tokens (currStartAddrs, currJmpTargets) =
- + Some (allStartAddrs, allJmpTargets)
- + -> Int32Set.Subset currStartAddrs allStartAddrs /\
- + Int32Set.Subset currJmpTargets allJmpTargets.
- +
- +Proof. induction n. intros.
- + Case "n=0". intros. destruct tokens; pbprover.
- + Case "S n". intros.
- + destruct tokens as [| t tokens']. pbprover.
- + SCase "tokens<>nil".
- + unfold process_buffer_align, FastVerifier.process_buffer_align in H.
- + destruct (FastVerifier.process_buffer_aux non_cflow_dfa dir_cflow_dfa nacljmp_dfa
- + initial_state start (S n) (t :: tokens')
- + (currStartAddrs, currJmpTargets)) as [res_pair|] eqn:Hpba.
- + SSCase "_aux_res <> None".
- + destruct res_pair as [start_insn_new check_list_new].
- + use_lemma process_buffer_aux_subset by eassumption.
- + use_lemma IHn by eassumption.
- + intuition.
- + eapply Int32SetFacts.Subset_trans; [idtac | eassumption].
- + assumption.
- + eapply Int32SetFacts.Subset_trans; [idtac | eassumption].
- + assumption.
- + SSCase "_aux_res is None".
- + discriminate.
- +Qed.
- +
- +(* Admitted.*)
- +
- + Lemma process_buffer_aux_start_in :
- forall n start tokens currStartAddrs currJmpTargets allStartAddrs allJmpTargets,
- process_buffer_aux start n tokens (currStartAddrs, currJmpTargets) =
- Some(allStartAddrs, allJmpTargets)
- @@ -1049,12 +1387,39 @@
- apply H2. apply Int32SetFacts.add_1. apply int_eq_refl.
- Qed.
- + Lemma process_buffer_align_start_in :
- + forall n start tokens currStartAddrs currJmpTargets allStartAddrs allJmpTargets,
- + process_buffer_align start n tokens (currStartAddrs, currJmpTargets) =
- + Some(allStartAddrs, allJmpTargets)
- + -> (length (tokens) > 0)%nat
- + -> Int32Set.In start allStartAddrs.
- +Proof. intros. destruct tokens as [| t tokens'].
- + Case "tokens=nil". simpl in H0. contradict H0. omega.
- + Case "tokens<>nil".
- + assert (length (t::tokens') >= 1)%nat by (simpl; omega).
- + destruct n.
- + SCase "n=0". discriminate.
- + SCase "S n".
- + unfold process_buffer_align, FastVerifier.process_buffer_align in H.
- + destruct (FastVerifier.process_buffer_aux non_cflow_dfa dir_cflow_dfa nacljmp_dfa
- + initial_state start (S n) (t :: tokens')
- + (currStartAddrs, currJmpTargets)) as [res_pair|] eqn:Hpba.
- + SSCase "_aux_res <> None".
- + destruct res_pair as [start_insn_new check_list_new].
- + use_lemma process_buffer_aux_start_in by eassumption.
- + use_lemma process_buffer_align_subset by eassumption.
- + intuition.
- + SSCase "_aux_res is None".
- + discriminate.
- +Qed.
- +(* Admitted.*)
- +
- Lemma process_buffer_start_in : forall code startAddrs jmpTargets,
- process_buffer code = Some (startAddrs, jmpTargets)
- -> (length (code) > 0)%nat
- -> Int32Set.In int32_zero startAddrs.
- Proof. unfold process_buffer, FastVerifier.process_buffer; intros.
- - eapply process_buffer_aux_start_in. eassumption.
- + eapply process_buffer_align_start_in. eassumption.
- rewrite list_length_map. assumption.
- Qed.
- @@ -1111,9 +1476,9 @@
- -> Z_of_nat (length tokens) <= w32modulus
- -> forall pc:int32, Int32Set.In pc (Int32Set.diff allStartAddrs currStartAddrs)
- -> exists tokens', exists len, exists remaining,
- - tokens' = (List.skipn (Zabs_nat (unsigned pc - unsigned start))
- + tokens' = (List.skipn (Zabs_nat (unsigned pc - unsigned start))
- tokens) /\
- - goodDefaultPC_aux (pc +32_n len) start allStartAddrs
- + goodDefaultPC_aux (pc +32_n len) start allStartAddrs
- (length tokens) /\
- (dfa_recognize non_cflow_dfa tokens' = Some (len, remaining) \/
- (dfa_recognize dir_cflow_dfa tokens' = Some (len, remaining) /\
- @@ -1253,6 +1618,281 @@
- split. trivial. split; assumption.
- Qed.
- + Lemma merge_Znat_abs : forall x z, (0 <= x) -> (0 <= z) ->
- + ((Zabs_nat x) + Z.to_nat z)%nat = Zabs_nat (x + z).
- + Proof.
- + intros x z.
- + intros HxGt0 HzGt0.
- + rewrite -> Zabs2Nat.abs_nat_nonneg by assumption.
- + assert(HxpzGt0: 0 <= x + z) by lia.
- + rewrite -> Zabs2Nat.abs_nat_nonneg by assumption.
- + symmetry.
- + apply Z2Nat.inj_add; assumption.
- + Qed.
- +
- + Lemma combine_p32_n : forall a n1 n2,
- + a +32_n n1 +32_n n2 = a +32_n (n1 + n2)%nat.
- + Proof.
- + intros a n1 n2.
- + unfold w32add.
- + rewrite add_assoc.
- + f_equal.
- + replace (Z.of_nat (n1 + n2)) with ((Z.of_nat n1) + (Z.of_nat n2)).
- + Case "After replace". apply add_repr.
- + Case "Proof of replacement". symmetry. apply Nat2Z.inj_add.
- + Qed.
- +
- + Lemma includeAllJmpTargets_superset : forall pc len tokens set superset,
- + (Int32Set.Subset set superset) ->
- + (includeAllJmpTargets pc len tokens set) ->
- + (includeAllJmpTargets pc len tokens superset).
- + Proof.
- + intros pc len tokens set superset.
- + intros Hsubset.
- + unfold includeAllJmpTargets.
- + destruct_head. destruct p as [[pre ins] _].
- + destruct ins; try trivial.
- + Case "JMP".
- + destruct near; try congruence.
- + destruct absolute; try congruence.
- + destruct op1; try congruence.
- + destruct sel.
- + trivial.
- + intros. apply Int32Set_in_subset with (s:=set); assumption.
- + intros. apply Int32Set_in_subset with (s:=set); assumption.
- + Case "Call".
- + destruct near; try congruence.
- + destruct absolute; try congruence.
- + destruct op1; try congruence.
- + destruct sel.
- + trivial.
- + intros. apply Int32Set_in_subset with (s:=set); assumption.
- + trivial.
- + Qed.
- +
- + Lemma process_buffer_align_inversion :
- + forall n start tokens currStartAddrs currJmpTargets allStartAddrs allJmpTargets,
- + process_buffer_align start n tokens (currStartAddrs, currJmpTargets) =
- + Some (allStartAddrs, allJmpTargets)
- + -> noOverflow (start :: int32_of_nat (length tokens - 1) :: nil)
- + -> Z_of_nat (length tokens) <= w32modulus
- + -> forall pc:int32, Int32Set.In pc (Int32Set.diff allStartAddrs currStartAddrs)
- + -> exists tokens', exists len, exists remaining,
- + tokens' = (List.skipn (Zabs_nat (unsigned pc - unsigned start))
- + tokens) /\
- + goodDefaultPC_aux (pc +32_n len) start allStartAddrs
- + (length tokens) /\
- + (dfa_recognize non_cflow_dfa tokens' = Some (len, remaining) \/
- + (dfa_recognize dir_cflow_dfa tokens' = Some (len, remaining) /\
- + includeAllJmpTargets pc len tokens' allJmpTargets) \/
- + dfa_recognize nacljmp_dfa tokens' = Some (len, remaining)).
- + Proof.
- + induction n as [| n'].
- + Case "n = 0". intros. destruct tokens as [|t tokens2]; pbprover.
- + Case "n = S n'".
- + intros until 0.
- + intros HretSome HnoOverF HtokBound pc HpcAdded.
- + destruct tokens as [| t tokens2]. SCase "tokens = nil". pbprover.
- + SCase "tokens <> nil".
- + assert(HtokensLen: ((length (t::tokens2) >= 1))%nat) by (simpl; omega).
- + destruct (FastVerifier.process_buffer_aux non_cflow_dfa dir_cflow_dfa
- + nacljmp_dfa initial_state start (S n') (t :: tokens2)
- + (currStartAddrs, currJmpTargets)) as [res_pair|] eqn:Hpb_aux.
- + SSCase "pb_aux = Some".
- + destruct res_pair as [start_instrs_new check_list_new].
- + use_lemma (process_buffer_align_subset (S n') start
- + (t :: tokens2) currStartAddrs currJmpTargets
- + allStartAddrs allJmpTargets)
- + by assumption.
- + break_hyp.
- + rename H into HcurAllStarts.
- + rename H0 into HcurAllJmps.
- + use_lemma (process_buffer_aux_subset (S n') start
- + (t :: tokens2) currStartAddrs currJmpTargets
- + start_instrs_new check_list_new)
- + by assumption.
- + break_hyp.
- + rename H into HcurNextStarts.
- + rename H0 into HcurNetJmps.
- + assert(HrecSome:
- + process_buffer_align (start +32_n Z.to_nat chunkSize) n'
- + (skipn (Z.to_nat chunkSize) (t :: tokens2))
- + (start_instrs_new, check_list_new) =
- + Some (allStartAddrs, allJmpTargets)).
- + SSSCase "Proof of HrecSome".
- + unfold process_buffer_align,
- + FastVerifier.process_buffer_align in HretSome.
- + rewrite Hpb_aux in HretSome.
- + exact HretSome.
- + use_lemma (process_buffer_align_subset n'
- + (start +32_n Z.to_nat chunkSize)
- + (skipn (Z.to_nat chunkSize) (t :: tokens2))
- + start_instrs_new check_list_new
- + allStartAddrs allJmpTargets)
- + by assumption.
- + break_hyp.
- + rename H into HnextAllStarts.
- + rename H0 into HnextAllJmps.
- + destruct (@Int32Set_diff_diff_dichotomy
- + pc _ start_instrs_new _ HpcAdded)
- + as [Hdiff1|Hdiff2].
- + SSSCase "pc added in recursion".
- + use_lemma (IHn' (start +32_n Z.to_nat chunkSize)
- + (skipn (Z.to_nat chunkSize) (t :: tokens2))
- + start_instrs_new check_list_new
- + allStartAddrs allJmpTargets) by assumption.
- + rename H into IH.
- + assert(HskipLen: (length (skipn (Z.to_nat chunkSize)
- + (t :: tokens2)) >= 1)%nat).
- + SSSSCase "Proof of HskipLen".
- + unfold process_buffer_align,
- + FastVerifier.process_buffer_align in HretSome.
- + rewrite Hpb_aux in HretSome.
- + assert(HnoPcContra:
- + ~(Some (start_instrs_new, check_list_new) =
- + Some (allStartAddrs, allJmpTargets))).
- + SSSSSCase "Proof of HnoPcContra".
- + injection. intros HnoCLN HnoSIN.
- + rewrite HnoSIN in Hdiff1. contradict Hdiff1.
- + rewrite Int32Set.diff_spec. tauto.
- + destruct n' as [| p],
- + (skipn (Z.to_nat chunkSize) (t :: tokens2))
- + as [|tokens3] eqn:Hskipped.
- + SSSSSCase "n' = 0, skipn = nil".
- + contradict HnoPcContra. assumption.
- + SSSSSCase "n' = 0, skipn <> nil".
- + contradict HretSome. discriminate.
- + SSSSSCase "n' = S p, skipn = nil".
- + contradict HnoPcContra. assumption.
- + SSSSSCase "n' = Sp, skipn <> nil".
- + simpl. omega.
- + generalize
- + (skipn_length3 (Z.to_nat chunkSize) _ (t :: tokens2)).
- + intros Hlen3.
- + generalize (Hlen3 HskipLen). intros Hgt32.
- + assert(H32pskip: (length (t :: tokens2) = (Z.to_nat chunkSize +
- + length (skipn (Z.to_nat chunkSize) (t :: tokens2))))%nat).
- + SSSSCase "|tokens|=32+|rest|".
- + use_lemma (@skipn_length (Z.to_nat chunkSize)
- + _ (t :: tokens2)) by assumption.
- + rename H into Hskipnl.
- + rewrite plus_comm. symmetry. apply Hskipnl.
- + use_lemma (process_buffer_arith_facts start
- + (Z.to_nat chunkSize) (t :: tokens2)
- + (skipn (Z.to_nat chunkSize) (t :: tokens2)))
- + by assumption.
- + break_hyp.
- + rename H into HnoOverFStartP32.
- + rename H0 into HnoOverFStartPlen.
- + rename H1 into HrestBound.
- + generalize (IH HnoOverFStartPlen HrestBound pc Hdiff1).
- + intros H.
- + destruct H as [tokens']. exists tokens'.
- + destruct H as [len]. exists len.
- + destruct H as [remaining]. exists remaining.
- + break_hyp.
- + rename H into HinsnToks.
- + rename H0 into HgoodPC.
- + rename H1 into Hdfas.
- + split.
- + SSSSCase "tokens' definition".
- + rewrite skipn_twice_eq in HinsnToks.
- + replace (Z.abs_nat (unsigned pc -
- + unsigned (start +32_n Z.to_nat chunkSize)) +
- + Z.to_nat chunkSize)%nat with
- + (Z.abs_nat (unsigned pc - unsigned start))
- + in HinsnToks. assumption.
- + SSSSSCase "Arithmetic cancellation".
- + assert(HrewA32: (unsigned (start +32_n Z.to_nat chunkSize)) =
- + ((unsigned start) + chunkSize)).
- + SSSSSSCase "Proof of noOverflow replacement rule".
- + generalize (noOverflow_2_iff start
- + (int32_of_nat (Z.to_nat chunkSize))).
- + intros. break_hyp. clear H0.
- + rename H into HnoO2if.
- + rewrite HnoO2if by assumption.
- + auto.
- + rewrite HrewA32.
- + replace (unsigned pc - (unsigned start + chunkSize)) with
- + (unsigned pc - unsigned start - chunkSize) by lia.
- + generalize chunkSize_gt_0. intros HchunkGt0.
- + generalize (process_buffer_align_addrRange
- + (S n') start (t :: tokens2)
- + currStartAddrs currJmpTargets
- + allStartAddrs allJmpTargets pc HretSome
- + HnoOverF HtokBound HpcAdded).
- + intros HaddrRange.
- + generalize (process_buffer_align_addrRange
- + n' (start +32_n Z.to_nat chunkSize)
- + (skipn (Z.to_nat chunkSize) (t :: tokens2))
- + start_instrs_new check_list_new
- + allStartAddrs allJmpTargets pc
- + HrecSome HnoOverFStartPlen HrestBound
- + Hdiff1).
- + intros HaddrRange2.
- + rewrite HrewA32 in HaddrRange2.
- + replace ((Z.abs_nat (unsigned pc - unsigned start - chunkSize)
- + + Z.to_nat chunkSize)%nat) with
- + (Z.abs_nat (unsigned pc - unsigned start - chunkSize
- + + chunkSize)).
- + SSSSSSCase "Proof after abs_nat merger".
- + f_equal. lia.
- + SSSSSSCase "Proof of abs_nat merger".
- + assert(HdiffPos:
- + (0 <= unsigned pc - unsigned start - chunkSize))
- + by lia.
- + symmetry.
- + apply merge_Znat_abs; lia.
- + split.
- + SSSSCase "HgoodPC displaced".
- + unfold goodDefaultPC_aux.
- + unfold goodDefaultPC_aux in HgoodPC.
- + destruct HgoodPC as [HgoodPC_l | HgoodPC_r].
- + SSSSSCase "Not last address". left. assumption.
- + SSSSSCase "Last address". right.
- + rewrite HgoodPC_r.
- + rewrite combine_p32_n.
- + f_equal. f_equal. f_equal.
- + symmetry. assumption.
- + SSSSCase "Hdfas". assumption.
- + SSSCase "pc added in aux".
- + use_lemma (process_buffer_aux_inversion (S n') start
- + (t :: tokens2) currStartAddrs currJmpTargets
- + start_instrs_new check_list_new
- + Hpb_aux HnoOverF HtokBound pc)
- + by assumption.
- + destruct H as [tokens']. exists tokens'.
- + destruct H as [len]. exists len.
- + destruct H as [remaining]. exists remaining.
- + break_hyp.
- + rename H into HinsnToks.
- + rename H0 into HgoodPC.
- + rename H1 into Hdfas.
- + split.
- + SSSSCase "HinsnToks". assumption.
- + split.
- + SSSSCase "HgoodPC subset".
- + unfold goodDefaultPC_aux.
- + unfold goodDefaultPC_aux in HgoodPC.
- + assert(HstartSub:
- + Int32Set.In (pc +32_n len) start_instrs_new ->
- + Int32Set.In (pc +32_n len) allStartAddrs).
- + SSSSSCase "Proof of HstartSub".
- + intros HinNext.
- + apply Int32Set_in_subset with (s:=start_instrs_new);
- + assumption.
- + tauto.
- + SSSSCase "Hdfas subset".
- + use_lemma (includeAllJmpTargets_superset pc len tokens'
- + check_list_new allJmpTargets) by assumption.
- + tauto.
- + SSCase "pb_aux = None".
- + unfold process_buffer_align,
- + FastVerifier.process_buffer_align in HretSome.
- + rewrite Hpb_aux in HretSome.
- + contradict HretSome. discriminate.
- + Qed.
- +
- Hint Rewrite Zminus_0_r : pbDB.
- Lemma process_buffer_inversion :
- @@ -1278,7 +1918,7 @@
- simpl. int32_simplify. rewrite int32_modulus_constant. simpl. lia.
- assert (length (b::buffer') >= 1)%nat by (simpl; omega).
- int32_prover.
- - apply process_buffer_aux_inversion with (pc:=pc) in H;
- + apply process_buffer_align_inversion with (pc:=pc) in H;
- [idtac | assumption | (rewrite list_length_map; omega) | pbprover].
- destruct H as [tokens' [len [remaining H]]].
- break_hyp.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement