This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix problem with file locking used before initialised


Please find attached a patch against libc in newlib to fix I a problem I have encountered in the use of the _flockfile/_funlockfile API on the standard I/O streams (stderr, stdout and stdin).

The problems stems from the fact that the FILE objects for these I/O streams are initially statically allocated in the global re-entrancy structure (aka the "impure" pointer) and they are not 100% initialised by static initialisation. This is overcome by the use of the CHECK_INIT and _REENT_SMALL_CHECK_INIT macros which complete the initialisation of the standard FILE I/O objects in a re-entrancy structure. As part of the initialisation of the standard I/O FILE objects the file lock objects are initialised.

Unfortunately the _flockfile/_funlockfile functions are used before CHECK_INIT is called and therefore the FILE lock object could end up in an unknown state depending on the implementation of the FILE lock object and the method of initialisation. To solve this problem it is necessary to call CHECK_INIT before _flockfile/_funlockfile are called in any function that takes a FILE * object as an argument (which normally is a user level function). The attached patch attempts to fix this problem.

Note that I have modified some machine specific files unfortunately I am unable to test so you may not wish to commit these changes (powerpc and arm files).

Cheers,

Antony.
2005-01-24  Antony King  <antony.king@st.com>

	* libc/stdio/clearerr.c (clearerr): Ensure CHECK_INIT() is
	called before _flockfile to prevent lock object use before
	initialisation. _REENT_SMALL_CHECK_INIT() and CHECK_INIT()
	take a struct _reent * instead of a FILE *.
	* libc/stdio/fclose.c (_fclose_r): Ditto.
	* libc/stdio/feof.c (feof): Ditto.
	* libc/stdio/ferror.c (ferror): Ditto.
	* libc/stdio/fflush.c (fflush): Ditto.
	* libc/stdio/fgetc.c (fgetc): Ditto.
	* libc/stdio/fgets.c (fgets): Ditto.
	* libc/stdio/fileno.c (fileno): Ditto.
	* libc/stdio/fputc.c (fputc): Ditto.
	* libc/stdio/fputs.c (fputs): Ditto.
	* libc/stdio/fread.c (fread): Ditto.
	* libc/stdio/freopen.c (_freopen_r): Ditto.
	* libc/stdio/fseek.c (_fseek_r): Ditto.
	* libc/stdio/ftell.c (_ftell_r): Ditto.
	* libc/stdio/fwrite.c (fwrite): Ditto.
	* libc/stdio/getc.c (getc): Ditto.
	* libc/stdio/getdelim.c (__getdelim): Ditto.
	* libc/stdio/putc.c (putc): Ditto.
	* libc/stdio/setvbuf.c (setvbuf): Ditto.
	* libc/stdio/ungetc.c (_ungetc_r): Ditto.
	* libc/stdio/vfprintf.c (_VFPRINTF_R): Ditto.
	* libc/stdio64/freopen64.c (_freopen64_r): Ditto.
	* libc/stdio64/fseeko64.c (_fseeko64_r): Ditto.
	* libc/stdio64/ftello64.c (_ftello64_r): Ditto.
	* libc/stdio/local.h (CHECK_INIT): Argument is now a struct
	_reent * instead of a FILE * and so replace incorrect use of
	_REENT with argument.
	* libc/sys/arm/syscalls.c (CHECK_INIT): Ditto.
	* libc/stdio/getchar.c (getchar): _REENT_SMALL_CHECK_INIT() and
	CHECK_INIT() take a struct _reent * instead of a FILE *.
	* libc/stdio/iprintf.c (iprintf, _iprintf_r): Ditto.
	* libc/stdio/iscanf.c (iscanf, _iscanf_r): Ditto.
	* libc/stdio/perror.c (perror): Ditto.
	* libc/stdio/printf.c (printf, _printf_r): Ditto.
	* libc/stdio/putchar.c (putchar): Ditto.
	* libc/stdio/puts.c (puts): Ditto.
	* libc/stdio/refill.c (__srefill): Ditto.
	* libc/stdio/scanf.c (scanf, _scanf_r): Ditto.
	* libc/stdio/vfscanf.c (VFSCANF, _VFSCANF_R): Ditto.
	* libc/stdio/viprintf.c (viprintf, _viprintf_r): Ditto.
	* libc/stdio/viscanf.c (viscanf, _viscanf_r): Ditto.
	* libc/stdio/vprintf.c (vprintf, _vprintf_r): Ditto.
	* libc/stdio/vscanf.c (vscanf, _vscanf_r): Ditto.
	* libc/stdio/wbuf.c (__swbuf): Ditto.
	* libc/stdio/wsetup.c (__swsetup): Ditto.
	* libc/stdlib/mallocr.c (malloc_stats): Ditto.
	* libc/stdlib/mstats.c (_mstats_r): Ditto.
	* libc/include/sys/reent.h (_REENT_SMALL_CHECK_INIT): Ditto.
	* libc/machine/powerpc/vfscanf.c (vfscanf): Ditto.
	* libc/stdio/fgetpos.c (_fgetpos_r): Removed unnecessary calls
	to _flockfile and _funlockfile; rely on locking in _ftell_r.
	* libc/stdio64/fgetpos64.c (_fgetpos64_r): Ditto (_ftello64_r).
	* libc/machine/powerpc/vfprintf.c (__sbprintf): Removed unnecessary
	initialision of _data field in FILE structure.
	* libc/machine/powerpc/vfprintf.c (VFPRINTF): Added CHECK_INIT() call.

Attachment: newlib.diffs.gz
Description: GNU Zip compressed data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]