From 6a03abcfd23f31d1df06eb0059830e22621282bb Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Mon, 3 Nov 2014 12:32:17 -0800 Subject: [PATCH] Ensure we initialize stdin/stdout/stderr's recursive mutexes. Bug: 18208568 Change-Id: I9da16ce0f9375bc363d1d02be706d73fd3b1e150 --- libc/Android.mk | 2 +- .../{upstream-openbsd/lib/libc => }/stdio/findfp.c | 28 +++++++++++++++------- tests/stdio_test.cpp | 17 +++++++++++++ 3 files changed, 37 insertions(+), 10 deletions(-) rename libc/{upstream-openbsd/lib/libc => }/stdio/findfp.c (89%) diff --git a/libc/Android.mk b/libc/Android.mk index 037febf3c..694c64228 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -58,6 +58,7 @@ libc_common_src_files := \ bionic/siginterrupt.c \ bionic/sigsetmask.c \ bionic/system_properties_compat.c \ + stdio/findfp.c \ stdio/snprintf.c\ stdio/sprintf.c \ stdio/stdio_ext.cpp \ @@ -399,7 +400,6 @@ libc_upstream_openbsd_src_files := \ upstream-openbsd/lib/libc/stdio/fgetwc.c \ upstream-openbsd/lib/libc/stdio/fgetws.c \ upstream-openbsd/lib/libc/stdio/fileno.c \ - upstream-openbsd/lib/libc/stdio/findfp.c \ upstream-openbsd/lib/libc/stdio/flags.c \ upstream-openbsd/lib/libc/stdio/fmemopen.c \ upstream-openbsd/lib/libc/stdio/fopen.c \ diff --git a/libc/upstream-openbsd/lib/libc/stdio/findfp.c b/libc/stdio/findfp.c similarity index 89% rename from libc/upstream-openbsd/lib/libc/stdio/findfp.c rename to libc/stdio/findfp.c index 3594369bf..35d028e14 100644 --- a/libc/upstream-openbsd/lib/libc/stdio/findfp.c +++ b/libc/stdio/findfp.c @@ -39,7 +39,10 @@ #include #include "local.h" #include "glue.h" -#include "thread_private.h" +#include "private/thread_private.h" + +#define ALIGNBYTES (sizeof(uintptr_t) - 1) +#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES) int __sdidinit; @@ -47,9 +50,7 @@ int __sdidinit; #define std(flags, file) \ {0,0,0,flags,file,{0},0,__sF+file,__sclose,__sread,__sseek,__swrite, \ - {(unsigned char *)(__sFext+file), 0}} -/* p r w flags file _bf z cookie close read seek write - ext */ + {(unsigned char *)(__sFext+file), 0},NULL,0,{0},{0},{0},0,0} /* the usual - (stdin + stdout + stderr) */ static FILE usual[FOPEN_MAX - 3]; @@ -162,17 +163,26 @@ void __sinit(void) { _THREAD_PRIVATE_MUTEX(__sinit_mutex); - int i; _THREAD_PRIVATE_MUTEX_LOCK(__sinit_mutex); - if (__sdidinit) - goto out; /* bail out if caller lost the race */ - for (i = 0; i < FOPEN_MAX - 3; i++) { + if (__sdidinit) { + /* bail out if caller lost the race */ + _THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex); + return; + } + + /* Initialize stdin/stdout/stderr (for the recursive mutex). http://b/18208568. */ + for (size_t i = 0; i < 3; ++i) { + _FILEEXT_SETUP(__sF+i, __sFext+i); + } + /* Initialize the pre-allocated (but initially unused) streams. */ + for (size_t i = 0; i < FOPEN_MAX - 3; ++i) { _FILEEXT_SETUP(usual+i, usualext+i); } + /* make sure we clean up on exit */ __atexit_register_cleanup(_cleanup); /* conservative */ __sdidinit = 1; -out: + _THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex); } diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp index 6a653b4dd..549792efb 100644 --- a/tests/stdio_test.cpp +++ b/tests/stdio_test.cpp @@ -29,6 +29,23 @@ #include "TemporaryFile.h" +TEST(stdio, flockfile_18208568_stderr) { + // Check that we have a _recursive_ mutex for flockfile. + flockfile(stderr); + feof(stderr); // We don't care about the result, but this needs to take the lock. + funlockfile(stderr); +} + +TEST(stdio, flockfile_18208568_regular) { + // We never had a bug for streams other than stdin/stdout/stderr, but test anyway. + FILE* fp = fopen("/dev/null", "w"); + ASSERT_TRUE(fp != NULL); + flockfile(fp); + feof(fp); + funlockfile(fp); + fclose(fp); +} + TEST(stdio, tmpfile_fileno_fprintf_rewind_fgets) { FILE* fp = tmpfile(); ASSERT_TRUE(fp != NULL); -- 2.11.0