llvm-project/llvm
Fangrui Song a0c0389ffb [SimplifyLibcalls] Don't replace locked IO (fgetc/fgets/fputc/fputs/fread/fwrite) with unlocked IO (*_unlocked)
This essentially reverts some of the SimplifyLibcalls part changes of D45736 [SimplifyLibcalls] Replace locked IO with unlocked IO.

C11 7.21.5.2 The fflush function

> If stream is a null pointer, the fflush function performs this flushing action on all streams for which the behavior is defined above.

i.e. fopen'ed FILE* is inherently captured.

POSIX.1-2017 getc_unlocked, getchar_unlocked, putc_unlocked, putchar_unlocked - stdio with explicit client locking

> These functions can safely be used in a multi-threaded program if and only if they are called while the invoking thread owns the ( FILE *) object, as is the case after a successful call to the flockfile() or ftrylockfile() functions.

After a thread fopen'ed a FILE*, when it is calling foobar() which is now replaced by foobar_unlocked(),
if another thread is concurrently calling fflush(0), the behavior is undefined.

C11 7.22.4.4 The exit function

> Next, all open streams with unwritten buffered data are flushed, all open streams are closed, and all files created by the tmpfile function are removed.

The replacement is only feasible if the program is single threaded, or exit or fflush(0) is never called.
See also http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20180528/556615.html
for how the replacement makes libc interceptors difficult to implement.

dalias: in a worst case, it's unbounded data corruption because of concurrent access to pointers
without synchronization.  f->wpos or rpos could get outside of the buffer, thread A could do
f->wpos += j after knowing j is in bounds, while thread B also changes it concurrently.

This can produce exploitable conditions depending on libc internals.

Revert the SimplifyLibcalls part change because the cons obviously
overweigh the pros.  Even when the replacement is feasible, the benefit
is indemonstrable, more so in an application instead of an artificial
glibc benchmark.  Theoretically the replacement could be beneficial when
calling getc_unlocked/putc_unlocked in a loop, but then it is better
using a blocked IO operation and the user is likely aware of that.

The function attribute inference is still useful and thus kept.

Reviewed By: xbolva00

Differential Revision: https://reviews.llvm.org/D75933
2020-03-10 11:11:58 -07:00
..
benchmarks
bindings [LLVM-C] Add bindings for addCoroutinePassesToExtensionPoints 2020-02-24 20:15:51 +01:00
cmake [clang][cmake] Include generated rst files in html built by docs-clang-html target 2020-03-05 21:30:37 -08:00
docs Fix internal links in Kaleidoscope tutorial 2020-03-09 15:07:44 -06:00
examples [ORC][examples] Fix ThinLtoJIT example after changes in 85fb997659. 2020-02-20 11:15:08 -08:00
include [SimplifyLibcalls] Don't replace locked IO (fgetc/fgets/fputc/fputs/fread/fwrite) with unlocked IO (*_unlocked) 2020-03-10 11:11:58 -07:00
lib [SimplifyLibcalls] Don't replace locked IO (fgetc/fgets/fputc/fputs/fread/fwrite) with unlocked IO (*_unlocked) 2020-03-10 11:11:58 -07:00
projects
resources
runtimes [runtimes] Add umbrella targets for runtimes 2020-02-12 09:46:14 -08:00
test [SimplifyLibcalls] Don't replace locked IO (fgetc/fgets/fputc/fputs/fread/fwrite) with unlocked IO (*_unlocked) 2020-03-10 11:11:58 -07:00
tools [NFC][llvm-dwarfdump] Always use 'const Twine &' 2020-03-10 12:58:59 +01:00
unittests Fixed [AssumeBundles] Move to IR so it can be used by Analysis 2020-03-10 18:02:39 +01:00
utils [gn build] Port a4cde9ad7b 2020-03-10 17:04:42 +00:00
.clang-format
.clang-tidy
.gitattributes
.gitignore
CMakeLists.txt Revert abb00753 "build: reduce CMake handling for zlib" (PR44780) 2020-03-03 11:03:09 +01:00
CODE_OWNERS.TXT Remove myself from CODE_OWNERS. 2020-02-25 11:59:29 +00:00
CREDITS.TXT
LICENSE.TXT
LLVMBuild.txt
README.txt
RELEASE_TESTERS.TXT
configure
llvm.spec.in

README.txt

The LLVM Compiler Infrastructure
================================

This directory and its subdirectories contain source code for LLVM,
a toolkit for the construction of highly optimized compilers,
optimizers, and runtime environments.

LLVM is open source software. You may freely distribute it under the terms of
the license agreement found in LICENSE.txt.

Please see the documentation provided in docs/ for further
assistance with LLVM, and in particular docs/GettingStarted.rst for getting
started with LLVM and docs/README.txt for an overview of LLVM's
documentation setup.

If you are writing a package for LLVM, see docs/Packaging.rst for our
suggestions.