[RFA]: race safe fwalk
Jeff Johnston
jjohnstn@redhat.com
Fri Mar 26 20:58:00 GMT 2004
Thomas Pfaff wrote:
> Jeff Johnston wrote:
>
>> Thomas Pfaff wrote:
>>
>>> This time with attachment.
>>>
>>> There is a possible race between fwalk and fopen:
>>>
>>> When a thread make a call to fopen the FILE * _flags will be set to 1
>>> in findfp to mark it used and later it will be changed to the real
>>> FILE flag.
>>>
>>> When another thread calls fwalk during that time fwalk will treat the
>>> FILE as already opened and calls the callback functions with the yet
>>> unopened and only partially initialized FILE *.
>>>
>>> This can be avoided by checking for fp->_flags != 0 && fp->_flags !=
>>> 1. Since _flags is signed short i did not check for _flags > 1. The
>>> flag should be set as the last step in an open call.
>>> I do not think that 1 is a valid _flag for an open file. Correct me
>>> if am wrong.
>>>
>>
>> Unfortunately, 1 is also line-buffered: __SLBF.
>>
>> What if instead, we use the _file field to check for a valid file. It
>> gets set to -1 by __sfp. Now, if we set _file inside the __sfp_lock
>> and then had fwalk() use the __sfp lock as well and check for _file !=
>> -1, plus have the open routines set the _file field last, this should
>> work equally as well. Comments?
>>
>
> I do not think that this can be done that easy anymore. The whole file
> list stuff must be better protected.
>
> Attached is a new patch. I am sorry for the delay.
>
No problem. I had to do some tweaking to get Linux to build with the change and
I added a missing include in freopen64.c. Patch checked in. Thanks.
-- Jeff J.
> 2004-03-22 Thomas Pfaff <tpfaff@gmx.net>
>
> * libc/stdio/fclose.c (fclose): Protect file pointer list when
> releasing a file.
> * libc/stdio/fcloseall.c (_fcloseall_r): Close all files via
> fwalk.
> * libc/stdio/fdopen.c (_fdopen_r): Add calls to
> _flockfile/_funlockfile.
> * libc/stdio/findfp.c: Move __sfp_lock. Change __sfp_lock type
> to recursive.
> Change __lock_acquire/__lock_release calls for __sfp_lock to
> __sfp_lock_acquire/__sfp_lock_release throughout.
> (std): Make sure that file lock is only initialized once.
> (__sfp): Move _file initialization. Initialize file lock.
> (__sfp_lock_acquire): New function.
> (__sfp_lock_release): Ditto.
> (__fp_lock_all): Remove __sfp_lock_acquire call.
> (__fp_unlock_all): Remove __sfp_lock_release call.
> * libc/stdio/fopen.c (_fopen_r): Protect file pointer list.
> Add calls to _flockfile/_funlockfile. Remove
> __lock_init_recursive call.
> * libc/stdio/freopen.c (_freopen_r): Protect file pointer list.
> * libc/stdio/fwalk.c (__fwalk): New static function.
> (_fwalk): Protect file pointer list. Use __fwalk to walk through
> file pointers.
> * libc/stdio/local.h: Add defines for
> __sfp_lock_acquire/__sfp_lock_release when
> single threaded. Add function prototypes otherwise.
> * libc/stdio64/fdopen64.c (_fdopen64_r): Add calls to
> _flockfile/_funlockfile.
> * libc/stdio/fopen64.c (_fopen64_r): Protect file pointer list.
> Add calls to _flockfile/_funlockfile. Remove
> __lock_init_recursive call.
> * libc/stdio/freopen64.c (_freopen64_r): Protect file pointer
> list.
More information about the Newlib
mailing list