[PATCH] s6-rc-update: avoid getrandom(2)

From: Rasmus Villemoes <rasmus.villemoes_at_prevas.dk>
Date: Tue, 26 Sep 2017 11:51:47 +0200

On a modern linux system, s6-rc-update ends up calling getrandom(2) via
the random_sauniquename() library function. But on embedded systems, and
especially during early initialization, that is likely to block, which
means that the entire boot process hangs.

No, writing 160 bytes of crap to /dev/urandom as random_init does makes
no difference; it does not in any way "speed up /dev/urandom
initialization".

And no, we cannot just make sure the kernel's random number generator is
fully initialized before calling s6-rc-update, as s6-rc-update may very
well be the one that starts the service(s) that eventually ensures this
initialization (e.g., all the network-facing services).

In general, none of the infrastructure utilities (skaware or otherwise)
involved in the boot process can be allowed to make a possibly-blocking
getrandom() call.

We don't need a hard-to-predict name, we just need a name that doesn't
already exist. So avoid getrandom() in s6-rc-update, and use mkdtemp()
instead. Unfortunately, that doesn't accept a mode argument and uses
0700, so to emulate a mkdir(, 0755), do a little umask dance
afterwards. It shouldn't be hard to reimplement mkdtemp and have that
function take a mode argument, but for now this at least makes my board
boot.

Signed-off-by: Rasmus Villemoes <rasmus.villemoes_at_prevas.dk>
---
 src/s6-rc/s6-rc-update.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/s6-rc/s6-rc-update.c b/src/s6-rc/s6-rc-update.c
index a6e7cfe..5c933de 100644
--- a/src/s6-rc/s6-rc-update.c
+++ b/src/s6-rc/s6-rc-update.c
_at_@ -3,7 +3,10 @@
 #include <string.h>
 #include <stdint.h>
 #include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <unistd.h>
+#include <stdlib.h>
 #include <errno.h>
 #include <stdio.h>
 #include <skalibs/types.h>
_at_@ -19,7 +22,6 @@
 #include <skalibs/skamisc.h>
 #include <skalibs/webipc.h>
 #include <skalibs/unix-transactional.h>
-#include <skalibs/random.h>
 #include <execline/execline.h>
 #include <s6/config.h>
 #include <s6/s6-supervise.h>
_at_@ -330,12 +332,14 @@ static inline void make_new_livedir (unsigned char const *oldstate, s6rc_db_t co
   size_t dirlen, llen, newlen, sdlen ;
   int e = 0 ;
   unsigned int i = 0 ;
+  mode_t mask;
   if (sareadlink(&satmp, live) < 0) strerr_diefu2sys(111, "readlink ", live) ;
   if (!s6rc_sanitize_dir(sa, live, &dirlen)) dienomem() ;
   llen = sa->len ;
-  if (!random_sauniquename(sa, 8) || !stralloc_0(sa)) dienomem() ;
+  if (!sauniquename(sa) || !stralloc_cats(sa, ":XXXXXX") || !stralloc_0(sa)) dienomem() ;
   newlen = --sa->len ;
-  if (mkdir(sa->s + sabase, 0755) < 0) strerr_diefu2sys(111, "mkdir ", sa->s + sabase) ;
+  if (!mkdtemp(sa->s + sabase)) strerr_diefu2sys(111, "mkdtemp ", sa->s + sabase) ;
+  mask = umask(0); chmod(sa->s + sabase, 0755 & ~mask); umask(mask);
   {
     size_t tmplen = satmp.len ;
     char fn[llen - sabase + 9] ;
_at_@ -642,9 +646,6 @@ int main (int argc, char const *const *argv, char const *const *envp)
     strerr_dief2x(100, live, " is not an absolute path") ;
   livelen = strlen(live) ;
 
-  if (!random_init())
-    strerr_diefu1sys(111, "init random generator") ;
-
   {
     int livelock, oldlock, newlock ;
     int fdoldc, fdnewc ;
-- 
2.7.4
Received on Tue Sep 26 2017 - 09:51:47 UTC

This archive was generated by hypermail 2.3.0 : Sun May 09 2021 - 19:38:49 UTC