diff options
author | Rich Felker <dalias@aerifal.cx> | 2018-11-02 12:31:19 -0400 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2018-11-02 12:31:19 -0400 |
commit | 4a086030264f5cf423ea76453ef721e2c8e2e093 (patch) | |
tree | 8e09c785e7715b22a42189793c596881dfcfa6cd /src/thread | |
parent | 00bd3b7d3006c5d350959c994fa65358bf65e6a2 (diff) | |
download | musl-4a086030264f5cf423ea76453ef721e2c8e2e093.tar.gz musl-4a086030264f5cf423ea76453ef721e2c8e2e093.tar.xz musl-4a086030264f5cf423ea76453ef721e2c8e2e093.zip |
fix deadlock and buffered data loss race in fclose
fflush(NULL) and __stdio_exit lock individual FILEs while holding the open file list lock to walk the list. since fclose first locked the FILE to be closed, then the ofl lock, it could deadlock with these functions. also, because fclose removed the FILE to be closed from the open file list before flushing and closing it, a concurrent fclose or exit could complete successfully before fclose flushed the FILE it was closing, resulting in data loss. reorder the body of fclose to first flush and close the file, then remove it from the open file list only after unlocking it. this creates a window where consumers of the open file list can see dead FILE objects, but in the absence of undefined behavior on the part of the application, such objects will be in an inactive-buffer state and processing them will have no side effects. __unlist_locked_file is also moved so that it's performed only for non-permanent files. this change is not necessary, but preserves consistency (and thereby provides safety/hardening) in the case where an application uses one of the standard streams after closing it while holding an explicit lock on it. such usage is of course undefined behavior.
Diffstat (limited to 'src/thread')
0 files changed, 0 insertions, 0 deletions