On 8/28/20 1:27 PM, Daniel Borkmann wrote:
On 8/28/20 12:01 AM, Alexei Starovoitov wrote:
From: Alexei Starovoitov <ast@xxxxxxxxxx>
'static' and 'static noinline' function attributes make no guarantees
that
gcc/clang won't optimize them. The compiler may decide to inline 'static'
function and in such case ALLOW_ERROR_INJECT becomes meaningless. The
compiler
could have inlined __add_to_page_cache_locked() in one callsite and
didn't
inline in another. In such case injecting errors into it would cause
unpredictable behavior. It's worse with 'static noinline' which won't be
inlined, but it still can be optimized. Like the compiler may decide
to remove
one argument or constant propagate the value depending on the callsite.
To avoid such issues make sure that these functions are global noinline.
Back in the days when adding 6bf37e5aa90f ("crypto: crypto_memneq - add
equality
testing of memory regions w/o timing leaks") we added noinline, but also an
explicit EXPORT_SYMBOL() to prevent this from being optimized away; I
wonder
whether ALLOW_ERROR_INJECT() should have something implicit here too to
prevent
from optimization .. otoh we probably don't want to expose every
ALLOW_ERROR_INJECT()
function also to modules generically...
I don't quite follow the concern.
EXPORT_SYMBOL() only takes the address of the function.
Just like ALLOW_ERROR_INJECT() also takes the address.
Taking the address doesn't prevent optimizations.
The compiler is free to inline the function, but it can keep an
extra function body with the address pointing there.
Also ALLOW_ERROR_INJECT() doesn't make the symbol available to modules.