[COMMIT osv master] auxv AT_RANDOM: rollback use of getrandom() for now

1 view
Skip to first unread message

Commit Bot

unread,
Aug 24, 2023, 10:28:58 AM8/24/23
to osv...@googlegroups.com, Waldemar Kozaczuk
From: Waldemar Kozaczuk <jwkoz...@gmail.com>
Committer: Waldemar Kozaczuk <jwkoz...@gmail.com>
Branch: master

auxv AT_RANDOM: rollback use of getrandom() for now

The commit 597a8b56ec83413c06b363fecdace646a297224a changed
prepare_argv() to add AT_RANDOM the to auxiliary vector.

However, when I ran unit tests I noticed they they take in total
on average 20 seconds longer - bump from ~200 to ~220 after this commit.
There are 142 unit tests ran as part of RoFS image, which means that
on average each test ran ~140ms slower after this commit.

After removing the call to getrandom() and simply using the
pseudo-random rand_r() fixed this time regression.

Ideally, we would like to improve the AT_RANDOM quality of randomness but
for that we have to use different tool than getrandom() or fix its
issue.

Signed-off-by: Waldemar Kozaczuk <jwkoz...@gmail.com>

---
diff --git a/core/app.cc b/core/app.cc
--- a/core/app.cc
+++ b/core/app.cc
@@ -20,7 +20,6 @@
#include <boost/range/algorithm/transform.hpp>
#include <osv/wait_record.hh>
#include "libc/pthread.hh"
-#include <sys/random.h>

using namespace boost::range;

@@ -363,13 +362,14 @@ void application::prepare_argv(elf::program *program)
}

// Initialize random bytes array so it can be passed as AT_RANDOM auxv vector
- if (getrandom(random_bytes, sizeof(random_bytes), 0) != sizeof(random_bytes)) {
- // Fall back to rand_r()
- auto d = osv::clock::wall::now().time_since_epoch();
- unsigned seed = std::chrono::duration_cast<std::chrono::nanoseconds>(d).count() % 1000000000;
- for (unsigned idx = 0; idx < sizeof(random_bytes)/(sizeof(int)); idx++) {
- reinterpret_cast<int*>(random_bytes)[idx] = rand_r(&seed);
- }
+ //TODO: Ideally we would love to use something better than the pseudo-random scheme below
+ //based on the time since epoch and rand_r(). But the getrandom() at this points does
+ //no always work and is also very slow. Once we figure out how to fix or improve it
+ //we may refine it with a better solution. For now it will do.
+ auto d = osv::clock::wall::now().time_since_epoch();
+ unsigned seed = std::chrono::duration_cast<std::chrono::nanoseconds>(d).count() % 1000000000;
+ for (unsigned idx = 0; idx < sizeof(random_bytes)/(sizeof(int)); idx++) {
+ reinterpret_cast<int*>(random_bytes)[idx] = rand_r(&seed);
}

int auxv_parameters_count = 4;
Reply all
Reply to author
Forward
0 new messages