Race condition in initialisation of stdio standard streams

Sean Harte sean.harte@linux.intel.com
Fri Mar 2 02:40:00 GMT 2012


I believe there is a race condition in the initialisation and use of
recursive locks used in the _stdin, _stdout, and _stderr files. In
__sinit() in findfp.c, the __sdidinit field is set to 1 before the actual
initialisation is done. Other threads could read this field (e.g. by using
the CHECK_INIT() macro in local.h) and proceed to access one of the
standard files before it is initialised. This can result in unwanted
behaviour due to calling _flockfile() before the lock is setup.

Such behaviour can be reproduced by simultaneously calling a function that
will result in initialisation of a standard file in multiple threads (on a
SMP system). For example if _stdout is not yet initialised and printf() is
called on multiple threads simultaneously, sometimes only one thread will
print output.

This behaviour can be fixed by moving the setting of __sdidinit in
__sinit() to after the standard files are initialised, putting it
immediately before the call to __sinit_lock_release(). Preferably there
should be a memory barrier before setting __sdidinit also.

Seán Harte

More information about the Newlib mailing list