]> xenbits.xensource.com Git - people/aperard/osstest.git/commitdiff
Bodge systemd random seed arrangements
authorIan Jackson <ian.jackson@eu.citrix.com>
Thu, 28 May 2020 17:18:06 +0000 (18:18 +0100)
committerIan Jackson <ian.jackson@eu.citrix.com>
Mon, 8 Jun 2020 15:33:28 +0000 (16:33 +0100)
systemd does not regard the contents of the random seed file as useful
for the purposes of placating the kernel's entropy tracker.  As a
result, the system hangs at boot waiting for entropy.

Fix this by providing a small program which can be used to load a seed
file into /dev/random and also call RNDADDTOENTCNT to add the
appropriate amount to the kernel's counter.

Arrange to run this program instead of
   /lib/systemd/systemd-random-seed load

With systemd the random seed file is in /var/lib/systemd/random-seed
rather than /var/lib/urandom/random-seed.

And, provide an initial contents of this file, via a d-i late_command.

Unfortunately we must hardcode the actual numerical value of
RNDADDTOENTCNT because we don't have a suitable compiler anywhere
nearby.  It seems to have the same value on i386, amd64, armhf and
arm64, our currently supported architectures.

Thanks to Colin Watson for pointers to the systemd random unit and
Matthew Vernon for instructions on overriding just ExecStart.

I think this change should be a no-op on non-systemd systems.

In principle this is a bug in Debian or in systemd, that ought to be
reported upstream.  However, it has been extensively discussed on
debian-devel and it does not seem that any improvement is likely.

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Osstest/Debian.pm
overlay/etc/systemd/system/systemd-random-seed.service.d/override.conf [new file with mode: 0644]
overlay/usr/local/bin/random-seed-add [new file with mode: 0755]

index b8bf67dc8e02c435839c5da21ac2b25c5bed3657..8ccacc794011e05dcd8bdac3e60794a8d8ba08a3 100644 (file)
@@ -49,6 +49,7 @@ BEGIN {
                       di_installcmdline_core
                       di_vg_name
                       debian_dhcp_rofs_fix
+                     debian_write_random_seed_command
                       );
     %EXPORT_TAGS = ( );
 
@@ -1087,6 +1088,13 @@ ln -s . /target/boot/boot
 END
     }
 
+    my $cmd = debian_write_random_seed_command('/target');
+    preseed_hook_command($ho, 'late_command', $sfx, <<END);
+#!/bin/sh
+set -ex
+$cmd
+END
+
     $preseed_file .= preseed_hook_cmds();
 
     return create_webfile($ho, "preseed$sfx", $preseed_file);
@@ -1612,4 +1620,14 @@ mv '$script.new' '$script'
 END
 }
 
+sub debian_write_random_seed_command ($) {
+    my ($mountpoint) = @_;
+    my $dir = "$mountpoint/var/lib/systemd";
+    return <<END;
+        umask 077
+        test -d $dir || mkdir -m 0755 $dir
+        dd if=/dev/urandom of=$dir/random-seed bs=1k count=1
+END
+}
+
 1;
diff --git a/overlay/etc/systemd/system/systemd-random-seed.service.d/override.conf b/overlay/etc/systemd/system/systemd-random-seed.service.d/override.conf
new file mode 100644 (file)
index 0000000..f6cc0f8
--- /dev/null
@@ -0,0 +1,3 @@
+[Service]
+ExecStart=
+ExecStart=/usr/local/bin/random-seed-add /var/lib/systemd/random-seed
diff --git a/overlay/usr/local/bin/random-seed-add b/overlay/usr/local/bin/random-seed-add
new file mode 100755 (executable)
index 0000000..89e75c4
--- /dev/null
@@ -0,0 +1,33 @@
+#!/usr/bin/perl -w
+use strict;
+
+open R, '>', '/dev/random' or die "open /dev/random: $!\n";
+R->autoflush(1);
+
+sub rndaddtoentcnt ($) {
+    my ($bits) = @_;
+    my $x = pack 'L', $bits;
+    my $r = ioctl R, 0x40045201, $x;
+    defined $r or die "RNDADDTOENTCNT: $!\n";
+}
+
+sub process_stdin ($) {
+    my ($f) = @_;
+    my $got = read STDIN, $_, 512;
+    defined $got or die "read $f: $!\n";
+    last if !$got;
+    print R $_ or die "write /dev/random: $!\n";
+    my $bits = length($_) * 8;
+    rndaddtoentcnt($bits);
+}
+
+if (!@ARGV) {
+    process_stdin('stdin');
+} else {
+    die "no options supported\n" if $ARGV[0] =~ m/^\-/;
+    foreach my $f (@ARGV) {
+        open STDIN, '<', $f or die "open for reading $f: $!\n";
+        process_stdin($f);
+    }
+}
+