mllib: Add a utility function for safely reading from /dev/urandom.

OCaml's buffered 'in_channel' has a 64k buffer, so using it to read a
few bytes from /dev/urandom removes a lot of the system's entropy (for
example /proc/sys/kernel/random/entropy_avail goes from ~3000 to 128).

This patch was originally by Edwin Török for builder.ml.  I
generalized it because there are two other places where we did
over-sized reads from /dev/urandom.
This commit is contained in:
Richard W.M. Jones
2013-11-14 10:09:52 +00:00
parent 544d6b25e3
commit f013b15fa1
7 changed files with 78 additions and 7 deletions

View File

@@ -65,6 +65,7 @@ OBJECTS = \
$(top_builddir)/mllib/libdir.cmx \
$(top_builddir)/mllib/common_gettext.cmx \
$(top_builddir)/mllib/common_utils.cmx \
$(top_builddir)/mllib/urandom.cmx \
$(top_builddir)/mllib/random_seed.cmx \
$(top_builddir)/mllib/hostname.cmx \
$(top_builddir)/mllib/firstboot.cmx \

View File

@@ -48,6 +48,8 @@ SOURCES = \
tty-c.c \
tTY.mli \
tTY.ml \
urandom.mli \
urandom.ml \
uri-c.c \
uRI.mli \
uRI.ml
@@ -70,6 +72,7 @@ OBJECTS = \
libdir.cmx \
common_gettext.cmx \
common_utils.cmx \
urandom.cmx \
random_seed.cmx \
hostname.cmx \
firstboot.cmx \

View File

@@ -78,13 +78,8 @@ and make_random_seed_file g file =
(* Default to 512 bytes of randomness. *)
512 in
let entropy =
(* Get n bytes of randomness from the host. *)
let chan = open_in "/dev/urandom" in
let buf = String.create n in
really_input chan buf 0 n;
close_in chan;
buf in
(* Get n bytes of randomness from the host. *)
let entropy = Urandom.urandom_bytes n in
if file_exists then (
(* Truncate the original file and append, in order to

48
mllib/urandom.ml Normal file
View File

@@ -0,0 +1,48 @@
(* Read /dev/urandom.
* Copyright (C) 2013 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*)
(* Read and return N bytes (only) from /dev/urandom.
*
* As pointed out by Edwin Török, previous versions of this had a big
* problem. They used the OCaml buffered I/O library which would read
* a lot more data than requested. This version uses unbuffered I/O
* from the Unix module.
*)
open Unix
let open_urandom_fd () = openfile "/dev/urandom" [O_RDONLY] 0
let read_byte fd =
let s = String.make 1 ' ' in
fun () ->
if read fd s 0 1 = 0 then (
close fd;
raise End_of_file
);
Char.code s.[0]
let urandom_bytes n =
assert (n > 0);
let ret = String.make n ' ' in
let fd = open_urandom_fd () in
for i = 0 to n-1 do
ret.[i] <- Char.chr (read_byte fd ())
done;
close fd;
ret

22
mllib/urandom.mli Normal file
View File

@@ -0,0 +1,22 @@
(* Read /dev/urandom.
* Copyright (C) 2013 Red Hat Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*)
(** Read and return N bytes (only) from /dev/urandom. *)
val urandom_bytes : int -> string
(** Read N bytes from /dev/urandom and return it as a binary string. *)

View File

@@ -21,6 +21,7 @@ mllib/progress.ml
mllib/random_seed.ml
mllib/tTY.ml
mllib/uRI.ml
mllib/urandom.ml
resize/resize.ml
sparsify/sparsify.ml
sysprep/main.ml

View File

@@ -89,6 +89,7 @@ OBJECTS = \
$(top_builddir)/mllib/uRI.cmx \
$(top_builddir)/mllib/crypt-c.o \
$(top_builddir)/mllib/crypt.cmx \
$(top_builddir)/mllib/urandom.cmx \
$(top_builddir)/mllib/password.cmx \
$(top_builddir)/mllib/random_seed.cmx \
$(top_builddir)/mllib/hostname.cmx \