Skip to content

Commit

Permalink
Prevent seek_in from marking buffer data as valid after closing the…
Browse files Browse the repository at this point in the history
… channel (ocaml#11965)

* Test calls to input_byte after close_in

Add a test demonstrating issue ocaml#11878

* Reset offset when closing a channel

If offset keeps its value when the channel is closed, it is possible to
`seek_in` backward which will only decrease `channel->curr` and therefore
mark some buffer bytes as valid: further calls to `input_byte` would
succeed on the closed channel

Fixes: ocaml#11878
(cherry picked from commit a606e92)
  • Loading branch information
shym authored and edwintorok committed Feb 10, 2024
1 parent 77f09d8 commit 5e2c51f
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ OCaml 4.14 maintenance version
- #11332, #12702: make sure `Bool_val(v)` has type `bool` in C++
(Xavier Leroy, report by ygrek, review by Gabriel Scherer)

### Standard library:

- #11878, #11965: Prevent seek_in from marking buffer data as valid after
closing the channel. This could lead to inputting uninitialized bytes.
(Samuel Hym, review by Xavier Leroy and Olivier Nicole)

### Build system:

- #11590: Allow installing to a destination path containing spaces.
Expand Down
3 changes: 3 additions & 0 deletions runtime/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,9 @@ CAMLprim value caml_ml_close_channel(value vchannel)
immediate caml_flush_partial or caml_refill, thus raising a Sys_error
exception */
channel->curr = channel->max = channel->end;
/* Prevent any seek backward that would mark the last bytes of the
* channel buffer as valid */
channel->offset = 0;

/* If already closed, we are done */
if (channel->fd == -1) return Val_unit;
Expand Down
20 changes: 20 additions & 0 deletions testsuite/tests/lib-channels/close_in.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(* TEST *)

(* Test that inputting bytes from a closed in_channel triggers an exception *)

(* The number of bytes we'll rewind after closing; a value
between 1 and IO_BUFFER_SIZE *)
let nb_bytes = 3

let () =
let ic = open_in_bin Sys.argv.(0) in
seek_in ic nb_bytes;
close_in ic;
seek_in ic 0;
assert (
try
ignore (input_byte ic);
false
with
| Sys_error _ -> true
| _ -> false)

0 comments on commit 5e2c51f

Please sign in to comment.