Skip to content

Commit e1ea590

Browse files
josuemoreauxavierleroy
authored andcommitted
Semantics of free(): remove requirement size > 0 (#509)
Zero-sized blocks work fine, with a slightly different proof of memory injections in Events.v. Co-authored-by: xavier.leroy@college-de-france.fr
1 parent 2e37443 commit e1ea590

3 files changed

Lines changed: 38 additions & 14 deletions

File tree

cfrontend/Cexec.v

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,6 @@ Definition do_ef_free
508508
| Vptr b lo :: nil =>
509509
do vsz <- Mem.load Mptr m b (Ptrofs.unsigned lo - size_chunk Mptr);
510510
do sz <- do_alloc_size vsz;
511-
check (zlt 0 (Ptrofs.unsigned sz));
512511
do m' <- Mem.free m b (Ptrofs.unsigned lo - size_chunk Mptr) (Ptrofs.unsigned lo + Ptrofs.unsigned sz);
513512
Some(w, E0, Vundef, m')
514513
| Vint n :: nil =>
@@ -630,7 +629,7 @@ Proof with try congruence.
630629
replace (Vlong Int64.zero) with Vnullptr. split; constructor.
631630
unfold Vnullptr; rewrite H0; auto.
632631
+ destruct vargs... mydestr.
633-
split. apply SIZE in Heqo0. econstructor; eauto. congruence. lia.
632+
split. apply SIZE in Heqo0. econstructor; eauto. congruence.
634633
constructor.
635634
- (* EF_memcpy *)
636635
unfold do_ef_memcpy. destruct vargs... destruct v... destruct vargs...
@@ -687,7 +686,7 @@ Proof.
687686
inv H0. erewrite SIZE by eauto. rewrite H1, H2. auto.
688687
- (* EF_free *)
689688
inv H; unfold do_ef_free.
690-
+ inv H0. rewrite H1. erewrite SIZE by eauto. rewrite zlt_true. rewrite H3. auto. lia.
689+
+ inv H0. rewrite H1. erewrite SIZE by eauto. rewrite H2. auto.
691690
+ inv H0. unfold Vnullptr; destruct Archi.ptr64; auto.
692691
- (* EF_memcpy *)
693692
inv H; unfold do_ef_memcpy.

common/Events.v

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,6 @@ Inductive extcall_free_sem (ge: Senv.t):
10681068
list val -> mem -> trace -> val -> mem -> Prop :=
10691069
| extcall_free_sem_ptr: forall b lo sz m m',
10701070
Mem.load Mptr m b (Ptrofs.unsigned lo - size_chunk Mptr) = Some (Vptrofs sz) ->
1071-
Ptrofs.unsigned sz > 0 ->
10721071
Mem.free m b (Ptrofs.unsigned lo - size_chunk Mptr) (Ptrofs.unsigned lo + Ptrofs.unsigned sz) = Some m' ->
10731072
extcall_free_sem ge (Vptr b lo :: nil) m E0 Vundef m'
10741073
| extcall_free_sem_null: forall m,
@@ -1090,13 +1089,13 @@ Proof.
10901089
(* readonly *)
10911090
- eapply unchanged_on_readonly; eauto. inv H.
10921091
+ eapply Mem.free_unchanged_on; eauto.
1093-
intros. red; intros. elim H6.
1092+
intros. red; intros. elim H5.
10941093
apply Mem.perm_cur_max. apply Mem.perm_implies with Freeable; auto with mem.
10951094
eapply Mem.free_range_perm; eauto.
10961095
+ apply Mem.unchanged_on_refl.
10971096
(* mem extends *)
10981097
- inv H.
1099-
+ inv H1. inv H8. inv H6.
1098+
+ inv H1. inv H7. inv H5.
11001099
exploit Mem.load_extends; eauto. intros [v' [A B]].
11011100
assert (v' = Vptrofs sz).
11021101
{ unfold Vptrofs in *; destruct Archi.ptr64; inv B; auto. }
@@ -1108,7 +1107,7 @@ Proof.
11081107
unfold loc_out_of_bounds; intros.
11091108
assert (Mem.perm m1 b i Max Nonempty).
11101109
{ apply Mem.perm_cur_max. apply Mem.perm_implies with Freeable; auto with mem.
1111-
eapply Mem.free_range_perm. eexact H4. eauto. }
1110+
eapply Mem.free_range_perm. eexact H3. eauto. }
11121111
tauto.
11131112
+ inv H1. inv H5. replace v2 with Vnullptr.
11141113
exists Vundef; exists m1'; intuition auto.
@@ -1117,18 +1116,17 @@ Proof.
11171116
unfold Vnullptr in *; destruct Archi.ptr64; inv H3; auto.
11181117
(* mem inject *)
11191118
- inv H0.
1120-
+ inv H2. inv H7. inv H9.
1119+
+ inv H2. inv H6. inv H8.
11211120
exploit Mem.load_inject; eauto. intros [v' [A B]].
11221121
assert (v' = Vptrofs sz).
11231122
{ unfold Vptrofs in *; destruct Archi.ptr64; inv B; auto. }
11241123
subst v'.
11251124
assert (P: Mem.range_perm m1 b (Ptrofs.unsigned lo - size_chunk Mptr) (Ptrofs.unsigned lo + Ptrofs.unsigned sz) Cur Freeable).
11261125
eapply Mem.free_range_perm; eauto.
1127-
exploit Mem.address_inject; eauto.
1128-
apply Mem.perm_implies with Freeable; auto with mem.
1129-
apply P. instantiate (1 := lo).
1130-
generalize (size_chunk_pos Mptr); lia.
1131-
intro EQ.
1126+
assert (EQ: Ptrofs.unsigned (Ptrofs.add lo (Ptrofs.repr delta)) = Ptrofs.unsigned lo + delta).
1127+
{ eapply Mem.address_inject_gen with (p := Freeable); eauto.
1128+
right. apply P.
1129+
generalize (size_chunk_pos Mptr), (Ptrofs.unsigned_range sz); lia. }
11321130
exploit Mem.free_parallel_inject; eauto. intros (m2' & C & D).
11331131
exists f, Vundef, m2'; split.
11341132
apply extcall_free_sem_ptr with (sz := sz) (m' := m2').

common/Memory.v

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3262,15 +3262,42 @@ Qed.
32623262
(** The following lemmas establish the absence of machine integer overflow
32633263
during address computations. *)
32643264

3265+
Lemma address_inject_gen:
3266+
forall f m1 m2 b1 ofs1 b2 delta p,
3267+
inject f m1 m2 ->
3268+
perm m1 b1 (Ptrofs.unsigned ofs1) Cur p \/ perm m1 b1 (Ptrofs.unsigned ofs1 - 1) Cur p ->
3269+
f b1 = Some (b2, delta) ->
3270+
Ptrofs.unsigned (Ptrofs.add ofs1 (Ptrofs.repr delta)) = Ptrofs.unsigned ofs1 + delta.
3271+
Proof.
3272+
intros.
3273+
assert (perm m1 b1 (Ptrofs.unsigned ofs1) Max Nonempty
3274+
\/ perm m1 b1 (Ptrofs.unsigned ofs1 - 1) Max Nonempty)
3275+
by (destruct H0; eauto with mem).
3276+
exploit mi_representable; eauto. intros [A B].
3277+
assert (0 <= delta <= Ptrofs.max_unsigned).
3278+
generalize (Ptrofs.unsigned_range ofs1). lia.
3279+
unfold Ptrofs.add. repeat rewrite Ptrofs.unsigned_repr; lia.
3280+
Qed.
3281+
32653282
Lemma address_inject:
32663283
forall f m1 m2 b1 ofs1 b2 delta p,
32673284
inject f m1 m2 ->
32683285
perm m1 b1 (Ptrofs.unsigned ofs1) Cur p ->
32693286
f b1 = Some (b2, delta) ->
32703287
Ptrofs.unsigned (Ptrofs.add ofs1 (Ptrofs.repr delta)) = Ptrofs.unsigned ofs1 + delta.
3288+
Proof.
3289+
intros; eapply address_inject_gen; eauto.
3290+
Qed.
3291+
3292+
Lemma address_inject_1:
3293+
forall f m1 m2 b1 ofs1 b2 delta p,
3294+
inject f m1 m2 ->
3295+
perm m1 b1 (Ptrofs.unsigned ofs1 - 1) Cur p ->
3296+
f b1 = Some (b2, delta) ->
3297+
Ptrofs.unsigned (Ptrofs.add ofs1 (Ptrofs.repr delta)) = Ptrofs.unsigned ofs1 + delta.
32713298
Proof.
32723299
intros.
3273-
assert (perm m1 b1 (Ptrofs.unsigned ofs1) Max Nonempty) by eauto with mem.
3300+
assert (perm m1 b1 (Ptrofs.unsigned ofs1 - 1) Max Nonempty) by eauto with mem.
32743301
exploit mi_representable; eauto. intros [A B].
32753302
assert (0 <= delta <= Ptrofs.max_unsigned).
32763303
generalize (Ptrofs.unsigned_range ofs1). lia.

0 commit comments

Comments
 (0)