gcc-plugins: structleak: Generalize to all variable types
authorKees Cook <keescook@chromium.org>
Wed, 23 Jan 2019 23:19:29 +0000 (15:19 -0800)
committerKees Cook <keescook@chromium.org>
Mon, 4 Mar 2019 17:29:41 +0000 (09:29 -0800)
commit81a56f6dcd20325607d6008f4bb560c96f4c821a
treec41d189a7cc44326833ecd9fddc98cb063ab66e0
parent49a57857aeea06ca831043acbb0fa5e0f50602fd
gcc-plugins: structleak: Generalize to all variable types

This adjusts structleak to also work with non-struct types when they
are passed by reference, since those variables may leak just like
anything else. This is exposed via an improved set of Kconfig options.
(This does mean structleak is slightly misnamed now.)

Building with CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL should give the
kernel complete initialization coverage of all stack variables passed
by reference, including padding (see lib/test_stackinit.c).

Using CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE to count added initializations
under defconfig:

..._BYREF:      5945 added initializations
..._BYREF_ALL: 16606 added initializations

There is virtually no change to text+data size (both have less than 0.05%
growth):

   text    data     bss     dec     hex filename
19502103        5051456 1917000 26470559        193e89f vmlinux.stock
19513412        5051456 1908808 26473676        193f4cc vmlinux.byref
19516974        5047360 1900616 26464950        193d2b6 vmlinux.byref_all

The measured performance difference is in the noise for hackbench and
kernel build benchmarks:

Stock:

5x hackbench -g 20 -l 1000
Mean:   10.649s
Std Dev: 0.339

5x kernel build (4-way parallel)
Mean:  261.98s
Std Dev: 1.53

CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF:

5x hackbench -g 20 -l 1000
Mean:   10.540s
Std Dev: 0.233

5x kernel build (4-way parallel)
Mean:  260.52s
Std Dev: 1.31

CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL:

5x hackbench -g 20 -l 1000
Mean:   10.320
Std Dev: 0.413

5x kernel build (4-way parallel)
Mean:  260.10
Std Dev: 0.86

This does not yet solve missing padding initialization for structures
on the stack that are never passed by reference (which should be a tiny
minority). Hopefully this will be more easily addressed by upstream
compiler fixes after clarifying the C11 padding initialization
specification.

Signed-off-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
scripts/Makefile.gcc-plugins
scripts/gcc-plugins/Kconfig
scripts/gcc-plugins/structleak_plugin.c