[PATCH 05/15] tools/nolibc: add getrandom()

Thomas Weißschuh posted 15 patches 7 months, 3 weeks ago
There is a newer version of this series
[PATCH 05/15] tools/nolibc: add getrandom()
Posted by Thomas Weißschuh 7 months, 3 weeks ago
This is used in various selftests and will be handy when integrating
those with nolibc.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
---
 tools/include/nolibc/Makefile                |  1 +
 tools/include/nolibc/nolibc.h                |  1 +
 tools/include/nolibc/sys/random.h            | 32 ++++++++++++++++++++++++++++
 tools/testing/selftests/nolibc/nolibc-test.c | 19 +++++++++++++++++
 4 files changed, 53 insertions(+)

diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile
index e05862cd08051685112f067d6eb45716613dd43c..b22ff1e268b2e4bd788e974d6d8f2e1ef96dfc5f 100644
--- a/tools/include/nolibc/Makefile
+++ b/tools/include/nolibc/Makefile
@@ -47,6 +47,7 @@ all_files := \
 		sys.h \
 		sys/auxv.h \
 		sys/mman.h \
+		sys/random.h \
 		sys/stat.h \
 		sys/syscall.h \
 		sys/time.h \
diff --git a/tools/include/nolibc/nolibc.h b/tools/include/nolibc/nolibc.h
index d1b949e094eeb7cc0fe875deeafa4c972ecf35b2..3f329feb379c4c808d2e56fbb2b7a6c4b08a7c0d 100644
--- a/tools/include/nolibc/nolibc.h
+++ b/tools/include/nolibc/nolibc.h
@@ -98,6 +98,7 @@
 #include "sys.h"
 #include "sys/auxv.h"
 #include "sys/mman.h"
+#include "sys/random.h"
 #include "sys/stat.h"
 #include "sys/syscall.h"
 #include "sys/time.h"
diff --git a/tools/include/nolibc/sys/random.h b/tools/include/nolibc/sys/random.h
new file mode 100644
index 0000000000000000000000000000000000000000..b5a904dffbfb5039ca8f9efb9eaf68e7bb1716b5
--- /dev/null
+++ b/tools/include/nolibc/sys/random.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * random definitions for NOLIBC
+ * Copyright (C) 2025 Thomas Weißschuh <thomas.weissschuh@linutronix.de>
+ */
+
+#ifndef _NOLIBC_SYS_RANDOM_H
+#define _NOLIBC_SYS_RANDOM_H
+
+#include "../arch.h"
+#include "../sys.h"
+
+/*
+ * ssize_t getrandom(void *buf, size_t buflen, unsigned int flags);
+ */
+
+static __attribute__((unused))
+ssize_t sys_getrandom(void *buf, size_t buflen, unsigned int flags)
+{
+       return my_syscall3(__NR_getrandom, buf, buflen, flags);
+}
+
+static __attribute__((unused))
+ssize_t getrandom(void *buf, size_t buflen, unsigned int flags)
+{
+       return __sysret(sys_getrandom(buf, buflen, flags));
+}
+
+/* make sure to include all global symbols */
+#include "../nolibc.h"
+
+#endif /* _NOLIBC_SYS_RANDOM_H */
diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index abe0ae794208762f6d91ad81e902fbf77253a1c1..95d08e9ccf5b3be924548100e9621cd47f39e8c2 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -20,6 +20,7 @@
 #include <sys/mman.h>
 #include <sys/mount.h>
 #include <sys/prctl.h>
+#include <sys/random.h>
 #include <sys/reboot.h>
 #include <sys/resource.h>
 #include <sys/stat.h>
@@ -807,6 +808,23 @@ static int test_dirent(void)
 	return 0;
 }
 
+int test_getrandom(void)
+{
+	uint64_t rng = 0;
+	ssize_t ret;
+
+	ret = getrandom(&rng, sizeof(rng), 0);
+	if (ret != sizeof(rng))
+		return ret;
+
+	if (!rng) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	return 0;
+}
+
 int test_getpagesize(void)
 {
 	int x = getpagesize();
@@ -1124,6 +1142,7 @@ int run_syscall(int min, int max)
 		CASE_TEST(getdents64_root);   EXPECT_SYSNE(1, test_getdents64("/"), -1); break;
 		CASE_TEST(getdents64_null);   EXPECT_SYSER(1, test_getdents64("/dev/null"), -1, ENOTDIR); break;
 		CASE_TEST(directories);       EXPECT_SYSZR(proc, test_dirent()); break;
+		CASE_TEST(getrandom);         EXPECT_SYSZR(1, test_getrandom()); break;
 		CASE_TEST(gettimeofday_tv);   EXPECT_SYSZR(1, gettimeofday(&tv, NULL)); break;
 		CASE_TEST(gettimeofday_tv_tz);EXPECT_SYSZR(1, gettimeofday(&tv, &tz)); break;
 		CASE_TEST(getpagesize);       EXPECT_SYSZR(1, test_getpagesize()); break;

-- 
2.49.0

Re: [PATCH 05/15] tools/nolibc: add getrandom()
Posted by Willy Tarreau 7 months, 3 weeks ago
Hi Thomas,

On Wed, Apr 23, 2025 at 05:01:35PM +0200, Thomas Weißschuh wrote:
> --- /dev/null
> +++ b/tools/include/nolibc/sys/random.h
> @@ -0,0 +1,32 @@
> +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
> +/*
> + * random definitions for NOLIBC
> + * Copyright (C) 2025 Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> + */
> +

Note: don't forget to add your nolibc include here from the other series.

> +#ifndef _NOLIBC_SYS_RANDOM_H
> +#define _NOLIBC_SYS_RANDOM_H
> +
> +#include "../arch.h"
> +#include "../sys.h"
(...)

> diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
> index abe0ae794208762f6d91ad81e902fbf77253a1c1..95d08e9ccf5b3be924548100e9621cd47f39e8c2 100644
> --- a/tools/testing/selftests/nolibc/nolibc-test.c
> +++ b/tools/testing/selftests/nolibc/nolibc-test.c
(...)
> +int test_getrandom(void)
> +{
> +	uint64_t rng = 0;
> +	ssize_t ret;
> +
> +	ret = getrandom(&rng, sizeof(rng), 0);
> +	if (ret != sizeof(rng))
> +		return ret;
> +
> +	if (!rng) {
> +		errno = EINVAL;
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +

Just a thought about this one: in a not-so-distant past, getrandom()
could hang forever when lacking entropy (classical problem when booting
a headless machine having no RNG), and since a recent kernel it turned
to "only" multiple seconds. I'm not seeing any easy solution to this,
but we need to keep an eye on this one, and in case of bad reports,
maybe have this test as an opt-in or something like this. Anyway the
best way to know is to have it right now and wait for reports to
arrive.

Willy
Re: [PATCH 05/15] tools/nolibc: add getrandom()
Posted by Thomas Weißschuh 7 months, 3 weeks ago
On Sat, Apr 26, 2025 at 12:31:58PM +0200, Willy Tarreau wrote:
> Hi Thomas,
> 
> On Wed, Apr 23, 2025 at 05:01:35PM +0200, Thomas Weißschuh wrote:
> > --- /dev/null
> > +++ b/tools/include/nolibc/sys/random.h
> > @@ -0,0 +1,32 @@
> > +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
> > +/*
> > + * random definitions for NOLIBC
> > + * Copyright (C) 2025 Thomas Weißschuh <thomas.weissschuh@linutronix.de>
> > + */
> > +
> 
> Note: don't forget to add your nolibc include here from the other series.

Ack. This series was sent before I got the idea about moving "#include nolibc.h".
I'll fix it up for v2.

> > +#ifndef _NOLIBC_SYS_RANDOM_H
> > +#define _NOLIBC_SYS_RANDOM_H
> > +
> > +#include "../arch.h"
> > +#include "../sys.h"
> (...)
> 
> > diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
> > index abe0ae794208762f6d91ad81e902fbf77253a1c1..95d08e9ccf5b3be924548100e9621cd47f39e8c2 100644
> > --- a/tools/testing/selftests/nolibc/nolibc-test.c
> > +++ b/tools/testing/selftests/nolibc/nolibc-test.c
> (...)
> > +int test_getrandom(void)
> > +{
> > +	uint64_t rng = 0;
> > +	ssize_t ret;
> > +
> > +	ret = getrandom(&rng, sizeof(rng), 0);
> > +	if (ret != sizeof(rng))
> > +		return ret;
> > +
> > +	if (!rng) {
> > +		errno = EINVAL;
> > +		return -1;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> 
> Just a thought about this one: in a not-so-distant past, getrandom()
> could hang forever when lacking entropy (classical problem when booting
> a headless machine having no RNG), and since a recent kernel it turned
> to "only" multiple seconds. I'm not seeing any easy solution to this,
> but we need to keep an eye on this one, and in case of bad reports,
> maybe have this test as an opt-in or something like this. Anyway the
> best way to know is to have it right now and wait for reports to
> arrive.

What about using GRND_NONBLOCK and mark the test as skipped if no entropy is
available?