From 8dda7382646a6664128eb6847ddae8ba02dfe870 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Thu, 17 Mar 2022 18:47:18 +0000 Subject: [PATCH 1/3] getrandom(2): Fix return value checks in automatic tests. The syscall only guarantees up to 256 bytes in a single go -- if interrupted, it might return short, but if the caller requested at least 256 bytes it will definitely return 256 bytes. --- tests/lib/libc/sys/t_getrandom.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/lib/libc/sys/t_getrandom.c b/tests/lib/libc/sys/t_getrandom.c index 0d5780e17215..1d42288b5790 100644 --- a/tests/lib/libc/sys/t_getrandom.c +++ b/tests/lib/libc/sys/t_getrandom.c @@ -32,6 +32,8 @@ #include __RCSID("$NetBSD: t_getrandom.c,v 1.3 2020/08/25 01:37:38 riastradh Exp $"); +#include + #include #include @@ -89,7 +91,8 @@ ATF_TC_BODY(getrandom_default, tc) if (n == -1) { ATF_CHECK_EQ(errno, EINTR); } else { - ATF_CHECK_EQ((size_t)n, sizeof buf); + ATF_CHECK(n >= (ssize_t)MIN(256, sizeof buf)); + ATF_CHECK((size_t)n <= sizeof buf); ATF_CHECK(memcmp(buf, zero24, 24) != 0); ATF_CHECK(memcmp(buf + sizeof buf - 24, zero24, 24) != 0); } @@ -111,7 +114,8 @@ ATF_TC_BODY(getrandom_nonblock, tc) if (n == -1) { ATF_CHECK_EQ(errno, EAGAIN); } else { - ATF_CHECK_EQ((size_t)n, sizeof buf); + ATF_CHECK(n >= (ssize_t)MIN(256, sizeof buf)); + ATF_CHECK((size_t)n <= sizeof buf); ATF_CHECK(memcmp(buf, zero24, 24) != 0); ATF_CHECK(memcmp(buf + sizeof buf - 24, zero24, 24) != 0); } @@ -130,7 +134,8 @@ ATF_TC_BODY(getrandom_insecure, tc) memset(buf, 0, sizeof buf); n = getrandom(buf, sizeof buf, GRND_INSECURE); ATF_CHECK(n != -1); - ATF_CHECK_EQ((size_t)n, sizeof buf); + ATF_CHECK(n >= (ssize_t)MIN(256, sizeof buf)); + ATF_CHECK((size_t)n <= sizeof buf); ATF_CHECK(memcmp(buf, zero24, 24) != 0); ATF_CHECK(memcmp(buf + sizeof buf - 24, zero24, 24) != 0); } @@ -149,7 +154,8 @@ ATF_TC_BODY(getrandom_insecure_nonblock, tc) memset(buf, 0, sizeof buf); n = getrandom(buf, sizeof buf, GRND_INSECURE|GRND_NONBLOCK); ATF_CHECK(n != -1); - ATF_CHECK_EQ((size_t)n, sizeof buf); + ATF_CHECK(n >= (ssize_t)MIN(256, sizeof buf)); + ATF_CHECK((size_t)n <= sizeof buf); ATF_CHECK(memcmp(buf, zero24, 24) != 0); ATF_CHECK(memcmp(buf + sizeof buf - 24, zero24, 24) != 0); } From e35ead38d555ae0bc6623575af12896248ccd22b Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Thu, 17 Mar 2022 18:55:26 +0000 Subject: [PATCH 2/3] getrandom(2): Eliminate blocking path for default mode. Only with GRND_RANDOM does getrandom(2) block now. The semantics is now identical to /dev/random with GRND_RANDOM, and to /dev/urandom without. Experience has shown that applications calling getrandom are not in a position to interact meaningfully with system operators to solve system engineering problems; instead it just causes confusing hangs. We now have various approaches to solve the system engineering problem, or alert operators to the problem, in better places like sysinst, the daily security report, and rc.log. --- lib/libc/sys/getrandom.2 | 213 ++++++++----------------------- sys/kern/kern_entropy.c | 12 -- sys/kern/sys_getrandom.c | 41 +++--- sys/sys/entropy.h | 1 - tests/lib/libc/sys/t_getrandom.c | 24 ++-- 5 files changed, 84 insertions(+), 207 deletions(-) diff --git a/lib/libc/sys/getrandom.2 b/lib/libc/sys/getrandom.2 index ffe376cdd939..06aeafd76fc6 100644 --- a/lib/libc/sys/getrandom.2 +++ b/lib/libc/sys/getrandom.2 @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd January 13, 2020 +.Dd March 17, 2022 .Dt GETRANDOM 2 .Os .Sh NAME @@ -49,117 +49,41 @@ with up to independent uniform random bytes derived from the system's entropy pool. .Pp -The function may block until the system has full entropy, meaning that -the system has observed enough noise from physical processes that an -adversary cannot predict what state it is in: -.Bl -bullet -compact -.It -When the system has only partial entropy, the output of -.Fn getrandom -may be predictable. -.It -When the system has full entropy, the output is fit for use as -cryptographic key material. -.El -.Pp The .Fa flags -argument may be: -.Bl -tag -offset abcd -width GRND_INSECURE -.It Li 0 -Block until the system entropy pool has full entropy; then generate -arbitrarily much data. -.Em Recommended . -.Pp -If interrupted by a signal, may fail with -.Er EINTR -or return a short read. -If successful, guaranteed to return at least 256 bytes even if -interrupted. -.It Dv GRND_INSECURE -Do not block; instead fill -.Fa buf -with output derived from whatever is in the system entropy pool so -far. -Equivalent to reading from +argument should be zero, in which case this is equivalent to reading +from .Pa /dev/urandom ; see .Xr rnd 4 . -.Pp -If interrupted by a signal, may fail with -.Er EINTR -or return a short read. -If successful, guaranteed to return at least 256 bytes even if +If interrupted by a signal, may return a short read. +If successful, guaranteed to return up to 256 bytes even if interrupted. .Pp -Despite the name, this is secure as long as you only do it -.Em after -at least one successful call without -.Dv GRND_INSECURE , -such as -.Li "getrandom(..., 0)" -or -.Li "getrandom(..., GRND_RANDOM)" , -or after reading at least one byte from -.Pa /dev/random . -.Pp -.Sy WARNING : -If you use -.Dv GRND_INSECURE -.Em before -the system has full entropy. the output may enable an adversary to -search the possible states of the entropy pool by brute force, and -thereby reduce its entropy to zero. -Thus, incautious use of -.Dv GRND_INSECURE -can ruin the security of the whole system. -.Pp -.Nx -attempts to defend against this threat model by resetting the system's -entropy estimate to zero in this event, requiring gathering full -entropy again before -.Pa /dev/random -or -.Fn getrandom -without -.Dv GRND_INSECURE -will unblock, but other operating systems may not. +Other flags are available for source compatibility with Linux: +.Bl -tag -width "Dv GRND_NONBLOCK" +.It Dv GRND_INSECURE +No effect. +Exclusive of +.Dv GRND_RANDOM . .It Dv GRND_RANDOM -Block until the system entropy pool has full entropy; then generate a -small amount of data. Equivalent to reading from -.Pa /dev/random ; -see -.Xr rnd 4 . -This is provided mainly for source compatibility with Linux; there is -essentially no reason to ever use it. -.El -.Pp -The flag -.Dv GNRD_NONBLOCK -may also be included with bitwise-OR, in which case if -.Fn getrandom -would have blocked without -.Dv GRND_NONBLOCK , -it returns +.Pa /dev/random . +May block. +May return arbitrarily short reads. +Exclusive of +.Dv GRND_INSECURE . +Only for system integration logic, not for ordinary applications to +generate keys. +.It Dv GRND_NONBLOCK +If +.Nm +would block, fail with .Er EAGAIN -instead. -.Pp -Adding -.Dv GRND_NONBLOCK -to -.Dv GRND_INSECURE -has no effect; the combination -.Dv GRND_INSECURE Ns Li "|" Ns Li GRND_NONBLOCK -is equivalent to -.Dv GRND_INSECURE , -since -.Dv GRND_INSECURE -never blocks. -The combination -.Dv GRND_INSECURE Ns Li "|" Ns Li GRND_RANDOM -is nonsensical and fails with -.Er EINVAL . +instead of blocking. +Only has an effect if combined with +.Dv GRND_RANDOM . +.El .Sh RETURN VALUES If successful, .Fn getrandom @@ -172,25 +96,25 @@ returns \-1 and sets .Pp Since .Li "getrandom(..., 0)" -and -.Li "getrandom(..., GRND_INSECURE)" -are guaranteed to return at least 256 bytes if successful, it -is sufficient to use, e.g., -.Bd -literal -compact - getrandom(buf, 32, 0) == -1 -.Ed -or -.Bd -literal -compact - getrandom(buf, 32, GRND_INSECURE) == -1 +is guaranteed to return up to 256 bytes if successful, it is safe to +use the idiom: +.Bd -literal + if (getrandom(buf, 32, 0) == -1) + goto err; .Ed -to detect failure. -However, with +.Pp +If successful, this call is guaranteed to fill +.Fa buf +with the full 32 bytes. +.Pp +Note: With .Dv GRND_RANDOM , .Fn getrandom -may return as little as a single byte if successful. +may return as little as a single byte even if successful, so the caller +must check the return value for the number of bytes returned to +.Dv GRND_RANDOM +requests for more than a single byte. .Sh EXAMPLES -.Sy Recommended usage . -Generate a key for cryptography: .Bd -literal uint8_t secretkey[32]; @@ -198,53 +122,22 @@ Generate a key for cryptography: err(EXIT_FAILURE, "getrandom"); crypto_secretbox_xsalsa20poly1305(..., secretkey); .Ed -.Pp -Other idioms for illustration: -.Bl -bullet -.It -Wait for entropy once, and then generate many keys without waiting: -.Bd -literal - struct { uint8_t key[32]; } user[100]; - - if (getrandom(NULL, 0, 0) == -1) - err(EXIT_FAILURE, "getrandom"); - for (i = 0; i < 100; i++) - if (getrandom(user[i].key, sizeof user[i].key, - GRND_INSECURE) == -1) - err(EXIT_FAILURE, "getrandom"); -.Ed -.It -Twiddle thumbs while waiting for entropy: -.Bd -literal - uint8_t secretkey[32]; - - while (getrandom(secretkey, sizeof secretkey, GRND_NONBLOCK) - == -1) { - if (errno != EAGAIN) - err(EXIT_FAILURE, "getrandom"); - twiddle_thumbs(); - } - crypto_secretbox_xsalsa20poly1305(..., secretkey); -.Ed -.El -.Pp -(No examples of -.Dv GRND_RANDOM -because it is not useful.) .Sh ERRORS .Bl -tag -width Er .It Bq Er EAGAIN The +.Dv GRND_RANDOM +and .Dv GRND_NONBLOCK -flag was specified, and the system entropy pool does not have full +flags were specified, and the system entropy pool does not have full entropy. .It Bq Er EINTR The -.Dv GRND_NONBLOCK -flag was -.Em not -specified, the system entropy pool does not have full entropy, and the -process was interrupted by a signal while waiting. +.Dv GRND_RANDOM +flag was specified without +.Dv GRND_NONBLOCK , +the system entropy pool does not have full entropy, and the process was +interrupted by a signal while waiting. .It Bq Er EINVAL .Fa flags contains an unrecognized flag or a nonsensical combination of flags. @@ -273,11 +166,11 @@ with other I/O in .Xr select 2 , .Xr poll 2 , or -.Xr kqueue 2 . +.Xr kqueue 2 , +or to atomically unmask a set of signals while +.Fn getrandom +blocks. Instead, you can wait for a read from .Pa /dev/random ; see .Xr rnd 4 . -.Pp -.Dv GRND_RANDOM -is a little silly. diff --git a/sys/kern/kern_entropy.c b/sys/kern/kern_entropy.c index 72d449dc5287..73340648d1d9 100644 --- a/sys/kern/kern_entropy.c +++ b/sys/kern/kern_entropy.c @@ -647,18 +647,6 @@ entropy_epoch(void) return atomic_load_relaxed(&E->epoch); } -/* - * entropy_ready() - * - * True if the entropy pool has full entropy. - */ -bool -entropy_ready(void) -{ - - return atomic_load_relaxed(&E->needed) == 0; -} - /* * entropy_account_cpu(ec) * diff --git a/sys/kern/sys_getrandom.c b/sys/kern/sys_getrandom.c index 4ec268b426db..d451d9e75b5b 100644 --- a/sys/kern/sys_getrandom.c +++ b/sys/kern/sys_getrandom.c @@ -61,7 +61,6 @@ dogetrandom(struct uio *uio, unsigned int flags) uint8_t seed[NIST_HASH_DRBG_SEEDLEN_BYTES] = {0}; struct nist_hash_drbg drbg; uint8_t *buf; - int extractflags = 0; int error; KASSERT((flags & ~(GRND_RANDOM|GRND_INSECURE|GRND_NONBLOCK)) == 0); @@ -72,12 +71,10 @@ dogetrandom(struct uio *uio, unsigned int flags) buf = kmem_alloc(RANDOM_BUFSIZE, KM_SLEEP); /* - * Fast path: for short reads other than from /dev/random, if - * seeded or if INSECURE, just draw from per-CPU cprng_strong. + * Fast path: for short reads other than from /dev/random, just + * draw from per-CPU cprng_strong. */ - if (uio->uio_resid <= RANDOM_BUFSIZE && - !ISSET(flags, GRND_RANDOM) && - (entropy_ready() || ISSET(flags, GRND_INSECURE))) { + if (uio->uio_resid <= RANDOM_BUFSIZE && !ISSET(flags, GRND_RANDOM)) { /* Generate data and transfer it out. */ cprng_strong(user_cprng, buf, uio->uio_resid, 0); error = uiomove(buf, uio->uio_resid, uio); @@ -85,19 +82,27 @@ dogetrandom(struct uio *uio, unsigned int flags) } /* - * Try to get a seed from the entropy pool. Fail if we would - * block. If GRND_INSECURE, always return something even if it - * is partial entropy; if !GRND_INSECURE, set ENTROPY_HARDFAIL - * in order to tell entropy_extract not to bother drawing - * anything from a partial pool if we can't get full entropy. + * Try to get a seed from the entropy pool. + * + * - From /dev/random, wait for full entropy, and fail if signal or + * nonblocking before full entropy is ready. + * + * - From /dev/urandom, take what we can get. If we have only + * partial entropy, we'll use it, but entropy_extract will + * warn on the console and zero the system's entropy estimate + * to mitigate iterative guessing attacks. */ - if (!ISSET(flags, GRND_NONBLOCK) && !ISSET(flags, GRND_INSECURE)) - extractflags |= ENTROPY_WAIT|ENTROPY_SIG; - if (!ISSET(flags, GRND_INSECURE)) - extractflags |= ENTROPY_HARDFAIL; - error = entropy_extract(seed, sizeof seed, extractflags); - if (error && !ISSET(flags, GRND_INSECURE)) - goto out; + if (ISSET(flags, GRND_RANDOM)) { + int extractflags = ENTROPY_HARDFAIL; + + if (!ISSET(flags, GRND_NONBLOCK)) + extractflags |= ENTROPY_WAIT|ENTROPY_SIG; + error = entropy_extract(seed, sizeof seed, extractflags); + if (error) + goto out; + } else { + (void)entropy_extract(seed, sizeof seed, 0); + } /* Instantiate the DRBG. */ if (nist_hash_drbg_instantiate(&drbg, seed, sizeof seed, NULL, 0, diff --git a/sys/sys/entropy.h b/sys/sys/entropy.h index da6ef63abd61..92b5cd8ff9e2 100644 --- a/sys/sys/entropy.h +++ b/sys/sys/entropy.h @@ -51,7 +51,6 @@ struct knote; void entropy_bootrequest(void); void entropy_consolidate(void); unsigned entropy_epoch(void); -bool entropy_ready(void); int entropy_extract(void *, size_t, int); int entropy_poll(int); int entropy_kqfilter(struct knote *); diff --git a/tests/lib/libc/sys/t_getrandom.c b/tests/lib/libc/sys/t_getrandom.c index 1d42288b5790..30b8071f8427 100644 --- a/tests/lib/libc/sys/t_getrandom.c +++ b/tests/lib/libc/sys/t_getrandom.c @@ -88,14 +88,10 @@ ATF_TC_BODY(getrandom_default, tc) alarm(1); memset(buf, 0, sizeof buf); n = getrandom(buf, sizeof buf, 0); - if (n == -1) { - ATF_CHECK_EQ(errno, EINTR); - } else { - ATF_CHECK(n >= (ssize_t)MIN(256, sizeof buf)); - ATF_CHECK((size_t)n <= sizeof buf); - ATF_CHECK(memcmp(buf, zero24, 24) != 0); - ATF_CHECK(memcmp(buf + sizeof buf - 24, zero24, 24) != 0); - } + ATF_CHECK(n >= (ssize_t)MIN(256, sizeof buf)); + ATF_CHECK((size_t)n <= sizeof buf); + ATF_CHECK(memcmp(buf, zero24, 24) != 0); + ATF_CHECK(memcmp(buf + sizeof buf - 24, zero24, 24) != 0); alarm(0); } @@ -111,14 +107,10 @@ ATF_TC_BODY(getrandom_nonblock, tc) /* default, nonblocking */ memset(buf, 0, sizeof buf); n = getrandom(buf, sizeof buf, GRND_NONBLOCK); - if (n == -1) { - ATF_CHECK_EQ(errno, EAGAIN); - } else { - ATF_CHECK(n >= (ssize_t)MIN(256, sizeof buf)); - ATF_CHECK((size_t)n <= sizeof buf); - ATF_CHECK(memcmp(buf, zero24, 24) != 0); - ATF_CHECK(memcmp(buf + sizeof buf - 24, zero24, 24) != 0); - } + ATF_CHECK(n >= (ssize_t)MIN(256, sizeof buf)); + ATF_CHECK((size_t)n <= sizeof buf); + ATF_CHECK(memcmp(buf, zero24, 24) != 0); + ATF_CHECK(memcmp(buf + sizeof buf - 24, zero24, 24) != 0); } ATF_TC(getrandom_insecure); From 6502f93f89f37c4827cb4c78e9c6479db9e7a331 Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Thu, 17 Mar 2022 19:24:52 +0000 Subject: [PATCH 3/3] getrandom(2): Test interrupting getrandom. Make sure it returns at least 256 bytes. Adds 8sec to total test runtime on success. Sort ATF_TP_ADD_TC calls in t_getrandom.c while here. --- tests/lib/libc/sys/Makefile | 1 + tests/lib/libc/sys/t_getrandom.c | 135 +++++++++++++++++++++++++++++-- 2 files changed, 130 insertions(+), 6 deletions(-) diff --git a/tests/lib/libc/sys/Makefile b/tests/lib/libc/sys/Makefile index ac3e4a719ae6..70a80002f943 100644 --- a/tests/lib/libc/sys/Makefile +++ b/tests/lib/libc/sys/Makefile @@ -97,6 +97,7 @@ SRCS.t_mprotect= t_mprotect.c ${SRCS_EXEC_PROT} t_mprotect_helper.c LDADD.t_eventfd+= -lpthread LDADD.t_getpid+= -lpthread +LDADD.t_getrandom+= -lpthread LDADD.t_timerfd+= -lpthread LDADD.t_ptrace_sigchld+= -pthread -lm diff --git a/tests/lib/libc/sys/t_getrandom.c b/tests/lib/libc/sys/t_getrandom.c index 30b8071f8427..72c1ffba776f 100644 --- a/tests/lib/libc/sys/t_getrandom.c +++ b/tests/lib/libc/sys/t_getrandom.c @@ -38,6 +38,7 @@ __RCSID("$NetBSD: t_getrandom.c,v 1.3 2020/08/25 01:37:38 riastradh Exp $"); #include #include +#include #include #include #include @@ -125,7 +126,7 @@ ATF_TC_BODY(getrandom_insecure, tc) /* insecure */ memset(buf, 0, sizeof buf); n = getrandom(buf, sizeof buf, GRND_INSECURE); - ATF_CHECK(n != -1); + ATF_CHECK_MSG(n != -1, "getrandom failed: %s", strerror(errno)); ATF_CHECK(n >= (ssize_t)MIN(256, sizeof buf)); ATF_CHECK((size_t)n <= sizeof buf); ATF_CHECK(memcmp(buf, zero24, 24) != 0); @@ -145,7 +146,7 @@ ATF_TC_BODY(getrandom_insecure_nonblock, tc) /* insecure, nonblocking -- same as mere insecure */ memset(buf, 0, sizeof buf); n = getrandom(buf, sizeof buf, GRND_INSECURE|GRND_NONBLOCK); - ATF_CHECK(n != -1); + ATF_CHECK_MSG(n != -1, "getrandom failed: %s", strerror(errno)); ATF_CHECK(n >= (ssize_t)MIN(256, sizeof buf)); ATF_CHECK((size_t)n <= sizeof buf); ATF_CHECK(memcmp(buf, zero24, 24) != 0); @@ -270,19 +271,141 @@ ATF_TC_BODY(getrandom_fault, tc) ATF_CHECK_EQ(errno, EFAULT); } +sig_atomic_t stop; + +static void +sigusr1_ignore(int signo) +{ +} + +static void * +bother(void *cookie) +{ + pthread_t sampler = cookie; + int error; + + while (!stop) { + error = pthread_kill(sampler, SIGUSR1); + ATF_CHECK_EQ_MSG(error, 0, "pthread_kill failed: %s", + strerror(error)); + } + return NULL; +} + +static void * +sample(void *cookie) +{ + int flags = (int)(intptr_t)cookie; + ssize_t n; + + while (!stop) { + n = getrandom(buf + 1, 32, flags); + ATF_CHECK_MSG(n != -1, "getrandom failed: %s", + strerror(errno)); + ATF_CHECK(n == 32); + + n = getrandom(buf, sizeof buf, flags); + ATF_CHECK_MSG(n != -1, "getrandom failed: %s", + strerror(errno)); + ATF_CHECK(n >= 256); + ATF_CHECK((size_t)n <= sizeof buf); + } + return NULL; +} + +static void +botherbotherbother(int flags) +{ + struct sigaction sa; + pthread_t botherer, sampler; + int error; + + memset(&sa, 0, sizeof sa); + sa.sa_handler = sigusr1_ignore; + sigfillset(&sa.sa_mask); + sa.sa_flags = 0; /* no SA_RESTART */ + + ATF_CHECK_MSG(sigaction(SIGUSR1, &sa, NULL) != -1, + "sigaction(SIGUSR1): %s", strerror(errno)); + + error = pthread_create(&sampler, NULL, sample, + (void *)(intptr_t)flags); + ATF_CHECK_EQ_MSG(error, 0, "pthread_create botherer failed: %s", + strerror(error)); + error = pthread_create(&botherer, NULL, bother, sampler); + ATF_CHECK_EQ_MSG(error, 0, "pthread_create sampler failed: %s", + strerror(errno)); + + sleep(2); + stop = 1; + error = pthread_join(botherer, NULL); + ATF_CHECK_EQ_MSG(error, 0, "pthread_join botherer failed: %s", + strerror(error)); + error = pthread_join(sampler, NULL); + ATF_CHECK_EQ_MSG(error, 0, "pthread_join sampler failed: %s", + strerror(error)); +} + +ATF_TC(getrandom_intr_default); +ATF_TC_HEAD(getrandom_intr_default, tc) +{ + atf_tc_set_md_var(tc, "descr", "getrandom(..., 0) with interrupt"); +} +ATF_TC_BODY(getrandom_intr_default, tc) +{ + botherbotherbother(0); +} + +ATF_TC(getrandom_intr_nonblock); +ATF_TC_HEAD(getrandom_intr_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", + "getrandom(..., GRND_NONBLOCK) with interrupt"); +} +ATF_TC_BODY(getrandom_intr_nonblock, tc) +{ + botherbotherbother(GRND_NONBLOCK); +} + +ATF_TC(getrandom_intr_insecure); +ATF_TC_HEAD(getrandom_intr_insecure, tc) +{ + atf_tc_set_md_var(tc, "descr", + "getrandom(..., GRND_INSECURE) with interrupt"); +} +ATF_TC_BODY(getrandom_intr_insecure, tc) +{ + botherbotherbother(GRND_INSECURE); +} + +ATF_TC(getrandom_intr_insecure_nonblock); +ATF_TC_HEAD(getrandom_intr_insecure_nonblock, tc) +{ + atf_tc_set_md_var(tc, "descr", + "getrandom(..., GRND_INSECURE|GRND_NONBLOCK) with interrupt"); +} +ATF_TC_BODY(getrandom_intr_insecure_nonblock, tc) +{ + botherbotherbother(GRND_INSECURE|GRND_NONBLOCK); +} + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, getrandom_default); - ATF_TP_ADD_TC(tp, getrandom_nonblock); + ATF_TP_ADD_TC(tp, getrandom_fault); ATF_TP_ADD_TC(tp, getrandom_insecure); ATF_TP_ADD_TC(tp, getrandom_insecure_nonblock); + ATF_TP_ADD_TC(tp, getrandom_intr_default); + ATF_TP_ADD_TC(tp, getrandom_intr_nonblock); + ATF_TP_ADD_TC(tp, getrandom_intr_insecure); + ATF_TP_ADD_TC(tp, getrandom_intr_insecure_nonblock); + ATF_TP_ADD_TC(tp, getrandom_invalid); + ATF_TP_ADD_TC(tp, getrandom_nonblock); ATF_TP_ADD_TC(tp, getrandom_random); - ATF_TP_ADD_TC(tp, getrandom_random_nonblock); ATF_TP_ADD_TC(tp, getrandom_random_insecure); ATF_TP_ADD_TC(tp, getrandom_random_insecure_nonblock); - ATF_TP_ADD_TC(tp, getrandom_invalid); - ATF_TP_ADD_TC(tp, getrandom_fault); + ATF_TP_ADD_TC(tp, getrandom_random_nonblock); return atf_no_error(); }