mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
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:
@@ -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 \
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
48
mllib/urandom.ml
Normal 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
22
mllib/urandom.mli
Normal 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. *)
|
||||
@@ -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
|
||||
|
||||
@@ -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 \
|
||||
|
||||
Reference in New Issue
Block a user