[PATCH] tools/nolibc: stackprotector: Avoid stalling program startup if crng is not init yet

Daniel Palmer posted 1 patch 2 days, 8 hours ago
tools/include/nolibc/stackprotector.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
[PATCH] tools/nolibc: stackprotector: Avoid stalling program startup if crng is not init yet
Posted by Daniel Palmer 2 days, 8 hours ago
We are using the getrandom syscall to get a random seed for the
stack protector canary but we are calling it with no flags which means
it'll block until there is some real randomness to return.

This means that if the crng is not ready yet program startup will
block and if you are unlucky that could be for a long time and
look like the program has crashed.

There is a comment in the code about mixing in the pid to make
sure the canary isn't 0 even if getrandom fails so it seems ok
to pass the non-blocking and insecure flags so it doesn't block
and potentially return something even if the crng is not init
yet.

Fixes: 7188d4637e95 ("tools/nolibc: add support for stack protector")
Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---

The insecure flag is apparently from 5.6, I think Willy said before
we are trying to keep nolibc working on the oldest LTS kernel.
That seems to be 5.10 so I think its ok?

Anyhow, I switched compilers for my nommu target and everything
stopped working, tracked it down to this. my other compiler must
have not supported the stack protector.

 tools/include/nolibc/stackprotector.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/include/nolibc/stackprotector.h b/tools/include/nolibc/stackprotector.h
index e11c20c75465..916a92062ba0 100644
--- a/tools/include/nolibc/stackprotector.h
+++ b/tools/include/nolibc/stackprotector.h
@@ -42,7 +42,8 @@ uintptr_t __stack_chk_guard;
 
 static __nolibc_no_stack_protector void __stack_chk_init(void)
 {
-	__nolibc_syscall3(__NR_getrandom, &__stack_chk_guard, sizeof(__stack_chk_guard), 0);
+	__nolibc_syscall3(__NR_getrandom, &__stack_chk_guard, sizeof(__stack_chk_guard),
+			  GRND_INSECURE | GRND_NONBLOCK);
 	/* a bit more randomness in case getrandom() fails, ensure the guard is never 0 */
 	if (__stack_chk_guard != (uintptr_t) &__stack_chk_guard)
 		__stack_chk_guard ^= (uintptr_t) &__stack_chk_guard;
-- 
2.53.0
Re: [PATCH] tools/nolibc: stackprotector: Avoid stalling program startup if crng is not init yet
Posted by Willy Tarreau 2 days, 8 hours ago
Hi Daniel!

On Fri, May 22, 2026 at 06:07:26PM +0900, Daniel Palmer wrote:
> We are using the getrandom syscall to get a random seed for the
> stack protector canary but we are calling it with no flags which means
> it'll block until there is some real randomness to return.
> 
> This means that if the crng is not ready yet program startup will
> block and if you are unlucky that could be for a long time and
> look like the program has crashed.
> 
> There is a comment in the code about mixing in the pid to make
> sure the canary isn't 0 even if getrandom fails so it seems ok
> to pass the non-blocking and insecure flags so it doesn't block
> and potentially return something even if the crng is not init
> yet.
> 
> Fixes: 7188d4637e95 ("tools/nolibc: add support for stack protector")
> Signed-off-by: Daniel Palmer <daniel@thingy.jp>

Acked-by: Willy Tarreau <w@1wt.eu>

> ---
> 
> The insecure flag is apparently from 5.6, I think Willy said before
> we are trying to keep nolibc working on the oldest LTS kernel.
> That seems to be 5.10 so I think its ok?

Sounds reasonable. We could also condition the flag to its existence
if it causes issues.

> Anyhow, I switched compilers for my nommu target and everything
> stopped working, tracked it down to this. my other compiler must
> have not supported the stack protector.

Possible, indeed.

Thanks!
Willy

> 
>  tools/include/nolibc/stackprotector.h | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/include/nolibc/stackprotector.h b/tools/include/nolibc/stackprotector.h
> index e11c20c75465..916a92062ba0 100644
> --- a/tools/include/nolibc/stackprotector.h
> +++ b/tools/include/nolibc/stackprotector.h
> @@ -42,7 +42,8 @@ uintptr_t __stack_chk_guard;
>  
>  static __nolibc_no_stack_protector void __stack_chk_init(void)
>  {
> -	__nolibc_syscall3(__NR_getrandom, &__stack_chk_guard, sizeof(__stack_chk_guard), 0);
> +	__nolibc_syscall3(__NR_getrandom, &__stack_chk_guard, sizeof(__stack_chk_guard),
> +			  GRND_INSECURE | GRND_NONBLOCK);
>  	/* a bit more randomness in case getrandom() fails, ensure the guard is never 0 */
>  	if (__stack_chk_guard != (uintptr_t) &__stack_chk_guard)
>  		__stack_chk_guard ^= (uintptr_t) &__stack_chk_guard;
> -- 
> 2.53.0
>
Re: [PATCH] tools/nolibc: stackprotector: Avoid stalling program startup if crng is not init yet
Posted by Thomas Weißschuh 2 days, 3 hours ago
On 2026-05-22 11:39:27+0200, Willy Tarreau wrote:
> On Fri, May 22, 2026 at 06:07:26PM +0900, Daniel Palmer wrote:
> > We are using the getrandom syscall to get a random seed for the
> > stack protector canary but we are calling it with no flags which means
> > it'll block until there is some real randomness to return.
> > 
> > This means that if the crng is not ready yet program startup will
> > block and if you are unlucky that could be for a long time and
> > look like the program has crashed.
> > 
> > There is a comment in the code about mixing in the pid to make
> > sure the canary isn't 0 even if getrandom fails so it seems ok
> > to pass the non-blocking and insecure flags so it doesn't block
> > and potentially return something even if the crng is not init
> > yet.
> > 
> > Fixes: 7188d4637e95 ("tools/nolibc: add support for stack protector")
> > Signed-off-by: Daniel Palmer <daniel@thingy.jp>
> 
> Acked-by: Willy Tarreau <w@1wt.eu>
> 
> > ---
> > 
> > The insecure flag is apparently from 5.6, I think Willy said before
> > we are trying to keep nolibc working on the oldest LTS kernel.
> > That seems to be 5.10 so I think its ok?
> 
> Sounds reasonable. We could also condition the flag to its existence
> if it causes issues.

IMO we could even not use GRND_INSECURE and only use GRND_NONBLOCK.

> > Anyhow, I switched compilers for my nommu target and everything
> > stopped working, tracked it down to this. my other compiler must
> > have not supported the stack protector.

Did the random pool *never* fully initialize?
That sounds weird.

(...)


Thomas
Re: [PATCH] tools/nolibc: stackprotector: Avoid stalling program startup if crng is not init yet
Posted by Daniel Palmer 16 hours ago
Hi Thomas, Willy,

On Fri, 22 May 2026 at 23:46, Thomas Weißschuh <linux@weissschuh.net> wrote:
>
> On 2026-05-22 11:39:27+0200, Willy Tarreau wrote:
> > > The insecure flag is apparently from 5.6, I think Willy said before
> > > we are trying to keep nolibc working on the oldest LTS kernel.
> > > That seems to be 5.10 so I think its ok?
> >
> > Sounds reasonable. We could also condition the flag to its existence
> > if it causes issues.
>
> IMO we could even not use GRND_INSECURE and only use GRND_NONBLOCK.

How about this:

static __nolibc_no_stack_protector void __stack_chk_init(void)
{
       int ret = -EINVAL;

       /* GRND_INSECURE is available in kernel 5.6+ */
#ifdef GRND_INSECURE
       ret = __nolibc_syscall3(__NR_getrandom, &__stack_chk_guard,
sizeof(__stack_chk_guard),
                               GRND_INSECURE | GRND_NONBLOCK);
#endif

       /* GRND_INSECURE wasn't defined at build time or the above call
to getrandom failed because
        * the running kernel didn't understand it.
        */
       if (ret == -EINVAL) {
               __nolibc_syscall3(__NR_getrandom, &__stack_chk_guard,
sizeof(__stack_chk_guard),
                                 GRND_NONBLOCK);
       }

       /* a bit more randomness in case getrandom() fails, ensure the
guard is never 0 */
       if (__stack_chk_guard != (uintptr_t) &__stack_chk_guard)
               __stack_chk_guard ^= (uintptr_t) &__stack_chk_guard;
}

I think that would allow building with >=5.6 headers and running on
<5.6 and building on <5.6.
Maybe its too much. :)

Thanks,

Daniel
Re: [PATCH] tools/nolibc: stackprotector: Avoid stalling program startup if crng is not init yet
Posted by Daniel Palmer 1 day, 19 hours ago
Hi Thomas,

On Fri, 22 May 2026 at 23:46, Thomas Weißschuh <linux@weissschuh.net> wrote:

> > > Anyhow, I switched compilers for my nommu target and everything
> > > stopped working, tracked it down to this. my other compiler must
> > > have not supported the stack protector.
>
> Did the random pool *never* fully initialize?
> That sounds weird.

The crng init message is eventually printed after a while if I
interact with the shell[0].
Since my init, shell, everything is written with nolibc now there is
so little disk activity etc I don't think there are enough interrupts
happening to collect any randomness.
Maybe something to save some seeding data between boots is the next
tool I need to write.

0 - https://gist.github.com/fifteenhex/d4a284f34a605702f98a3db68261f46e
Re: [PATCH] tools/nolibc: stackprotector: Avoid stalling program startup if crng is not init yet
Posted by Willy Tarreau 13 hours ago
On Sat, May 23, 2026 at 07:29:53AM +0900, Daniel Palmer wrote:
> Hi Thomas,
> 
> On Fri, 22 May 2026 at 23:46, Thomas Weißschuh <linux@weissschuh.net> wrote:
> 
> > > > Anyhow, I switched compilers for my nommu target and everything
> > > > stopped working, tracked it down to this. my other compiler must
> > > > have not supported the stack protector.
> >
> > Did the random pool *never* fully initialize?
> > That sounds weird.
> 
> The crng init message is eventually printed after a while if I
> interact with the shell[0].
> Since my init, shell, everything is written with nolibc now there is
> so little disk activity etc I don't think there are enough interrupts
> happening to collect any randomness.

Yeah I've known this problem as well for years on small headless
systems that never finish to boot if you ever called getrandom(),
before GRND_INSECURE existed. Several of us used to patch it not
to wait or used to change boot code not to call this function.

> Maybe something to save some seeding data between boots is the next
> tool I need to write.

Since modern kernels support GRND_INSECURE, I suspect you would just
be wasting your time. Better rely on this for boot code.

Willy
Re: [PATCH] tools/nolibc: stackprotector: Avoid stalling program startup if crng is not init yet
Posted by Thomas Weißschuh 9 hours ago
On 2026-05-24 06:25:37+0200, Willy Tarreau wrote:
> On Sat, May 23, 2026 at 07:29:53AM +0900, Daniel Palmer wrote:
> > On Fri, 22 May 2026 at 23:46, Thomas Weißschuh <linux@weissschuh.net> wrote:

(...)

> > Maybe something to save some seeding data between boots is the next
> > tool I need to write.
> 
> Since modern kernels support GRND_INSECURE, I suspect you would just
> be wasting your time. Better rely on this for boot code.

If it's good enough for Willy, it is certainly good enough for me, too.
Or we could switch to AT_RANDOM, but the current aproach is fine for me.


Thomas
Re: [PATCH] tools/nolibc: stackprotector: Avoid stalling program startup if crng is not init yet
Posted by Daniel Palmer 2 days, 8 hours ago
Sorry for the spam.

On Fri, 22 May 2026 at 18:07, Daniel Palmer <daniel@thingy.jp> wrote:
> There is a comment in the code about mixing in the pid to make
> sure the canary isn't 0 even if getrandom fails so it seems ok
> to pass the non-blocking and insecure flags so it doesn't block
> and potentially return something even if the crng is not init
> yet.

My brain made the pid part up. I checked again add it's not using the pid..
anyhow the code still seems to have been prepared for getrandom
failing so it seems ok to let it actually fail.

Thanks,

Daniel