Change _stdio_handles_locking into _caller_handles_locking.

It is reported by tsan that funlockfile() can unlock an unlocked mutex.
It happens when printf() is called before fopen() or other stdio stuff.
As FLOCKFILE(fp) is called before __sinit(), _stdio_handles_locking is false,
and _FLOCK(fp) will not be locked. But then cantwrite(fp) in __vfprintf()
calls__sinit(), which makes _stdio_handles_locking become true, and
FUNLOCKFILE(fp) unlocks _FLOCK(fp).

Change _stdio_handles_locking into _caller_handles_locking,
so __sinit() won't change its value. Add test due to my previous fault.

Bug: 25392375
Change-Id: I483e3c3cdb28da65e62f1fd9615bf58c5403b4dd
This commit is contained in:
Yabin Cui
2015-11-19 13:52:16 -08:00
parent 0ebe2f07c3
commit 76144aaa63
6 changed files with 58 additions and 32 deletions

View File

@@ -74,7 +74,7 @@ void _flushlbf() {
}
int __fsetlocking(FILE* fp, int type) {
int old_state = _EXT(fp)->_stdio_handles_locking ? FSETLOCKING_INTERNAL : FSETLOCKING_BYCALLER;
int old_state = _EXT(fp)->_caller_handles_locking ? FSETLOCKING_BYCALLER : FSETLOCKING_INTERNAL;
if (type == FSETLOCKING_QUERY) {
return old_state;
}
@@ -84,7 +84,7 @@ int __fsetlocking(FILE* fp, int type) {
__libc_fatal("Bad type (%d) passed to __fsetlocking", type);
}
_EXT(fp)->_stdio_handles_locking = (type == FSETLOCKING_INTERNAL);
_EXT(fp)->_caller_handles_locking = (type == FSETLOCKING_BYCALLER);
return old_state;
}