This fixes an issue where libexpat might read from `/dev/urandom` and thus block until the entropy pool is initialized. This hidden dependency is very hard to debug. Instead, we require the service launcher to delay startup until suitable entropy is available. This explicit dependency is much easier to manage, debug, and control. Reported-by: Stefan Agner Signed-off-by: David Rheinsberg --- src/launch/config.c | 17 +++++++++++++++++ src/launch/config.h | 1 + 2 files changed, 18 insertions(+) diff --git a/src/launch/config.c b/src/launch/config.c index 85521bd..4a6a11e 100644 --- a/src/launch/config.c +++ b/src/launch/config.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "dbus/protocol.h" #include "launch/config.h" #include "launch/nss-cache.h" @@ -1216,9 +1217,24 @@ static void config_parser_blob_fn(void *userdata, const XML_Char *data, int n_da * config_parser_init() - XXX */ void config_parser_init(ConfigParser *parser) { + void *random; + *parser = (ConfigParser)CONFIG_PARSER_NULL(*parser); parser->xml = XML_ParserCreate(NULL); + + /* + * The hash-tables of libexpat require a reliable random seed. + * Depending on libexpat compilation flags, this might end up using + * `/dev/urandom` and thus block until random-initialization is + * finished. We avoid this hidden dependency and instead use the + * entropy provided via `AT_RANDOM`. Hence, entropy availability is + * tightly coupled to process startup, and it is the job of the + * service manager to order processes accordingly. + */ + random = (void *)getauxval(AT_RANDOM); + assert(random); + memcpy(&parser->salt, random, sizeof(parser->salt)); } /** @@ -1262,6 +1278,7 @@ static int config_parser_include(ConfigParser *parser, ConfigRoot *root, ConfigN } XML_ParserReset(parser->xml, NULL); + XML_SetHashSalt(parser->xml, parser->salt); XML_SetUserData(parser->xml, &parser->state); XML_SetElementHandler(parser->xml, config_parser_begin_fn, config_parser_end_fn); XML_SetCharacterDataHandler(parser->xml, config_parser_blob_fn); diff --git a/src/launch/config.h b/src/launch/config.h index 4c8df18..8ae9be6 100644 --- a/src/launch/config.h +++ b/src/launch/config.h @@ -216,6 +216,7 @@ struct ConfigRoot { struct ConfigParser { struct XML_ParserStruct *xml; + unsigned long salt; struct ConfigState { NSSCache *nss; -- 2.33.0