From abeae3c0061c0599ac2f012b270d6b4c8f59c82f Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Thu, 16 Jan 2025 18:45:25 +0100 Subject: Linux: Fixes for getrandom fork handling Careful updates of grnd_alloc.len are required to ensure that after fork, grnd_alloc.states does not contain entries that are also encountered by __getrandom_reset_state in TCBs. For the same reason, it is necessary to overwrite the TCB state pointer with NULL before updating grnd_alloc.states in __getrandom_vdso_release. Before this change, different TCBs could share the same getrandom state after multi-threaded fork. This would be a critical security bug (predictable randomness) if not caught during development. The additional check in stdlib/tst-arc4random-thread makes it more likely that the test fails due to the bugs mentioned above. Both __getrandom_reset_state and __getrandom_vdso_release could put reserved NULL pointers into the states array. This is also fixed with this commit. After these changes, no null pointers were observed in the states array during testing. Reviewed-by: Adhemerval Zanella --- stdlib/tst-arc4random-thread.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'stdlib') diff --git a/stdlib/tst-arc4random-thread.c b/stdlib/tst-arc4random-thread.c index b7889b6..cb7c351 100644 --- a/stdlib/tst-arc4random-thread.c +++ b/stdlib/tst-arc4random-thread.c @@ -49,7 +49,7 @@ static const int sizes[] = { 12, 15, 16, 17, 24, 31, max_size }; struct blob { unsigned int size; - int thread_id; + int thread_id; /* -1 means after fork. */ unsigned int index; unsigned char bytes[max_size]; }; @@ -323,6 +323,20 @@ do_test_func (const char *fname, void (*func)(unsigned char *, size_t)) } } + for (struct blob *p = dynarray_blob_begin (&global_result); + p < end; ++p) + { + unsigned int sum = 0; + for (unsigned int i = 0; i < p->size; ++i) + sum += p->bytes[i]; + if (sum == 0) + { + support_record_failure (); + printf ("error: all-zero result of length %u on thread %d\n", + p->size, p->thread_id); + } + } + dynarray_blob_free (&global_result); return 0; -- cgit v1.1