malloc: Fix clobbered errno when getrandom failed [BZ #29624]

Message ID 20220929083352.11890-1-peterlin@andestech.com
State Superseded
Headers
Series malloc: Fix clobbered errno when getrandom failed [BZ #29624] |

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent
dj/TryBot-32bit success Build for i686

Commit Message

Yu-Chien Peter Lin Sept. 29, 2022, 8:33 a.m. UTC
  The patch resets errno when getrandom syscall failed, which will
result in errno clobbered at statically linked program startup. This
scenario is possible if getrandom is called by tcache_key_initialize
when crng is not ready thus EAGAIN is returned.

Fixes bug 29624.

Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
---
 malloc/malloc.c | 1 +
 1 file changed, 1 insertion(+)
  

Comments

Florian Weimer Sept. 29, 2022, 10 a.m. UTC | #1
* Yu Chien Peter Lin:

> The patch resets errno when getrandom syscall failed, which will
> result in errno clobbered at statically linked program startup. This
> scenario is possible if getrandom is called by tcache_key_initialize
> when crng is not ready thus EAGAIN is returned.
>
> Fixes bug 29624.
>
> Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com>
> ---
>  malloc/malloc.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> index 953183e956..21f2bf5431 100644
> --- a/malloc/malloc.c
> +++ b/malloc/malloc.c
> @@ -3140,6 +3140,7 @@ tcache_key_initialize (void)
>  #if __WORDSIZE == 64
>        tcache_key = (tcache_key << 32) | random_bits ();
>  #endif
> +      __set_errno(0);
>      }
>  }

Sorry, this is wrong for the dynamically linked case because we do not
call malloc before calling the main function.  The first call to
malloc will set errno to 0, which is observable by the application in
this case.  And such errno-setting behavior is not permitted by POSIX.

You need to save and restore errno instead.
  

Patch

diff --git a/malloc/malloc.c b/malloc/malloc.c
index 953183e956..21f2bf5431 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -3140,6 +3140,7 @@  tcache_key_initialize (void)
 #if __WORDSIZE == 64
       tcache_key = (tcache_key << 32) | random_bits ();
 #endif
+      __set_errno(0);
     }
 }