_REENT_CHECK_VERIFY calls __assert_func even if NDEBUG is defined

R. Diez rdiezmail-newlib@yahoo.de
Mon Apr 27 20:29:08 GMT 2020


> The code does not disable via NDEBUG because it is a fix for a CVE.
> It is not (and should not be) tied to user control over usage of the assert macro.
> [...]

First of all, thanks for you quick answer.

I guess you mean CVE-2019-14871.

The "fix" for this CVE feels wrong. It seems that you are trading accessing a NULL pointer with a total firmware crash. I believe that there is no other way that __assert_func() could behave to "fix" this problem. Well, that is trading a security problem for a denial of service problem. This is not really properly fixing the problem.

Firstly, is there no other routine to abort the firmware? __assert_func() should only be used together with assert(). Is it documented anywhere that __assert_func() must stop execution in order to prevent a security hole?

Is there a way to avoid malloc() at all at a place where the user does not expect for it to happen? For example, preallocating all memory that might be needed. If may be worth the trade-off space vs safety.

Like I said, my firmware does not use threads at all. Is there a way to drop all these reentrancy stuff? I am already using --disable-newlib-multithread .

In any case, I though the assertion message "REENT malloc succeeded" is wrong, it should probably read "REENT malloc failed". Or am I reading the code wrong?

Thanks again,
  rdiez

 newlib-3.3.0/newlib/libc/stdlib/rand.c:78: undefined reference to `__assert_func'
> 
> I tracked it down to this definition:
> 
> /* Specify how to handle reent_check malloc failures. */
> #ifdef _REENT_CHECK_VERIFY
> #include <assert.h>
> #define __reent_assert(x) ((x) ? (void)0 : __assert_func(__FILE__, __LINE__, (char *)0, "REENT malloc succeeded"))
> #else
> #define __reent_assert(x) ((void)0)
> #endif
> 
> This is unfortunate. First of all, I wonder what happens if malloc fails and there is no assert. Will there be a crash?
> 
> Then, I would like to assert() in debug builds, and not in release builds. My code does not define __assert_func in release builds, because assertions are only supposed to work if NDEBUG is not defined. That has been working fine for years, until this Newlib version.
> 
> I am configuring Newlib with --disable-newlib-multithread , because my embedded firmware has no threads. But I guess I still have to deal with "struct _reent", don't I? I would have hoped that, in this single-thread situation, any reentrancy structure could be allocated statically. Or is there any way to avoid this malloc()?
> 
> Thanks in advance,
>   rdiez
> 
> 


More information about the Newlib mailing list