On Fri, 2023-11-10 at 16:54 +0100, Benjamin Beichler wrote: > At the moment, we haven't patched the random device that fetches random > bytes from the host (do you already have a patch for this?), > so complete repeatability isn't guaranteed at the moment. However, that > could be a logical next step.
Right, we have the attached kernel patches internally. This simply disables some of the random sources and replaces os_getrandom with returning static random from the UML_RANDOM environment variable. I doubt that it makes sense to upstream these patches, but may we can include them as patch files in USFSTL or so. The second piece is using a mount namespace to ensure that the linux command line is identical between runs and that the location of all files that are accessed directly from the host through hostfs never changes. The last piece was setting GLIBC_TUNABLES=-AVX512CD in the environment just in case the CPU feature set is slightly different. That would cause ld.so to search for a different set of optimized library versions (affecting syscalls and with that randomness). Benjamin
From 0b51202872111f1a5f7a59435ff741ef0272d30f Mon Sep 17 00:00:00 2001 From: Benjamin Berg <benjamin.b...@intel.com> Date: Thu, 16 Mar 2023 13:19:37 +0200 Subject: [PATCH 1/3] um: Use fixed random seed if UML_RANDOM is set This helps with reproducable test runs. Signed-off-by: Benjamin Berg <benjamin.b...@intel.com> --- arch/um/os-Linux/util.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index fc0f2a9dee5a..1e7b19272dfa 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c @@ -99,6 +99,42 @@ static inline void __attribute__ ((noreturn)) uml_abort(void) ssize_t os_getrandom(void *buf, size_t len, unsigned int flags) { + static char random_pattern[128]; + static ssize_t random_pattern_len = -1; + + /* This happens when called by setup_arch */ + if (random_pattern_len == -1) { + const char *env; + + env = getenv("UML_RANDOM"); + if (env) { + random_pattern_len = + strlen(env) > sizeof(random_pattern) ? + sizeof(random_pattern) : strlen(env); + memcpy(random_pattern, env, random_pattern_len); + } else { + random_pattern_len = 0; + } + } + + if (random_pattern_len > 0) { + size_t tail = len; + /* + * If the returned length is too short, then the kernel might + * loop trying to generate random from the passing of time. + * Which seems to possibly infinite loop in time-travel mode. + * So just repeat the given pattern. + */ + while (tail > random_pattern_len) { + memcpy(buf, random_pattern, random_pattern_len); + tail -= random_pattern_len; + buf += random_pattern_len; + } + memcpy(buf, random_pattern, tail); + + return len; + } + return getrandom(buf, len, flags); } -- 2.41.0
From b8aa74aed9fa008b908682bfa085461635e876e0 Mon Sep 17 00:00:00 2001 From: Benjamin Berg <benjamin.b...@intel.com> Date: Thu, 16 Mar 2023 13:21:19 +0200 Subject: [PATCH 2/3] random: disable interrupt random source Interrupts in our UML environment are signals, which can be delivered at somewhat random times depending on host scheduling. Disable these as a source to make the random reproducible between runs. Signed-off-by: Benjamin Berg <benjamin.b...@intel.com> --- drivers/char/random.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/char/random.c b/drivers/char/random.c index 253f2ddb8913..db2c5a296c05 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1093,6 +1093,9 @@ void add_interrupt_randomness(int irq) struct pt_regs *regs = get_irq_regs(); unsigned int new_count; + /* UML seems to not always get the signals entirely at the same time */ + return; + fast_mix(fast_pool->pool, entropy, (regs ? instruction_pointer(regs) : _RET_IP_) ^ swab(irq)); new_count = ++fast_pool->count; -- 2.41.0
From c62e671073cfe990fd2200c81defae98b1e9258b Mon Sep 17 00:00:00 2001 From: Benjamin Berg <benjamin.b...@intel.com> Date: Wed, 22 Mar 2023 17:56:37 +0100 Subject: [PATCH 3/3] random: do not include utsname in early random The uts name includes information about the compile time and such and changes. Exclude it, so that different kernel compilations will see the same random numbers. Signed-off-by: Benjamin Berg <benjamin.b...@intel.com> --- drivers/char/random.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/random.c b/drivers/char/random.c index db2c5a296c05..dd4aa42a4404 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -865,7 +865,7 @@ void __init random_init_early(const char *command_line) ++i; } - _mix_pool_bytes(init_utsname(), sizeof(*(init_utsname()))); + /* _mix_pool_bytes(init_utsname(), sizeof(*(init_utsname()))); */ _mix_pool_bytes(command_line, strlen(command_line)); /* Reseed if already seeded by earlier phases. */ -- 2.41.0
_______________________________________________ linux-um mailing list linux-um@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-um