Re: [PATCH 20/23] gcc-plugins: always build plugins with C++
On Sat, 17 Feb 2018 03:38:48 +0900 Masahiro Yamadawrote: > If the target compiler is GCC 4.8 or newer, plugins are compiled with > HOSTCXX. Otherwise, gcc-plugin.sh will select HOSTCC or HOSTCXX. > > To simpily things, let's decide GCC 4.8 is the requirement for GCC > pulgins. With this, plugins are always built with HOSTCXX. This is a > feature of advanced users, so this requirement whould not be not a big > issue. I disagree with such a decision. I think the gcc plugins should compile with older version because the kernel can be compiled with them too. The distros use these older versions as well and I can very well imagine that new plugins will extend these with backported features such as my sancov plugin. -- Emese
Re: [PATCH 20/23] gcc-plugins: always build plugins with C++
On Sat, 17 Feb 2018 03:38:48 +0900 Masahiro Yamada wrote: > If the target compiler is GCC 4.8 or newer, plugins are compiled with > HOSTCXX. Otherwise, gcc-plugin.sh will select HOSTCC or HOSTCXX. > > To simpily things, let's decide GCC 4.8 is the requirement for GCC > pulgins. With this, plugins are always built with HOSTCXX. This is a > feature of advanced users, so this requirement whould not be not a big > issue. I disagree with such a decision. I think the gcc plugins should compile with older version because the kernel can be compiled with them too. The distros use these older versions as well and I can very well imagine that new plugins will extend these with backported features such as my sancov plugin. -- Emese
Re: [PATCH v4 0/4] Introduce the initify gcc plugin
On Wed, 15 Feb 2017 11:27:06 -0800 Kees Cook <keesc...@chromium.org> wrote: > On Tue, Feb 14, 2017 at 4:23 PM, Emese Revfy <re.em...@gmail.com> wrote: > > On Thu, 12 Jan 2017 15:40:41 -0800 > > Kees Cook <keesc...@chromium.org> wrote: > > > >> WARNING: drivers/clk/bcm/built-in.o(.text+0xec2): Section mismatch in > >> reference from the function clk_gate() to the variable > >> .init.rodata.str:__func__.29708 > >> The function clk_gate() references > >> the variable __initconst __func__.29708. > >> This is often because clk_gate lacks a __initconst > >> annotation or the annotation of __func__.29708 is wrong. > > > > Thanks for the report, it will be fixed in the next grsec patch. > > Very cool, thanks! What did the problem turn out to be? You can find it here: https://github.com/ephox-gcc-plugins/initify/commit/73e857aa47bde7cc78ed865a008d1519893c0f54 -- Emese
Re: [PATCH v4 0/4] Introduce the initify gcc plugin
On Wed, 15 Feb 2017 11:27:06 -0800 Kees Cook wrote: > On Tue, Feb 14, 2017 at 4:23 PM, Emese Revfy wrote: > > On Thu, 12 Jan 2017 15:40:41 -0800 > > Kees Cook wrote: > > > >> WARNING: drivers/clk/bcm/built-in.o(.text+0xec2): Section mismatch in > >> reference from the function clk_gate() to the variable > >> .init.rodata.str:__func__.29708 > >> The function clk_gate() references > >> the variable __initconst __func__.29708. > >> This is often because clk_gate lacks a __initconst > >> annotation or the annotation of __func__.29708 is wrong. > > > > Thanks for the report, it will be fixed in the next grsec patch. > > Very cool, thanks! What did the problem turn out to be? You can find it here: https://github.com/ephox-gcc-plugins/initify/commit/73e857aa47bde7cc78ed865a008d1519893c0f54 -- Emese
Re: [PATCH v4 0/4] Introduce the initify gcc plugin
On Thu, 12 Jan 2017 15:40:41 -0800 Kees Cookwrote: > WARNING: drivers/clk/bcm/built-in.o(.text+0xec2): Section mismatch in > reference from the function clk_gate() to the variable > .init.rodata.str:__func__.29708 > The function clk_gate() references > the variable __initconst __func__.29708. > This is often because clk_gate lacks a __initconst > annotation or the annotation of __func__.29708 is wrong. Thanks for the report, it will be fixed in the next grsec patch. -- Emese
Re: [PATCH v4 0/4] Introduce the initify gcc plugin
On Thu, 12 Jan 2017 15:40:41 -0800 Kees Cook wrote: > WARNING: drivers/clk/bcm/built-in.o(.text+0xec2): Section mismatch in > reference from the function clk_gate() to the variable > .init.rodata.str:__func__.29708 > The function clk_gate() references > the variable __initconst __func__.29708. > This is often because clk_gate lacks a __initconst > annotation or the annotation of __func__.29708 is wrong. Thanks for the report, it will be fixed in the next grsec patch. -- Emese
Re: [PATCH v4 0/4] Introduce the initify gcc plugin
On Thu, 12 Jan 2017 15:40:41 -0800 Kees Cookwrote: > WARNING: drivers/clk/bcm/built-in.o(.text+0xec2): Section mismatch in > reference from the function clk_gate() to the variable > .init.rodata.str:__func__.29708 > The function clk_gate() references > the variable __initconst __func__.29708. > This is often because clk_gate lacks a __initconst > annotation or the annotation of __func__.29708 is wrong. > > I used my initify v5 development tree, with the following patch, with > "make allyesconfig": > > http://git.kernel.org/cgit/linux/kernel/git/kees/linux.git/log/?h=for-next/gcc-plugin/initify Hi, I can't reproduce this mismatch with allyesconfig. Could you please send me your .config? -- Emese
Re: [PATCH v4 0/4] Introduce the initify gcc plugin
On Thu, 12 Jan 2017 15:40:41 -0800 Kees Cook wrote: > WARNING: drivers/clk/bcm/built-in.o(.text+0xec2): Section mismatch in > reference from the function clk_gate() to the variable > .init.rodata.str:__func__.29708 > The function clk_gate() references > the variable __initconst __func__.29708. > This is often because clk_gate lacks a __initconst > annotation or the annotation of __func__.29708 is wrong. > > I used my initify v5 development tree, with the following patch, with > "make allyesconfig": > > http://git.kernel.org/cgit/linux/kernel/git/kees/linux.git/log/?h=for-next/gcc-plugin/initify Hi, I can't reproduce this mismatch with allyesconfig. Could you please send me your .config? -- Emese
Re: [PATCH v4 0/4] Introduce the initify gcc plugin
On Tue, 10 Jan 2017 17:09:31 -0800 Kees Cookwrote: > WARNING: vmlinux.o(.text+0x1087e7): Section mismatch in reference from > the function rebind_subsystems() to the variable > .init.rodata.str:__func__.4400 > The function rebind_subsystems() references > the variable __initconst __func__.4400. > This is often because rebind_subsystems lacks a __initconst > annotation or the annotation of __func__.4400 is wrong. Thanks for the report, you can find the fix here: https://github.com/ephox-gcc-plugins/initify/commit/25f34834e3373e067133bc5d39d42c50a3592d56 -- Emese
Re: [PATCH v4 0/4] Introduce the initify gcc plugin
On Tue, 10 Jan 2017 17:09:31 -0800 Kees Cook wrote: > WARNING: vmlinux.o(.text+0x1087e7): Section mismatch in reference from > the function rebind_subsystems() to the variable > .init.rodata.str:__func__.4400 > The function rebind_subsystems() references > the variable __initconst __func__.4400. > This is often because rebind_subsystems lacks a __initconst > annotation or the annotation of __func__.4400 is wrong. Thanks for the report, you can find the fix here: https://github.com/ephox-gcc-plugins/initify/commit/25f34834e3373e067133bc5d39d42c50a3592d56 -- Emese
Re: [PATCH v4 0/4] Introduce the initify gcc plugin
On Tue, 3 Jan 2017 16:23:03 -0800 Kees Cook <keesc...@chromium.org> wrote: > On Mon, Dec 19, 2016 at 3:10 AM, Emese Revfy <re.em...@gmail.com> wrote: > > On Fri, 16 Dec 2016 14:19:10 -0800 > > Kees Cook <keesc...@chromium.org> wrote: > > > >> FWIW, it still seems to me that these aren't false positives: > >> > >> WARNING: vmlinux.o(.text.unlikely+0x1b1): Section mismatch in > >> reference from the function uncore_pci_exit.part.22() to the function > >> .init.text:uncore_free_pcibus_map() > >> The function uncore_pci_exit.part.22() references > >> the function __init uncore_free_pcibus_map(). > >> This is often because uncore_pci_exit.part.22 lacks a __init > >> annotation or the annotation of uncore_free_pcibus_map is wrong. Thanks for the report, you can find the fix here: https://github.com/ephox-gcc-plugins/initify/commit/5d93a54badd9751b79ef67ce8a8b4081fea37547 -- Emese
Re: [PATCH v4 0/4] Introduce the initify gcc plugin
On Tue, 3 Jan 2017 16:23:03 -0800 Kees Cook wrote: > On Mon, Dec 19, 2016 at 3:10 AM, Emese Revfy wrote: > > On Fri, 16 Dec 2016 14:19:10 -0800 > > Kees Cook wrote: > > > >> FWIW, it still seems to me that these aren't false positives: > >> > >> WARNING: vmlinux.o(.text.unlikely+0x1b1): Section mismatch in > >> reference from the function uncore_pci_exit.part.22() to the function > >> .init.text:uncore_free_pcibus_map() > >> The function uncore_pci_exit.part.22() references > >> the function __init uncore_free_pcibus_map(). > >> This is often because uncore_pci_exit.part.22 lacks a __init > >> annotation or the annotation of uncore_free_pcibus_map is wrong. Thanks for the report, you can find the fix here: https://github.com/ephox-gcc-plugins/initify/commit/5d93a54badd9751b79ef67ce8a8b4081fea37547 -- Emese
Re: [PATCH v4 0/4] Introduce the initify gcc plugin
On Fri, 16 Dec 2016 14:19:10 -0800 Kees Cookwrote: > FWIW, it still seems to me that these aren't false positives: > > WARNING: vmlinux.o(.text.unlikely+0x1b1): Section mismatch in > reference from the function uncore_pci_exit.part.22() to the function > .init.text:uncore_free_pcibus_map() > The function uncore_pci_exit.part.22() references > the function __init uncore_free_pcibus_map(). > This is often because uncore_pci_exit.part.22 lacks a __init > annotation or the annotation of uncore_free_pcibus_map is wrong. Hi, I can't reproduce this section mismatch. Could you please send me your .config? Which gcc version did you use? I used this tree: git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git initify-v4 Thanks -- Emese
Re: [PATCH v4 0/4] Introduce the initify gcc plugin
On Fri, 16 Dec 2016 14:19:10 -0800 Kees Cook wrote: > FWIW, it still seems to me that these aren't false positives: > > WARNING: vmlinux.o(.text.unlikely+0x1b1): Section mismatch in > reference from the function uncore_pci_exit.part.22() to the function > .init.text:uncore_free_pcibus_map() > The function uncore_pci_exit.part.22() references > the function __init uncore_free_pcibus_map(). > This is often because uncore_pci_exit.part.22 lacks a __init > annotation or the annotation of uncore_free_pcibus_map is wrong. Hi, I can't reproduce this section mismatch. Could you please send me your .config? Which gcc version did you use? I used this tree: git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git initify-v4 Thanks -- Emese
Re: [PATCH] gcc-plugin: include memmodel.h and tree_vrp.h for gcc-7
On Fri, 16 Dec 2016 10:00:22 +0100 Arnd Bergmannwrote: > Cc: sta...@vger.kernel.org > Suggested-by: Kugan > Signed-off-by: Arnd Bergmann > --- > scripts/gcc-plugins/gcc-common.h | 6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/scripts/gcc-plugins/gcc-common.h > b/scripts/gcc-plugins/gcc-common.h > index 950fd2e64bb7..cb4a9518b58a 100644 > --- a/scripts/gcc-plugins/gcc-common.h > +++ b/scripts/gcc-plugins/gcc-common.h > @@ -18,6 +18,9 @@ > > #include "tree-inline.h" > #include "version.h" > +#if BUILDING_GCC_VERSION >= 7000 > +#include "memmodel.h" > +#endif > #include "rtl.h" > #include "tm_p.h" > #include "flags.h" > @@ -66,6 +69,9 @@ > #include "tree-flow.h" > #else > #include "tree-cfgcleanup.h" > +#if BUILDING_GCC_VERSION >= 7000 > +#include "tree-vrp.h" > +#endif > #include "tree-ssa-operands.h" > #include "tree-into-ssa.h" > #endif Hi, Could you please use the upstream gcc-common.h? You can find it here: https://www.grsecurity.net/~paxguy1/gcc-common.h Thanks -- Emese
Re: [PATCH] gcc-plugin: include memmodel.h and tree_vrp.h for gcc-7
On Fri, 16 Dec 2016 10:00:22 +0100 Arnd Bergmann wrote: > Cc: sta...@vger.kernel.org > Suggested-by: Kugan > Signed-off-by: Arnd Bergmann > --- > scripts/gcc-plugins/gcc-common.h | 6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/scripts/gcc-plugins/gcc-common.h > b/scripts/gcc-plugins/gcc-common.h > index 950fd2e64bb7..cb4a9518b58a 100644 > --- a/scripts/gcc-plugins/gcc-common.h > +++ b/scripts/gcc-plugins/gcc-common.h > @@ -18,6 +18,9 @@ > > #include "tree-inline.h" > #include "version.h" > +#if BUILDING_GCC_VERSION >= 7000 > +#include "memmodel.h" > +#endif > #include "rtl.h" > #include "tm_p.h" > #include "flags.h" > @@ -66,6 +69,9 @@ > #include "tree-flow.h" > #else > #include "tree-cfgcleanup.h" > +#if BUILDING_GCC_VERSION >= 7000 > +#include "tree-vrp.h" > +#endif > #include "tree-ssa-operands.h" > #include "tree-into-ssa.h" > #endif Hi, Could you please use the upstream gcc-common.h? You can find it here: https://www.grsecurity.net/~paxguy1/gcc-common.h Thanks -- Emese
Re: enabling COMPILE_TEST support for GCC plugins in v4.11
On Fri, 9 Dec 2016 11:12:18 -0800 Kees Cookwrote: > On Fri, Dec 9, 2016 at 2:40 AM, Arnd Bergmann wrote: > > On Thursday, December 8, 2016 11:00:42 AM CET Kees Cook wrote: > > > >> If you have a moment, applying 215e2aa6c024[1] and reverting > >> a519167e753e for an allyesconfig/allmodconfig build should let you > >> know if things are working correctly with headers installed. If anyone > >> sees any problems, please let me know and I can queue up fixes. > > > > Using gcc-4.9.3 or gcc-5.3.1 for an ARM allmodconfig build, I get tons of > > errors such as this one: > > > > /git/arm-soc/init/initramfs.c: In function 'error': > > /git/arm-soc/init/initramfs.c:50:1: error: unrecognizable insn: > > } > > ^ > > (insn 26 25 27 5 (set (reg:SI 111 [ local_entropy.243 ]) > > (rotatert:SI (reg:SI 116 [ local_entropy.243 ]) > > (const_int -30 [0xffe2]))) -1 > > (nil)) > > *** WARNING *** there are active plugins, do not report this as a bug > > unless you can reproduce it without enabling any plugins. > > Event| Plugins > > PLUGIN_ATTRIBUTES| latent_entropy_plugin > > PLUGIN_START_UNIT| latent_entropy_plugin > > /git/arm-soc/init/initramfs.c:50:1: internal compiler error: in > > extract_insn, at recog.c:2202 > > /git/arm-soc/arch/arm/vfp/vfpmodule.c: In function 'vfp_init': > > /git/arm-soc/arch/arm/vfp/vfpmodule.c:824:1: error: unrecognizable insn: > > } > > ^ > > (insn 138 137 139 17 (set (reg:SI 165 [ local_entropy.93 ]) > > (rotatert:SI (reg:SI 150 [ local_entropy.93 ]) > > (const_int -9 [0xfff7]))) -1 > > (nil)) > > *** WARNING *** there are active plugins, do not report this as a bug > > unless you can reproduce it without enabling any plugins. > > Well that's exciting! :P Hi, You can find the fix here: https://github.com/ephox-gcc-plugins/latent_entropy/commit/c91275a1bfcebbcfc0ca1af03396e06039f04db8 -- Emese
Re: enabling COMPILE_TEST support for GCC plugins in v4.11
On Fri, 9 Dec 2016 11:12:18 -0800 Kees Cook wrote: > On Fri, Dec 9, 2016 at 2:40 AM, Arnd Bergmann wrote: > > On Thursday, December 8, 2016 11:00:42 AM CET Kees Cook wrote: > > > >> If you have a moment, applying 215e2aa6c024[1] and reverting > >> a519167e753e for an allyesconfig/allmodconfig build should let you > >> know if things are working correctly with headers installed. If anyone > >> sees any problems, please let me know and I can queue up fixes. > > > > Using gcc-4.9.3 or gcc-5.3.1 for an ARM allmodconfig build, I get tons of > > errors such as this one: > > > > /git/arm-soc/init/initramfs.c: In function 'error': > > /git/arm-soc/init/initramfs.c:50:1: error: unrecognizable insn: > > } > > ^ > > (insn 26 25 27 5 (set (reg:SI 111 [ local_entropy.243 ]) > > (rotatert:SI (reg:SI 116 [ local_entropy.243 ]) > > (const_int -30 [0xffe2]))) -1 > > (nil)) > > *** WARNING *** there are active plugins, do not report this as a bug > > unless you can reproduce it without enabling any plugins. > > Event| Plugins > > PLUGIN_ATTRIBUTES| latent_entropy_plugin > > PLUGIN_START_UNIT| latent_entropy_plugin > > /git/arm-soc/init/initramfs.c:50:1: internal compiler error: in > > extract_insn, at recog.c:2202 > > /git/arm-soc/arch/arm/vfp/vfpmodule.c: In function 'vfp_init': > > /git/arm-soc/arch/arm/vfp/vfpmodule.c:824:1: error: unrecognizable insn: > > } > > ^ > > (insn 138 137 139 17 (set (reg:SI 165 [ local_entropy.93 ]) > > (rotatert:SI (reg:SI 150 [ local_entropy.93 ]) > > (const_int -9 [0xfff7]))) -1 > > (nil)) > > *** WARNING *** there are active plugins, do not report this as a bug > > unless you can reproduce it without enabling any plugins. > > Well that's exciting! :P Hi, You can find the fix here: https://github.com/ephox-gcc-plugins/latent_entropy/commit/c91275a1bfcebbcfc0ca1af03396e06039f04db8 -- Emese
Re: [PATCH 3/3] powerpc: enable support for GCC plugins
On Tue, 6 Dec 2016 17:28:00 +1100 Andrew Donnellanwrote: > + # Various gccs between 4.5 and 5.1 have bugs on powerpc due to missing > + # header files. gcc <= 4.6 doesn't work at all, gccs from 4.8 to 5.1 > have > + # issues with 64-bit targets. > + ifeq ($(ARCH),powerpc) > +ifeq ($(call cc-ifversion, -le, 0501, y), y) > + @echo "Cannot use CONFIG_GCC_PLUGINS: plugin support on gcc <= 5.1 is > buggy on powerpc, please upgrade to gcc 5.2 or newer" >&2 && exit 1 > +endif > + endif Hi, What are these missing headers? Because if they aren't necessary then they can be removed from gcc-common.h. There were missing headers on arm/arm64 and these archs are supported. I think this version check is unnecessary because gcc-plugin.sh also checks the missing headers. What is the problem on gcc-4.5/gcc-4.6? -- Emese
Re: [PATCH 3/3] powerpc: enable support for GCC plugins
On Tue, 6 Dec 2016 17:28:00 +1100 Andrew Donnellan wrote: > + # Various gccs between 4.5 and 5.1 have bugs on powerpc due to missing > + # header files. gcc <= 4.6 doesn't work at all, gccs from 4.8 to 5.1 > have > + # issues with 64-bit targets. > + ifeq ($(ARCH),powerpc) > +ifeq ($(call cc-ifversion, -le, 0501, y), y) > + @echo "Cannot use CONFIG_GCC_PLUGINS: plugin support on gcc <= 5.1 is > buggy on powerpc, please upgrade to gcc 5.2 or newer" >&2 && exit 1 > +endif > + endif Hi, What are these missing headers? Because if they aren't necessary then they can be removed from gcc-common.h. There were missing headers on arm/arm64 and these archs are supported. I think this version check is unnecessary because gcc-plugin.sh also checks the missing headers. What is the problem on gcc-4.5/gcc-4.6? -- Emese
Re: scripts/gcc-plugins/gcc-common.h:4:22: fatal error: bversion.h: No such file or directory
On Sun, 6 Nov 2016 07:09:57 +0800 kbuild test robotwrote: > Hi Emese, > > FYI, the error/warning still remains. > >++(scripts/gcc-plugin.sh:12): main(): gcc-4.6 -E -x c++ - -o /dev/null > -Iscripts/gcc-plugins -Iplugin/include >scripts/Makefile.gcc-plugins:30: warning: your gcc installation does not > support plugins, perhaps the necessary headers are missing? Hi, You should install the gcc-4.6 plugin headers (gcc-4.6-plugin-dev package on debian if I remember well) for the plugins. -- Emese
Re: scripts/gcc-plugins/gcc-common.h:4:22: fatal error: bversion.h: No such file or directory
On Sun, 6 Nov 2016 07:09:57 +0800 kbuild test robot wrote: > Hi Emese, > > FYI, the error/warning still remains. > >++(scripts/gcc-plugin.sh:12): main(): gcc-4.6 -E -x c++ - -o /dev/null > -Iscripts/gcc-plugins -Iplugin/include >scripts/Makefile.gcc-plugins:30: warning: your gcc installation does not > support plugins, perhaps the necessary headers are missing? Hi, You should install the gcc-4.6 plugin headers (gcc-4.6-plugin-dev package on debian if I remember well) for the plugins. -- Emese
Re: drivers/pci/hotplug/ibmphp_ebda.c:409:1: warning: the frame size of 1108 bytes is larger than 1024 bytes
On Tue, 18 Oct 2016 15:05:39 -0700 Kees Cook <keesc...@chromium.org> wrote: > On Tue, Oct 18, 2016 at 2:36 PM, Emese Revfy <re.em...@gmail.com> wrote: > > On Tue, 18 Oct 2016 13:57:35 -0700 > > Kees Cook <keesc...@chromium.org> wrote: > > > >> This is controlled by CONFIG_FRAME_WARN. I don't think this is a > >> particular problem or should be avoided, but perhaps we can set the > >> default to 2048 (as done on 64BIT) if we're building with the entropy > >> plugin. > > > > This is probably a gcc code generation bug on i386 when a plugin uses too > > many 64 bit variables > > so I think PaX Team's patch will be the best solution. > > Okay, cool. If you're able, please CC me with the fix when it happens. :) This is the plugin side fix: https://github.com/ephox-gcc-plugins/latent_entropy/commit/12776eab89861239d5194a9241a98e48e3b3e8ae The kernel side fix will be released in PaX for linux 4.8. -- Emese
Re: drivers/pci/hotplug/ibmphp_ebda.c:409:1: warning: the frame size of 1108 bytes is larger than 1024 bytes
On Tue, 18 Oct 2016 15:05:39 -0700 Kees Cook wrote: > On Tue, Oct 18, 2016 at 2:36 PM, Emese Revfy wrote: > > On Tue, 18 Oct 2016 13:57:35 -0700 > > Kees Cook wrote: > > > >> This is controlled by CONFIG_FRAME_WARN. I don't think this is a > >> particular problem or should be avoided, but perhaps we can set the > >> default to 2048 (as done on 64BIT) if we're building with the entropy > >> plugin. > > > > This is probably a gcc code generation bug on i386 when a plugin uses too > > many 64 bit variables > > so I think PaX Team's patch will be the best solution. > > Okay, cool. If you're able, please CC me with the fix when it happens. :) This is the plugin side fix: https://github.com/ephox-gcc-plugins/latent_entropy/commit/12776eab89861239d5194a9241a98e48e3b3e8ae The kernel side fix will be released in PaX for linux 4.8. -- Emese
Re: drivers/pci/hotplug/ibmphp_ebda.c:409:1: warning: the frame size of 1108 bytes is larger than 1024 bytes
On Tue, 18 Oct 2016 13:57:35 -0700 Kees Cookwrote: > This is controlled by CONFIG_FRAME_WARN. I don't think this is a > particular problem or should be avoided, but perhaps we can set the > default to 2048 (as done on 64BIT) if we're building with the entropy > plugin. This is probably a gcc code generation bug on i386 when a plugin uses too many 64 bit variables so I think PaX Team's patch will be the best solution. -- Emese
Re: drivers/pci/hotplug/ibmphp_ebda.c:409:1: warning: the frame size of 1108 bytes is larger than 1024 bytes
On Tue, 18 Oct 2016 13:57:35 -0700 Kees Cook wrote: > This is controlled by CONFIG_FRAME_WARN. I don't think this is a > particular problem or should be avoided, but perhaps we can set the > default to 2048 (as done on 64BIT) if we're building with the entropy > plugin. This is probably a gcc code generation bug on i386 when a plugin uses too many 64 bit variables so I think PaX Team's patch will be the best solution. -- Emese
Re: drivers/pci/hotplug/ibmphp_ebda.c:409:1: warning: the frame size of 1108 bytes is larger than 1024 bytes
On Sun, 16 Oct 2016 06:52:16 +0800 kbuild test robotwrote: >drivers/pci/hotplug/ibmphp_ebda.c: In function 'ibmphp_access_ebda': > >> drivers/pci/hotplug/ibmphp_ebda.c:409:1: warning: the frame size of 1108 > >> bytes is larger than 1024 bytes [-Wframe-larger-than=] Hi, Thanks for the report. The problem is that these are large functions (there are a lot of basic blocks) and the entropy plugin instruments all basic blocks. I think the solution is to skip these functions which contain more than n basic blocks. Sorry, I haven't time to fix this bug. PaX Team will fix it in PaX. -- Emese
Re: drivers/pci/hotplug/ibmphp_ebda.c:409:1: warning: the frame size of 1108 bytes is larger than 1024 bytes
On Sun, 16 Oct 2016 06:52:16 +0800 kbuild test robot wrote: >drivers/pci/hotplug/ibmphp_ebda.c: In function 'ibmphp_access_ebda': > >> drivers/pci/hotplug/ibmphp_ebda.c:409:1: warning: the frame size of 1108 > >> bytes is larger than 1024 bytes [-Wframe-larger-than=] Hi, Thanks for the report. The problem is that these are large functions (there are a lot of basic blocks) and the entropy plugin instruments all basic blocks. I think the solution is to skip these functions which contain more than n basic blocks. Sorry, I haven't time to fix this bug. PaX Team will fix it in PaX. -- Emese
[PATCH v3 6/7] Mark a few functions with the printf attribute
Fixed format strings warnings exposed by the printf attribute. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- drivers/acpi/acpica/dbhistry.c | 2 +- drivers/acpi/acpica/dbinput.c | 10 ++--- drivers/acpi/acpica/dbstats.c | 88 +++--- drivers/acpi/acpica/utdebug.c | 2 +- drivers/scsi/esas2r/esas2r_init.c | 2 +- drivers/scsi/esas2r/esas2r_ioctl.c | 2 +- drivers/scsi/esas2r/esas2r_main.c | 4 +- 7 files changed, 55 insertions(+), 55 deletions(-) diff --git a/drivers/acpi/acpica/dbhistry.c b/drivers/acpi/acpica/dbhistry.c index 46bd65d..ec9da48 100644 --- a/drivers/acpi/acpica/dbhistry.c +++ b/drivers/acpi/acpica/dbhistry.c @@ -155,7 +155,7 @@ void acpi_db_display_history(void) for (i = 0; i < acpi_gbl_num_history; i++) { if (acpi_gbl_history_buffer[history_index].command) { - acpi_os_printf("%3ld %s\n", + acpi_os_printf("%3u %s\n", acpi_gbl_history_buffer[history_index]. cmd_num, acpi_gbl_history_buffer[history_index]. diff --git a/drivers/acpi/acpica/dbinput.c b/drivers/acpi/acpica/dbinput.c index 7cd5d2e..a837ce6 100644 --- a/drivers/acpi/acpica/dbinput.c +++ b/drivers/acpi/acpica/dbinput.c @@ -606,7 +606,7 @@ static u32 acpi_db_get_line(char *input_buffer) (acpi_gbl_db_parsed_buf, sizeof(acpi_gbl_db_parsed_buf), input_buffer)) { acpi_os_printf - ("Buffer overflow while parsing input line (max %u characters)\n", + ("Buffer overflow while parsing input line (max %lu characters)\n", sizeof(acpi_gbl_db_parsed_buf)); return (0); } @@ -862,24 +862,24 @@ acpi_db_command_dispatch(char *input_buffer, if (param_count == 0) { acpi_os_printf - ("Current debug level for file output is: %8.8lX\n", + ("Current debug level for file output is: %8.8X\n", acpi_gbl_db_debug_level); acpi_os_printf - ("Current debug level for console output is: %8.8lX\n", + ("Current debug level for console output is: %8.8X\n", acpi_gbl_db_console_debug_level); } else if (param_count == 2) { temp = acpi_gbl_db_console_debug_level; acpi_gbl_db_console_debug_level = strtoul(acpi_gbl_db_args[1], NULL, 16); acpi_os_printf - ("Debug Level for console output was %8.8lX, now %8.8lX\n", + ("Debug Level for console output was %8.8X, now %8.8X\n", temp, acpi_gbl_db_console_debug_level); } else { temp = acpi_gbl_db_debug_level; acpi_gbl_db_debug_level = strtoul(acpi_gbl_db_args[1], NULL, 16); acpi_os_printf - ("Debug Level for file output was %8.8lX, now %8.8lX\n", + ("Debug Level for file output was %8.8X, now %8.8X\n", temp, acpi_gbl_db_debug_level); } break; diff --git a/drivers/acpi/acpica/dbstats.c b/drivers/acpi/acpica/dbstats.c index a414e1f..de70230 100644 --- a/drivers/acpi/acpica/dbstats.c +++ b/drivers/acpi/acpica/dbstats.c @@ -377,17 +377,17 @@ acpi_status acpi_db_display_statistics(char *type_arg) "ACPI_TYPE", "NODES", "OBJECTS"); for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++) { - acpi_os_printf("%16.16s % 10ld% 10ld\n", + acpi_os_printf("%16.16s % 10d% 10d\n", acpi_ut_get_type_name(i), acpi_gbl_node_type_count[i], acpi_gbl_obj_type_count[i]); } - acpi_os_printf("%16.16s % 10ld% 10ld\n", "Misc/Unknown", + acpi_os_printf("%16.16s % 10d% 10d\n", "Misc/Unknown", acpi_gbl_node_type_count_misc, acpi_gbl_obj_type_count_misc); - acpi_os_printf("%16.16s % 10ld% 10ld\n", "TOTALS:", + acpi_os_printf("%16.16s % 10d% 10d\n", "TOTALS:", acpi_gbl_num_nodes, acpi_gbl_num_objects);
[PATCH v3 6/7] Mark a few functions with the printf attribute
Fixed format strings warnings exposed by the printf attribute. Signed-off-by: Emese Revfy --- drivers/acpi/acpica/dbhistry.c | 2 +- drivers/acpi/acpica/dbinput.c | 10 ++--- drivers/acpi/acpica/dbstats.c | 88 +++--- drivers/acpi/acpica/utdebug.c | 2 +- drivers/scsi/esas2r/esas2r_init.c | 2 +- drivers/scsi/esas2r/esas2r_ioctl.c | 2 +- drivers/scsi/esas2r/esas2r_main.c | 4 +- 7 files changed, 55 insertions(+), 55 deletions(-) diff --git a/drivers/acpi/acpica/dbhistry.c b/drivers/acpi/acpica/dbhistry.c index 46bd65d..ec9da48 100644 --- a/drivers/acpi/acpica/dbhistry.c +++ b/drivers/acpi/acpica/dbhistry.c @@ -155,7 +155,7 @@ void acpi_db_display_history(void) for (i = 0; i < acpi_gbl_num_history; i++) { if (acpi_gbl_history_buffer[history_index].command) { - acpi_os_printf("%3ld %s\n", + acpi_os_printf("%3u %s\n", acpi_gbl_history_buffer[history_index]. cmd_num, acpi_gbl_history_buffer[history_index]. diff --git a/drivers/acpi/acpica/dbinput.c b/drivers/acpi/acpica/dbinput.c index 7cd5d2e..a837ce6 100644 --- a/drivers/acpi/acpica/dbinput.c +++ b/drivers/acpi/acpica/dbinput.c @@ -606,7 +606,7 @@ static u32 acpi_db_get_line(char *input_buffer) (acpi_gbl_db_parsed_buf, sizeof(acpi_gbl_db_parsed_buf), input_buffer)) { acpi_os_printf - ("Buffer overflow while parsing input line (max %u characters)\n", + ("Buffer overflow while parsing input line (max %lu characters)\n", sizeof(acpi_gbl_db_parsed_buf)); return (0); } @@ -862,24 +862,24 @@ acpi_db_command_dispatch(char *input_buffer, if (param_count == 0) { acpi_os_printf - ("Current debug level for file output is: %8.8lX\n", + ("Current debug level for file output is: %8.8X\n", acpi_gbl_db_debug_level); acpi_os_printf - ("Current debug level for console output is: %8.8lX\n", + ("Current debug level for console output is: %8.8X\n", acpi_gbl_db_console_debug_level); } else if (param_count == 2) { temp = acpi_gbl_db_console_debug_level; acpi_gbl_db_console_debug_level = strtoul(acpi_gbl_db_args[1], NULL, 16); acpi_os_printf - ("Debug Level for console output was %8.8lX, now %8.8lX\n", + ("Debug Level for console output was %8.8X, now %8.8X\n", temp, acpi_gbl_db_console_debug_level); } else { temp = acpi_gbl_db_debug_level; acpi_gbl_db_debug_level = strtoul(acpi_gbl_db_args[1], NULL, 16); acpi_os_printf - ("Debug Level for file output was %8.8lX, now %8.8lX\n", + ("Debug Level for file output was %8.8X, now %8.8X\n", temp, acpi_gbl_db_debug_level); } break; diff --git a/drivers/acpi/acpica/dbstats.c b/drivers/acpi/acpica/dbstats.c index a414e1f..de70230 100644 --- a/drivers/acpi/acpica/dbstats.c +++ b/drivers/acpi/acpica/dbstats.c @@ -377,17 +377,17 @@ acpi_status acpi_db_display_statistics(char *type_arg) "ACPI_TYPE", "NODES", "OBJECTS"); for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++) { - acpi_os_printf("%16.16s % 10ld% 10ld\n", + acpi_os_printf("%16.16s % 10d% 10d\n", acpi_ut_get_type_name(i), acpi_gbl_node_type_count[i], acpi_gbl_obj_type_count[i]); } - acpi_os_printf("%16.16s % 10ld% 10ld\n", "Misc/Unknown", + acpi_os_printf("%16.16s % 10d% 10d\n", "Misc/Unknown", acpi_gbl_node_type_count_misc, acpi_gbl_obj_type_count_misc); - acpi_os_printf("%16.16s % 10ld% 10ld\n", "TOTALS:", + acpi_os_printf("%16.16s % 10d% 10d\n", "TOTALS:", acpi_gbl_num_nodes, acpi_gbl_num_objects); break; @@ -415,16 +415,16 @@
[PATCH v3 2/7] Split up struct warn_args
Disable the initify plugin on the 6th parameter of __warn() because the va_list type can't be NULL on the tile arch. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- include/asm-generic/bug.h | 7 +-- kernel/panic.c| 32 lib/bug.c | 2 +- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 13a9241..f6ae0d7 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -81,9 +81,12 @@ extern __nocapture(1) void warn_slowpath_null(const char *file, const int line); do { printk(arg); __WARN_TAINT(taint); } while (0) #endif -__nocapture(1, 6) +/* used internally by panic.c */ +struct warn_args; + +__nocapture(1, 0) void __warn(const char *file, int line, void *caller, unsigned taint, - struct pt_regs *regs, const char *fmt, va_list args); + struct pt_regs *regs, struct warn_args *args); #ifndef WARN_ON #define WARN_ON(condition) ({ \ diff --git a/kernel/panic.c b/kernel/panic.c index 993ad20..ca8cea1 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -475,8 +475,13 @@ void oops_exit(void) kmsg_dump(KMSG_DUMP_OOPS); } +struct warn_args { + const char *fmt; + va_list args; +}; + void __warn(const char *file, int line, void *caller, unsigned taint, - struct pt_regs *regs, const char *fmt, va_list args) + struct pt_regs *regs, struct warn_args *args) { disable_trace_on_warning(); @@ -490,8 +495,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint, pr_warn("WARNING: CPU: %d PID: %d at %pS\n", raw_smp_processor_id(), current->pid, caller); - if (fmt) - vprintk(fmt, args); + if (args) + vprintk(args->fmt, args->args); if (panic_on_warn) { /* @@ -520,28 +525,31 @@ void __warn(const char *file, int line, void *caller, unsigned taint, #ifdef WANT_WARN_ON_SLOWPATH void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...) { - va_list args; + struct warn_args args; - va_start(args, fmt); - __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, fmt, args); - va_end(args); + args.fmt = fmt; + va_start(args.args, fmt); + __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, + ); + va_end(args.args); } EXPORT_SYMBOL(warn_slowpath_fmt); void warn_slowpath_fmt_taint(const char *file, int line, unsigned taint, const char *fmt, ...) { - va_list args; + struct warn_args args; - va_start(args, fmt); - __warn(file, line, __builtin_return_address(0), taint, NULL, fmt, args); - va_end(args); + args.fmt = fmt; + va_start(args.args, fmt); + __warn(file, line, __builtin_return_address(0), taint, NULL, ); + va_end(args.args); } EXPORT_SYMBOL(warn_slowpath_fmt_taint); void warn_slowpath_null(const char *file, int line) { - __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL, NULL); + __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL); } EXPORT_SYMBOL(warn_slowpath_null); #endif diff --git a/lib/bug.c b/lib/bug.c index c8bdebb..bc3656e 100644 --- a/lib/bug.c +++ b/lib/bug.c @@ -168,7 +168,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) if (warning) { /* this is a WARN_ON rather than BUG/BUG_ON */ __warn(file, line, (void *)bugaddr, BUG_GET_TAINT(bug), regs, - NULL, NULL); + NULL); return BUG_TRAP_TYPE_WARN; } -- 2.8.1
[PATCH v3 2/7] Split up struct warn_args
Disable the initify plugin on the 6th parameter of __warn() because the va_list type can't be NULL on the tile arch. Signed-off-by: Emese Revfy --- include/asm-generic/bug.h | 7 +-- kernel/panic.c| 32 lib/bug.c | 2 +- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 13a9241..f6ae0d7 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -81,9 +81,12 @@ extern __nocapture(1) void warn_slowpath_null(const char *file, const int line); do { printk(arg); __WARN_TAINT(taint); } while (0) #endif -__nocapture(1, 6) +/* used internally by panic.c */ +struct warn_args; + +__nocapture(1, 0) void __warn(const char *file, int line, void *caller, unsigned taint, - struct pt_regs *regs, const char *fmt, va_list args); + struct pt_regs *regs, struct warn_args *args); #ifndef WARN_ON #define WARN_ON(condition) ({ \ diff --git a/kernel/panic.c b/kernel/panic.c index 993ad20..ca8cea1 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -475,8 +475,13 @@ void oops_exit(void) kmsg_dump(KMSG_DUMP_OOPS); } +struct warn_args { + const char *fmt; + va_list args; +}; + void __warn(const char *file, int line, void *caller, unsigned taint, - struct pt_regs *regs, const char *fmt, va_list args) + struct pt_regs *regs, struct warn_args *args) { disable_trace_on_warning(); @@ -490,8 +495,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint, pr_warn("WARNING: CPU: %d PID: %d at %pS\n", raw_smp_processor_id(), current->pid, caller); - if (fmt) - vprintk(fmt, args); + if (args) + vprintk(args->fmt, args->args); if (panic_on_warn) { /* @@ -520,28 +525,31 @@ void __warn(const char *file, int line, void *caller, unsigned taint, #ifdef WANT_WARN_ON_SLOWPATH void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...) { - va_list args; + struct warn_args args; - va_start(args, fmt); - __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, fmt, args); - va_end(args); + args.fmt = fmt; + va_start(args.args, fmt); + __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, + ); + va_end(args.args); } EXPORT_SYMBOL(warn_slowpath_fmt); void warn_slowpath_fmt_taint(const char *file, int line, unsigned taint, const char *fmt, ...) { - va_list args; + struct warn_args args; - va_start(args, fmt); - __warn(file, line, __builtin_return_address(0), taint, NULL, fmt, args); - va_end(args); + args.fmt = fmt; + va_start(args.args, fmt); + __warn(file, line, __builtin_return_address(0), taint, NULL, ); + va_end(args.args); } EXPORT_SYMBOL(warn_slowpath_fmt_taint); void warn_slowpath_null(const char *file, int line) { - __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL, NULL); + __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL); } EXPORT_SYMBOL(warn_slowpath_null); #endif diff --git a/lib/bug.c b/lib/bug.c index c8bdebb..bc3656e 100644 --- a/lib/bug.c +++ b/lib/bug.c @@ -168,7 +168,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) if (warning) { /* this is a WARN_ON rather than BUG/BUG_ON */ __warn(file, line, (void *)bugaddr, BUG_GET_TAINT(bug), regs, - NULL, NULL); + NULL); return BUG_TRAP_TYPE_WARN; } -- 2.8.1
[PATCH v3 7/7] Mark functions with the __unverified_nocapture attribute
This attribute disables the compile data flow verification of the designated nocapture parameters of the function. Use it only on function parameters that are difficult for the plugin to analyze. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- include/linux/compiler-gcc.h | 1 + include/linux/compiler.h | 4 lib/vsprintf.c | 4 ++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 6697ea3..76797b9 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -207,6 +207,7 @@ */ #ifdef INITIFY_PLUGIN #define __nocapture(...) __attribute__((nocapture(__VA_ARGS__))) +#define __unverified_nocapture(...) __attribute__((unverified_nocapture(__VA_ARGS__))) #endif /* diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 391b48b..f0b4156 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -416,6 +416,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s # define __nocapture(...) #endif +#ifndef __unverified_nocapture +# define __unverified_nocapture(...) +#endif + /* * Tell gcc if a function is cold. The compiler will assume any path * directly leading to the call is unlikely. diff --git a/lib/vsprintf.c b/lib/vsprintf.c index a192761..cb964b5 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -118,7 +118,7 @@ long long simple_strtoll(const char *cp, char **endp, unsigned int base) } EXPORT_SYMBOL(simple_strtoll); -static noinline_for_stack __nocapture(1) +static noinline_for_stack __nocapture(1) __unverified_nocapture(1) int skip_atoi(const char **s) { int i = 0; @@ -1570,7 +1570,7 @@ int kptr_restrict __read_mostly; * function pointers are really function descriptors, which contain a * pointer to the real address. */ -static noinline_for_stack __nocapture(1) +static noinline_for_stack __nocapture(1) __unverified_nocapture(1) char *pointer(const char *fmt, char *buf, char *end, void *ptr, struct printf_spec spec) { -- 2.8.1
[PATCH v3 7/7] Mark functions with the __unverified_nocapture attribute
This attribute disables the compile data flow verification of the designated nocapture parameters of the function. Use it only on function parameters that are difficult for the plugin to analyze. Signed-off-by: Emese Revfy --- include/linux/compiler-gcc.h | 1 + include/linux/compiler.h | 4 lib/vsprintf.c | 4 ++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 6697ea3..76797b9 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -207,6 +207,7 @@ */ #ifdef INITIFY_PLUGIN #define __nocapture(...) __attribute__((nocapture(__VA_ARGS__))) +#define __unverified_nocapture(...) __attribute__((unverified_nocapture(__VA_ARGS__))) #endif /* diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 391b48b..f0b4156 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -416,6 +416,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s # define __nocapture(...) #endif +#ifndef __unverified_nocapture +# define __unverified_nocapture(...) +#endif + /* * Tell gcc if a function is cold. The compiler will assume any path * directly leading to the call is unlikely. diff --git a/lib/vsprintf.c b/lib/vsprintf.c index a192761..cb964b5 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -118,7 +118,7 @@ long long simple_strtoll(const char *cp, char **endp, unsigned int base) } EXPORT_SYMBOL(simple_strtoll); -static noinline_for_stack __nocapture(1) +static noinline_for_stack __nocapture(1) __unverified_nocapture(1) int skip_atoi(const char **s) { int i = 0; @@ -1570,7 +1570,7 @@ int kptr_restrict __read_mostly; * function pointers are really function descriptors, which contain a * pointer to the real address. */ -static noinline_for_stack __nocapture(1) +static noinline_for_stack __nocapture(1) __unverified_nocapture(1) char *pointer(const char *fmt, char *buf, char *end, void *ptr, struct printf_spec spec) { -- 2.8.1
[PATCH v3 6/7] Mark a few functions with the printf attribute
This allows not only compile time format string checking but can also increase the coverage of the initify plugin. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- drivers/scsi/esas2r/esas2r_log.h | 4 ++-- include/acpi/acpiosxf.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/esas2r/esas2r_log.h b/drivers/scsi/esas2r/esas2r_log.h index 7b6397b..75b9d23 100644 --- a/drivers/scsi/esas2r/esas2r_log.h +++ b/drivers/scsi/esas2r/esas2r_log.h @@ -61,8 +61,8 @@ enum { #endif }; -int esas2r_log(const long level, const char *format, ...); -int esas2r_log_dev(const long level, +__printf(2, 3) int esas2r_log(const long level, const char *format, ...); +__printf(3, 4) int esas2r_log_dev(const long level, const struct device *dev, const char *format, ...); diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 562603d..7ee4475 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -337,11 +337,12 @@ acpi_status acpi_os_signal(u32 function, void *info); * Debug print routines */ #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_printf +__printf(1, 2) void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *format, ...); #endif #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_vprintf -void acpi_os_vprintf(const char *format, va_list args); +__printf(1, 0) void acpi_os_vprintf(const char *format, va_list args); #endif #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_redirect_output -- 2.8.1
[PATCH v3 6/7] Mark a few functions with the printf attribute
This allows not only compile time format string checking but can also increase the coverage of the initify plugin. Signed-off-by: Emese Revfy --- drivers/scsi/esas2r/esas2r_log.h | 4 ++-- include/acpi/acpiosxf.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/esas2r/esas2r_log.h b/drivers/scsi/esas2r/esas2r_log.h index 7b6397b..75b9d23 100644 --- a/drivers/scsi/esas2r/esas2r_log.h +++ b/drivers/scsi/esas2r/esas2r_log.h @@ -61,8 +61,8 @@ enum { #endif }; -int esas2r_log(const long level, const char *format, ...); -int esas2r_log_dev(const long level, +__printf(2, 3) int esas2r_log(const long level, const char *format, ...); +__printf(3, 4) int esas2r_log_dev(const long level, const struct device *dev, const char *format, ...); diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 562603d..7ee4475 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -337,11 +337,12 @@ acpi_status acpi_os_signal(u32 function, void *info); * Debug print routines */ #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_printf +__printf(1, 2) void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *format, ...); #endif #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_vprintf -void acpi_os_vprintf(const char *format, va_list args); +__printf(1, 0) void acpi_os_vprintf(const char *format, va_list args); #endif #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_redirect_output -- 2.8.1
[PATCH v3 5/7] Mark functions with the __nocapture attribute
The nocapture gcc attribute can be on functions only. The attribute takes zero or more signed integer constants as parameters that specify the function parameters to initify when the passed arguments are of const char* type. A negative attribute parameter value means that the corresponding function parameter is returned by the function and the passed argument will only be initified if the data flow of the returned value is not captured in the caller. If no values are passed to the attribute then all function parameters are treated as nocapture. If the marked parameter is a vararg then the plugin initifies all vararg arguments. I couldn't test the arm, arm64 and powerpc architectures. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- arch/arm/include/asm/string.h | 10 +++--- arch/arm64/include/asm/string.h | 25 ++--- arch/powerpc/include/asm/string.h | 19 +- arch/x86/include/asm/string_32.h | 25 ++--- arch/x86/include/asm/string_64.h | 20 +-- arch/x86/kernel/hpet.c| 2 +- drivers/acpi/acpica/acutils.h | 2 +- fs/char_dev.c | 2 +- fs/ntfs/debug.h | 6 ++-- fs/ocfs2/cluster/masklog.h| 2 +- include/acpi/acpixf.h | 2 +- include/asm-generic/bug.h | 7 ++-- include/drm/drmP.h| 2 +- include/linux/audit.h | 5 +-- include/linux/fs.h| 8 +++-- include/linux/printk.h| 2 +- include/linux/ratelimit.h | 3 +- include/linux/string.h| 75 --- lib/vsprintf.c| 6 ++-- mm/util.c | 2 +- security/integrity/integrity.h| 2 +- 21 files changed, 119 insertions(+), 108 deletions(-) diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h index cf4f3aa..8f2f2d9 100644 --- a/arch/arm/include/asm/string.h +++ b/arch/arm/include/asm/string.h @@ -7,19 +7,19 @@ */ #define __HAVE_ARCH_STRRCHR -extern char * strrchr(const char * s, int c); +extern char * strrchr(const char * s, int c) __nocapture(-1); #define __HAVE_ARCH_STRCHR -extern char * strchr(const char * s, int c); +extern char * strchr(const char * s, int c) __nocapture(-1); #define __HAVE_ARCH_MEMCPY -extern void * memcpy(void *, const void *, __kernel_size_t); +extern void * memcpy(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMMOVE -extern void * memmove(void *, const void *, __kernel_size_t); +extern void * memmove(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMCHR -extern void * memchr(const void *, int, __kernel_size_t); +extern void * memchr(const void *, int, __kernel_size_t) __nocapture(-1); #define __HAVE_ARCH_MEMSET extern void * memset(void *, int, __kernel_size_t); diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h index 2eb714c..188a102 100644 --- a/arch/arm64/include/asm/string.h +++ b/arch/arm64/include/asm/string.h @@ -17,40 +17,41 @@ #define __ASM_STRING_H #define __HAVE_ARCH_STRRCHR -extern char *strrchr(const char *, int c); +extern char *strrchr(const char *, int c) __nocapture(-1); #define __HAVE_ARCH_STRCHR -extern char *strchr(const char *, int c); +extern char *strchr(const char *, int c) __nocapture(-1); #define __HAVE_ARCH_STRCMP -extern int strcmp(const char *, const char *); +extern int strcmp(const char *, const char *) __nocapture(); #define __HAVE_ARCH_STRNCMP -extern int strncmp(const char *, const char *, __kernel_size_t); +extern int +strncmp(const char *, const char *, __kernel_size_t) __nocapture(1, 2); #define __HAVE_ARCH_STRLEN -extern __kernel_size_t strlen(const char *); +extern __kernel_size_t strlen(const char *) __nocapture(1); #define __HAVE_ARCH_STRNLEN -extern __kernel_size_t strnlen(const char *, __kernel_size_t); +extern __kernel_size_t strnlen(const char *, __kernel_size_t) __nocapture(1); #define __HAVE_ARCH_MEMCPY -extern void *memcpy(void *, const void *, __kernel_size_t); -extern void *__memcpy(void *, const void *, __kernel_size_t); +extern void *memcpy(void *, const void *, __kernel_size_t) __nocapture(2); +extern void *__memcpy(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMMOVE -extern void *memmove(void *, const void *, __kernel_size_t); -extern void *__memmove(void *, const void *, __kernel_size_t); +extern void *memmove(void *, const void *, __kernel_size_t) __nocapture(2); +extern void *__memmove(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMCHR -extern void *memchr(const void *, int, __kernel_size_t); +extern void *memchr(const void *, int, __kernel_size_t) __nocapture(-1); #define __HAVE_ARCH_MEMSET extern void *memset(void *, int, __kernel_size_t); extern void *__memset(void *, int, __kernel_size_t); #define __HAVE_ARCH_MEMCMP -extern int memcmp(const void *, const void *,
[PATCH v3 5/7] Mark functions with the __nocapture attribute
The nocapture gcc attribute can be on functions only. The attribute takes zero or more signed integer constants as parameters that specify the function parameters to initify when the passed arguments are of const char* type. A negative attribute parameter value means that the corresponding function parameter is returned by the function and the passed argument will only be initified if the data flow of the returned value is not captured in the caller. If no values are passed to the attribute then all function parameters are treated as nocapture. If the marked parameter is a vararg then the plugin initifies all vararg arguments. I couldn't test the arm, arm64 and powerpc architectures. Signed-off-by: Emese Revfy --- arch/arm/include/asm/string.h | 10 +++--- arch/arm64/include/asm/string.h | 25 ++--- arch/powerpc/include/asm/string.h | 19 +- arch/x86/include/asm/string_32.h | 25 ++--- arch/x86/include/asm/string_64.h | 20 +-- arch/x86/kernel/hpet.c| 2 +- drivers/acpi/acpica/acutils.h | 2 +- fs/char_dev.c | 2 +- fs/ntfs/debug.h | 6 ++-- fs/ocfs2/cluster/masklog.h| 2 +- include/acpi/acpixf.h | 2 +- include/asm-generic/bug.h | 7 ++-- include/drm/drmP.h| 2 +- include/linux/audit.h | 5 +-- include/linux/fs.h| 8 +++-- include/linux/printk.h| 2 +- include/linux/ratelimit.h | 3 +- include/linux/string.h| 75 --- lib/vsprintf.c| 6 ++-- mm/util.c | 2 +- security/integrity/integrity.h| 2 +- 21 files changed, 119 insertions(+), 108 deletions(-) diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h index cf4f3aa..8f2f2d9 100644 --- a/arch/arm/include/asm/string.h +++ b/arch/arm/include/asm/string.h @@ -7,19 +7,19 @@ */ #define __HAVE_ARCH_STRRCHR -extern char * strrchr(const char * s, int c); +extern char * strrchr(const char * s, int c) __nocapture(-1); #define __HAVE_ARCH_STRCHR -extern char * strchr(const char * s, int c); +extern char * strchr(const char * s, int c) __nocapture(-1); #define __HAVE_ARCH_MEMCPY -extern void * memcpy(void *, const void *, __kernel_size_t); +extern void * memcpy(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMMOVE -extern void * memmove(void *, const void *, __kernel_size_t); +extern void * memmove(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMCHR -extern void * memchr(const void *, int, __kernel_size_t); +extern void * memchr(const void *, int, __kernel_size_t) __nocapture(-1); #define __HAVE_ARCH_MEMSET extern void * memset(void *, int, __kernel_size_t); diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h index 2eb714c..188a102 100644 --- a/arch/arm64/include/asm/string.h +++ b/arch/arm64/include/asm/string.h @@ -17,40 +17,41 @@ #define __ASM_STRING_H #define __HAVE_ARCH_STRRCHR -extern char *strrchr(const char *, int c); +extern char *strrchr(const char *, int c) __nocapture(-1); #define __HAVE_ARCH_STRCHR -extern char *strchr(const char *, int c); +extern char *strchr(const char *, int c) __nocapture(-1); #define __HAVE_ARCH_STRCMP -extern int strcmp(const char *, const char *); +extern int strcmp(const char *, const char *) __nocapture(); #define __HAVE_ARCH_STRNCMP -extern int strncmp(const char *, const char *, __kernel_size_t); +extern int +strncmp(const char *, const char *, __kernel_size_t) __nocapture(1, 2); #define __HAVE_ARCH_STRLEN -extern __kernel_size_t strlen(const char *); +extern __kernel_size_t strlen(const char *) __nocapture(1); #define __HAVE_ARCH_STRNLEN -extern __kernel_size_t strnlen(const char *, __kernel_size_t); +extern __kernel_size_t strnlen(const char *, __kernel_size_t) __nocapture(1); #define __HAVE_ARCH_MEMCPY -extern void *memcpy(void *, const void *, __kernel_size_t); -extern void *__memcpy(void *, const void *, __kernel_size_t); +extern void *memcpy(void *, const void *, __kernel_size_t) __nocapture(2); +extern void *__memcpy(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMMOVE -extern void *memmove(void *, const void *, __kernel_size_t); -extern void *__memmove(void *, const void *, __kernel_size_t); +extern void *memmove(void *, const void *, __kernel_size_t) __nocapture(2); +extern void *__memmove(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMCHR -extern void *memchr(const void *, int, __kernel_size_t); +extern void *memchr(const void *, int, __kernel_size_t) __nocapture(-1); #define __HAVE_ARCH_MEMSET extern void *memset(void *, int, __kernel_size_t); extern void *__memset(void *, int, __kernel_size_t); #define __HAVE_ARCH_MEMCMP -extern int memcmp(const void *, const void *, size_t); +extern int memcmp
[PATCH v3 4/7] Add the initify gcc plugin
The kernel already has a mechanism to free up code and data memory that is only used during kernel or module initialization. This plugin will teach the compiler to find more such code and data that can be freed after initialization. It has two passes. The first one tries to find all functions that can be become __init/__exit. The second one moves string constants (local variables and function string arguments marked by the nocapture attribute) only referenced in __init/__exit functions to the __initconst/__exitconst sections. It reduces memory usage. This plugin can be useful for embedded systems. If a function is called by __init and __exit functions as well then the plugin moves it to the __exit section. This causes false positive section mismatch errors/warnings that I don't know how to handle yet. The instrumentation pass of the latent_entropy plugin must run after the initify plugin to increase coverage. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- arch/Kconfig | 35 + arch/x86/Kconfig |1 + arch/x86/lib/Makefile|4 + include/asm-generic/vmlinux.lds.h|2 + include/linux/compiler-gcc.h | 14 + include/linux/compiler.h |4 + scripts/Makefile.gcc-plugins |9 + scripts/gcc-plugins/gcc-common.h | 41 + scripts/gcc-plugins/initify_plugin.c | 1883 ++ 9 files changed, 1993 insertions(+) create mode 100644 scripts/gcc-plugins/initify_plugin.c diff --git a/arch/Kconfig b/arch/Kconfig index 88673c2..41eb562 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -417,6 +417,41 @@ config GCC_PLUGIN_LATENT_ENTROPY * https://grsecurity.net/ * https://pax.grsecurity.net/ +config GCC_PLUGIN_INITIFY + bool "Free more kernel memory after init" + depends on GCC_PLUGINS + help + The kernel has a mechanism to free up code and data memory that is + only used during kernel or module initialization. Enabling this + feature will teach the compiler to find more such code and data + that can be freed after initialization. + + This plugin is the part of grsecurity/PaX. More information at: + * https://grsecurity.net/ + * https://pax.grsecurity.net/ + +config HAVE_GCC_PLUGIN_INITIFY_INIT_EXIT + bool + depends on GCC_PLUGINS + help + Move functions to the exit section if they are called by __init and + __exit functions too. + +config GCC_PLUGIN_INITIFY_INIT_EXIT + bool + depends on GCC_PLUGIN_INITIFY && HAVE_GCC_PLUGIN_INITIFY_INIT_EXIT + +config GCC_PLUGIN_INITIFY_VERBOSE + bool "Verbose" + depends on GCC_PLUGINS + depends on GCC_PLUGIN_INITIFY + help + Print all initified strings and all functions which should be + __init/__exit. + Note that the candidates identified for __init/__exit markings + depend on the current kernel configuration and thus should be verified + manually before the source code is patched. + config HAVE_CC_STACKPROTECTOR bool help diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c580d8c..921a13c 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -114,6 +114,7 @@ config X86 select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_GCC_PLUGINS + select HAVE_GCC_PLUGIN_INITIFY_INIT_EXIT if GCC_PLUGINS select HAVE_GENERIC_DMA_COHERENTif X86_32 select HAVE_HW_BREAKPOINT select HAVE_IDE diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 34a7413..b98b8fd 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -29,6 +29,10 @@ lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o ifeq ($(CONFIG_X86_32),y) +CFLAGS_strstr_32.o += $(INITIFY_DISABLE_VERIFIY_NOCAPTURE_FUNCTIONS) +CFLAGS_string_32.o += $(INITIFY_DISABLE_VERIFIY_NOCAPTURE_FUNCTIONS) +CFLAGS_memcpy_32.o += $(INITIFY_DISABLE_VERIFIY_NOCAPTURE_FUNCTIONS) + obj-y += atomic64_32.o lib-y += atomic64_cx8_32.o lib-y += checksum_32.o diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 2456397..6e292f9 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -531,6 +531,7 @@ MEM_DISCARD(init.data) \ KERNEL_CTORS() \ MCOUNT_REC()\ + *(.init.rodata.str) \ *(.init.rodata) \ FTRACE_EVENTS() \ TRACE_SYSCALLS()
[PATCH v3 4/7] Add the initify gcc plugin
The kernel already has a mechanism to free up code and data memory that is only used during kernel or module initialization. This plugin will teach the compiler to find more such code and data that can be freed after initialization. It has two passes. The first one tries to find all functions that can be become __init/__exit. The second one moves string constants (local variables and function string arguments marked by the nocapture attribute) only referenced in __init/__exit functions to the __initconst/__exitconst sections. It reduces memory usage. This plugin can be useful for embedded systems. If a function is called by __init and __exit functions as well then the plugin moves it to the __exit section. This causes false positive section mismatch errors/warnings that I don't know how to handle yet. The instrumentation pass of the latent_entropy plugin must run after the initify plugin to increase coverage. Signed-off-by: Emese Revfy --- arch/Kconfig | 35 + arch/x86/Kconfig |1 + arch/x86/lib/Makefile|4 + include/asm-generic/vmlinux.lds.h|2 + include/linux/compiler-gcc.h | 14 + include/linux/compiler.h |4 + scripts/Makefile.gcc-plugins |9 + scripts/gcc-plugins/gcc-common.h | 41 + scripts/gcc-plugins/initify_plugin.c | 1883 ++ 9 files changed, 1993 insertions(+) create mode 100644 scripts/gcc-plugins/initify_plugin.c diff --git a/arch/Kconfig b/arch/Kconfig index 88673c2..41eb562 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -417,6 +417,41 @@ config GCC_PLUGIN_LATENT_ENTROPY * https://grsecurity.net/ * https://pax.grsecurity.net/ +config GCC_PLUGIN_INITIFY + bool "Free more kernel memory after init" + depends on GCC_PLUGINS + help + The kernel has a mechanism to free up code and data memory that is + only used during kernel or module initialization. Enabling this + feature will teach the compiler to find more such code and data + that can be freed after initialization. + + This plugin is the part of grsecurity/PaX. More information at: + * https://grsecurity.net/ + * https://pax.grsecurity.net/ + +config HAVE_GCC_PLUGIN_INITIFY_INIT_EXIT + bool + depends on GCC_PLUGINS + help + Move functions to the exit section if they are called by __init and + __exit functions too. + +config GCC_PLUGIN_INITIFY_INIT_EXIT + bool + depends on GCC_PLUGIN_INITIFY && HAVE_GCC_PLUGIN_INITIFY_INIT_EXIT + +config GCC_PLUGIN_INITIFY_VERBOSE + bool "Verbose" + depends on GCC_PLUGINS + depends on GCC_PLUGIN_INITIFY + help + Print all initified strings and all functions which should be + __init/__exit. + Note that the candidates identified for __init/__exit markings + depend on the current kernel configuration and thus should be verified + manually before the source code is patched. + config HAVE_CC_STACKPROTECTOR bool help diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c580d8c..921a13c 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -114,6 +114,7 @@ config X86 select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_GCC_PLUGINS + select HAVE_GCC_PLUGIN_INITIFY_INIT_EXIT if GCC_PLUGINS select HAVE_GENERIC_DMA_COHERENTif X86_32 select HAVE_HW_BREAKPOINT select HAVE_IDE diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile index 34a7413..b98b8fd 100644 --- a/arch/x86/lib/Makefile +++ b/arch/x86/lib/Makefile @@ -29,6 +29,10 @@ lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o ifeq ($(CONFIG_X86_32),y) +CFLAGS_strstr_32.o += $(INITIFY_DISABLE_VERIFIY_NOCAPTURE_FUNCTIONS) +CFLAGS_string_32.o += $(INITIFY_DISABLE_VERIFIY_NOCAPTURE_FUNCTIONS) +CFLAGS_memcpy_32.o += $(INITIFY_DISABLE_VERIFIY_NOCAPTURE_FUNCTIONS) + obj-y += atomic64_32.o lib-y += atomic64_cx8_32.o lib-y += checksum_32.o diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 2456397..6e292f9 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -531,6 +531,7 @@ MEM_DISCARD(init.data) \ KERNEL_CTORS() \ MCOUNT_REC()\ + *(.init.rodata.str) \ *(.init.rodata) \ FTRACE_EVENTS() \ TRACE_SYSCALLS()\ @@ -558,6 +55
[PATCH v3 3/7] Constify some function parameters
Initify needs const pointer types, the initify plugin caught some __printf arguments that weren't const yet. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- drivers/isdn/hisax/config.c | 16 drivers/isdn/hisax/hisax.h | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index bf04d2a..2d12c6c 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -659,7 +659,7 @@ int jiftime(char *s, long mark) static u_char tmpbuf[HISAX_STATUS_BUFSIZE]; -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, +void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args) { /* if head == NULL the fmt contains the full info */ @@ -669,23 +669,24 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, u_char *p; isdn_ctrl ic; int len; + const u_char*data; if (!cs) { printk(KERN_WARNING "HiSax: No CardStatus for message"); return; } spin_lock_irqsave(>statlock, flags); - p = tmpbuf; if (head) { + p = tmpbuf; p += jiftime(p, jiffies); p += sprintf(p, " %s", head); p += vsprintf(p, fmt, args); *p++ = '\n'; *p = 0; len = p - tmpbuf; - p = tmpbuf; + data = tmpbuf; } else { - p = fmt; + data = fmt; len = strlen(fmt); } if (len > HISAX_STATUS_BUFSIZE) { @@ -699,13 +700,12 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, if (i >= len) i = len; len -= i; - memcpy(cs->status_write, p, i); + memcpy(cs->status_write, data, i); cs->status_write += i; if (cs->status_write > cs->status_end) cs->status_write = cs->status_buf; - p += i; if (len) { - memcpy(cs->status_write, p, len); + memcpy(cs->status_write, data + i, len); cs->status_write += len; } #ifdef KERNELSTACK_DEBUG @@ -729,7 +729,7 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, } } -void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...) +void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...) { va_list args; diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index 6ead6314..338d040 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h @@ -1288,9 +1288,9 @@ int jiftime(char *s, long mark); int HiSax_command(isdn_ctrl *ic); int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb); __printf(3, 4) -void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...); +void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...); __printf(3, 0) -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args); +void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args); void HiSax_reportcard(int cardnr, int sel); int QuickHex(char *txt, u_char *p, int cnt); void LogFrame(struct IsdnCardState *cs, u_char *p, int size); -- 2.8.1
[PATCH v3 3/7] Constify some function parameters
Initify needs const pointer types, the initify plugin caught some __printf arguments that weren't const yet. Signed-off-by: Emese Revfy --- drivers/isdn/hisax/config.c | 16 drivers/isdn/hisax/hisax.h | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index bf04d2a..2d12c6c 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -659,7 +659,7 @@ int jiftime(char *s, long mark) static u_char tmpbuf[HISAX_STATUS_BUFSIZE]; -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, +void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args) { /* if head == NULL the fmt contains the full info */ @@ -669,23 +669,24 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, u_char *p; isdn_ctrl ic; int len; + const u_char*data; if (!cs) { printk(KERN_WARNING "HiSax: No CardStatus for message"); return; } spin_lock_irqsave(>statlock, flags); - p = tmpbuf; if (head) { + p = tmpbuf; p += jiftime(p, jiffies); p += sprintf(p, " %s", head); p += vsprintf(p, fmt, args); *p++ = '\n'; *p = 0; len = p - tmpbuf; - p = tmpbuf; + data = tmpbuf; } else { - p = fmt; + data = fmt; len = strlen(fmt); } if (len > HISAX_STATUS_BUFSIZE) { @@ -699,13 +700,12 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, if (i >= len) i = len; len -= i; - memcpy(cs->status_write, p, i); + memcpy(cs->status_write, data, i); cs->status_write += i; if (cs->status_write > cs->status_end) cs->status_write = cs->status_buf; - p += i; if (len) { - memcpy(cs->status_write, p, len); + memcpy(cs->status_write, data + i, len); cs->status_write += len; } #ifdef KERNELSTACK_DEBUG @@ -729,7 +729,7 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, } } -void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...) +void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...) { va_list args; diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index 6ead6314..338d040 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h @@ -1288,9 +1288,9 @@ int jiftime(char *s, long mark); int HiSax_command(isdn_ctrl *ic); int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb); __printf(3, 4) -void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...); +void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...); __printf(3, 0) -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args); +void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args); void HiSax_reportcard(int cardnr, int sel); int QuickHex(char *txt, u_char *p, int cnt); void LogFrame(struct IsdnCardState *cs, u_char *p, int size); -- 2.8.1
[PATCH v3 2/7] Split up struct warn_args
to enable dataflow verification by the initify plugin. This allows marking warn_slowpath* parameters as nocapture and compile time verification of the related dataflows. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- include/asm-generic/bug.h | 5 + kernel/panic.c| 32 lib/bug.c | 2 +- 3 files changed, 14 insertions(+), 25 deletions(-) diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 6f96247..3048d10 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -81,11 +81,8 @@ extern void warn_slowpath_null(const char *file, const int line); do { printk(arg); __WARN_TAINT(taint); } while (0) #endif -/* used internally by panic.c */ -struct warn_args; - void __warn(const char *file, int line, void *caller, unsigned taint, - struct pt_regs *regs, struct warn_args *args); + struct pt_regs *regs, const char *fmt, va_list args); #ifndef WARN_ON #define WARN_ON(condition) ({ \ diff --git a/kernel/panic.c b/kernel/panic.c index ca8cea1..993ad20 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -475,13 +475,8 @@ void oops_exit(void) kmsg_dump(KMSG_DUMP_OOPS); } -struct warn_args { - const char *fmt; - va_list args; -}; - void __warn(const char *file, int line, void *caller, unsigned taint, - struct pt_regs *regs, struct warn_args *args) + struct pt_regs *regs, const char *fmt, va_list args) { disable_trace_on_warning(); @@ -495,8 +490,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint, pr_warn("WARNING: CPU: %d PID: %d at %pS\n", raw_smp_processor_id(), current->pid, caller); - if (args) - vprintk(args->fmt, args->args); + if (fmt) + vprintk(fmt, args); if (panic_on_warn) { /* @@ -525,31 +520,28 @@ void __warn(const char *file, int line, void *caller, unsigned taint, #ifdef WANT_WARN_ON_SLOWPATH void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...) { - struct warn_args args; + va_list args; - args.fmt = fmt; - va_start(args.args, fmt); - __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, - ); - va_end(args.args); + va_start(args, fmt); + __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, fmt, args); + va_end(args); } EXPORT_SYMBOL(warn_slowpath_fmt); void warn_slowpath_fmt_taint(const char *file, int line, unsigned taint, const char *fmt, ...) { - struct warn_args args; + va_list args; - args.fmt = fmt; - va_start(args.args, fmt); - __warn(file, line, __builtin_return_address(0), taint, NULL, ); - va_end(args.args); + va_start(args, fmt); + __warn(file, line, __builtin_return_address(0), taint, NULL, fmt, args); + va_end(args); } EXPORT_SYMBOL(warn_slowpath_fmt_taint); void warn_slowpath_null(const char *file, int line) { - __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL); + __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL, NULL); } EXPORT_SYMBOL(warn_slowpath_null); #endif diff --git a/lib/bug.c b/lib/bug.c index bc3656e..c8bdebb 100644 --- a/lib/bug.c +++ b/lib/bug.c @@ -168,7 +168,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) if (warning) { /* this is a WARN_ON rather than BUG/BUG_ON */ __warn(file, line, (void *)bugaddr, BUG_GET_TAINT(bug), regs, - NULL); + NULL, NULL); return BUG_TRAP_TYPE_WARN; } -- 2.8.1
[PATCH v3 2/7] Split up struct warn_args
to enable dataflow verification by the initify plugin. This allows marking warn_slowpath* parameters as nocapture and compile time verification of the related dataflows. Signed-off-by: Emese Revfy --- include/asm-generic/bug.h | 5 + kernel/panic.c| 32 lib/bug.c | 2 +- 3 files changed, 14 insertions(+), 25 deletions(-) diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 6f96247..3048d10 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -81,11 +81,8 @@ extern void warn_slowpath_null(const char *file, const int line); do { printk(arg); __WARN_TAINT(taint); } while (0) #endif -/* used internally by panic.c */ -struct warn_args; - void __warn(const char *file, int line, void *caller, unsigned taint, - struct pt_regs *regs, struct warn_args *args); + struct pt_regs *regs, const char *fmt, va_list args); #ifndef WARN_ON #define WARN_ON(condition) ({ \ diff --git a/kernel/panic.c b/kernel/panic.c index ca8cea1..993ad20 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -475,13 +475,8 @@ void oops_exit(void) kmsg_dump(KMSG_DUMP_OOPS); } -struct warn_args { - const char *fmt; - va_list args; -}; - void __warn(const char *file, int line, void *caller, unsigned taint, - struct pt_regs *regs, struct warn_args *args) + struct pt_regs *regs, const char *fmt, va_list args) { disable_trace_on_warning(); @@ -495,8 +490,8 @@ void __warn(const char *file, int line, void *caller, unsigned taint, pr_warn("WARNING: CPU: %d PID: %d at %pS\n", raw_smp_processor_id(), current->pid, caller); - if (args) - vprintk(args->fmt, args->args); + if (fmt) + vprintk(fmt, args); if (panic_on_warn) { /* @@ -525,31 +520,28 @@ void __warn(const char *file, int line, void *caller, unsigned taint, #ifdef WANT_WARN_ON_SLOWPATH void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...) { - struct warn_args args; + va_list args; - args.fmt = fmt; - va_start(args.args, fmt); - __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, - ); - va_end(args.args); + va_start(args, fmt); + __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, fmt, args); + va_end(args); } EXPORT_SYMBOL(warn_slowpath_fmt); void warn_slowpath_fmt_taint(const char *file, int line, unsigned taint, const char *fmt, ...) { - struct warn_args args; + va_list args; - args.fmt = fmt; - va_start(args.args, fmt); - __warn(file, line, __builtin_return_address(0), taint, NULL, ); - va_end(args.args); + va_start(args, fmt); + __warn(file, line, __builtin_return_address(0), taint, NULL, fmt, args); + va_end(args); } EXPORT_SYMBOL(warn_slowpath_fmt_taint); void warn_slowpath_null(const char *file, int line) { - __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL); + __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL, NULL); } EXPORT_SYMBOL(warn_slowpath_null); #endif diff --git a/lib/bug.c b/lib/bug.c index bc3656e..c8bdebb 100644 --- a/lib/bug.c +++ b/lib/bug.c @@ -168,7 +168,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs) if (warning) { /* this is a WARN_ON rather than BUG/BUG_ON */ __warn(file, line, (void *)bugaddr, BUG_GET_TAINT(bug), regs, - NULL); + NULL, NULL); return BUG_TRAP_TYPE_WARN; } -- 2.8.1
[PATCH v3 1/7] Move type casts into is_kernel_rodata
so that its parameter can be marked as nocapture. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- mm/util.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mm/util.c b/mm/util.c index 662cddf..d95f10b 100644 --- a/mm/util.c +++ b/mm/util.c @@ -17,10 +17,10 @@ #include "internal.h" -static inline int is_kernel_rodata(unsigned long addr) +static inline int is_kernel_rodata(const void *addr) { - return addr >= (unsigned long)__start_rodata && - addr < (unsigned long)__end_rodata; + return (unsigned long)addr >= (unsigned long)__start_rodata && + (unsigned long)addr < (unsigned long)__end_rodata; } /** @@ -31,7 +31,7 @@ static inline int is_kernel_rodata(unsigned long addr) */ void kfree_const(const void *x) { - if (!is_kernel_rodata((unsigned long)x)) + if (!is_kernel_rodata(x)) kfree(x); } EXPORT_SYMBOL(kfree_const); @@ -68,7 +68,7 @@ EXPORT_SYMBOL(kstrdup); */ const char *kstrdup_const(const char *s, gfp_t gfp) { - if (is_kernel_rodata((unsigned long)s)) + if (is_kernel_rodata(s)) return s; return kstrdup(s, gfp); -- 2.8.1
[PATCH v3 1/7] Move type casts into is_kernel_rodata
so that its parameter can be marked as nocapture. Signed-off-by: Emese Revfy --- mm/util.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mm/util.c b/mm/util.c index 662cddf..d95f10b 100644 --- a/mm/util.c +++ b/mm/util.c @@ -17,10 +17,10 @@ #include "internal.h" -static inline int is_kernel_rodata(unsigned long addr) +static inline int is_kernel_rodata(const void *addr) { - return addr >= (unsigned long)__start_rodata && - addr < (unsigned long)__end_rodata; + return (unsigned long)addr >= (unsigned long)__start_rodata && + (unsigned long)addr < (unsigned long)__end_rodata; } /** @@ -31,7 +31,7 @@ static inline int is_kernel_rodata(unsigned long addr) */ void kfree_const(const void *x) { - if (!is_kernel_rodata((unsigned long)x)) + if (!is_kernel_rodata(x)) kfree(x); } EXPORT_SYMBOL(kfree_const); @@ -68,7 +68,7 @@ EXPORT_SYMBOL(kstrdup); */ const char *kstrdup_const(const char *s, gfp_t gfp) { - if (is_kernel_rodata((unsigned long)s)) + if (is_kernel_rodata(s)) return s; return kstrdup(s, gfp); -- 2.8.1
[PATCH v3 0/7] Introduce the initify gcc plugin
I would like to introduce the initify gcc plugin. The kernel already has a mechanism to free up code and data memory that is only used during kernel or module initialization. This plugin will teach the compiler to find more such code and data that can be freed after initialization. It reduces memory usage. The initify gcc plugin can be useful for embedded systems. Originally it was a CII project supported by the Linux Foundation. This plugin is the part of grsecurity/PaX. The plugin supports all gcc versions from 4.5 to 6.0. I made some changes on top of the PaX version (since March 6.). These are the important ones: * move all local strings to init.rodata.str and exit.rodata.str (not just __func__) * report all initified strings and functions (GCC_PLUGIN_INITIFY_VERBOSE config option) * automatically discover init/exit functions and apply the __init or __exit attributes on them You can find more about the changes here: https://github.com/ephox-gcc-plugins/initify This patch set is based on next-20160721. Some statistics about the plugin: On allyes config (amd64, gcc-6): * 8412 initified strings * 167 initified functions On allmod config (i386, gcc-6): * 8597 initified strings * 159 initified functions On allyes config (amd64, gcc-6): section vanilla vanilla + initifychange --- .rodata 21746728 (0x14bd428)21488680 (0x147e428)-258048 .init.data 1338376 (0x146c08) 1683016 (0x19ae48)+344640 .text 78270904 (0x4aa51b8)78228280 (0x4a9ab38) -42624 .init.text 1184725 (0x1213d5) 1223257 (0x12aa59) +38532 .exit.data 104 (0x68) 17760 (0x004560) +17656 .exit.text174473 (0x02a989) 175763 (0x02ae93) +1290 FileSiz (vanilla) FileSiz (vanilla + initify) change 00 102936576 (0x622b000) 102678528 (0x61ec000) -258048 03 28680192 (0x1b5a000)29081600 (0x1bbc000) +401408 00 .text .notes __ex_table .rodata __bug_table .pci_fixup .builtin_fw .tracedata __ksymtab __ksymtab_gpl __ksymtab_strings __init_rodata __param __modver 03 .init.text .altinstr_aux .init.data .x86_cpu_dev.init .parainstructions .altinstructions .altinstr_replacement .iommu_table .apicdrivers .exit.text .exit.data .smp_locks .bss .brk On defconfig (amd64, gcc-6): * 1957 initified strings * 29 initified functions On defconfig (amd64, gcc-6): section vanilla vanilla + initifychange --- .rodata 2524240 (0x268450) 2462800 (0x259450) -61440 .init.data 560256 (0x088c80) 644000 (0x09d3a0) +83744 .text 9377367 (0x8f1657) 9373079 (0x8f0597) -4288 .init.text 438586 (0x06b13a) 441828 (0x06bde4) +3242 .exit.data0 832 (0x000340)+832 .exit.text 8857 (0x002299) 8857 (0x002299) 0 FileSiz (vanilla) FileSiz (vanilla + initify) change 00 13398016 (0xcc7000) 13336576 (0xcb8000) -61440 03 2203648 (0x21a000) 2293760 (0x23) +90112 00 .text .notes __ex_table .rodata __bug_table .pci_fixup .builtin_fw .tracedata __ksymtab __ksymtab_gpl __ksymtab_strings __init_rodata __param __modver 03 .init.text .altinstr_aux .init.data .x86_cpu_dev.init .parainstructions .altinstructions .altinstr_replacement .iommu_table .apicdrivers .exit.text .exit.data .smp_locks .bss .brk Emese Revfy (7): Move type casts into is_kernel_rodata Split up struct warn_args to enable dataflow verification by the initify plugin Constify some function parameters Add the initify gcc plugin Mark functions with the __nocapture attribute Mark a few functions with the printf attribute Mark functions with the __unverified_nocapture attribute Changed from v2: * Check all uses when walking a use-def chain. * Check all uses of initialized local variables and initify them if they have only nocapture uses. Previously only uses in call arguments determined whether the initializer value could be initified. * Handle the format gcc attribute from the plugin too. * Verify nocapture parameters of calls. Track uses of these parameters and verify that all uses are not captured. Verify only the nocapture attribute (The format attribute should be verified too.). * Fixed wrong indexing of function arguments. * Fixed decl comparison. When comparing two decls the tree codes must be the same. * Search capture uses of the return value. Use negative nocapture attribute parameter on a function
[PATCH v3 0/7] Introduce the initify gcc plugin
I would like to introduce the initify gcc plugin. The kernel already has a mechanism to free up code and data memory that is only used during kernel or module initialization. This plugin will teach the compiler to find more such code and data that can be freed after initialization. It reduces memory usage. The initify gcc plugin can be useful for embedded systems. Originally it was a CII project supported by the Linux Foundation. This plugin is the part of grsecurity/PaX. The plugin supports all gcc versions from 4.5 to 6.0. I made some changes on top of the PaX version (since March 6.). These are the important ones: * move all local strings to init.rodata.str and exit.rodata.str (not just __func__) * report all initified strings and functions (GCC_PLUGIN_INITIFY_VERBOSE config option) * automatically discover init/exit functions and apply the __init or __exit attributes on them You can find more about the changes here: https://github.com/ephox-gcc-plugins/initify This patch set is based on next-20160721. Some statistics about the plugin: On allyes config (amd64, gcc-6): * 8412 initified strings * 167 initified functions On allmod config (i386, gcc-6): * 8597 initified strings * 159 initified functions On allyes config (amd64, gcc-6): section vanilla vanilla + initifychange --- .rodata 21746728 (0x14bd428)21488680 (0x147e428)-258048 .init.data 1338376 (0x146c08) 1683016 (0x19ae48)+344640 .text 78270904 (0x4aa51b8)78228280 (0x4a9ab38) -42624 .init.text 1184725 (0x1213d5) 1223257 (0x12aa59) +38532 .exit.data 104 (0x68) 17760 (0x004560) +17656 .exit.text174473 (0x02a989) 175763 (0x02ae93) +1290 FileSiz (vanilla) FileSiz (vanilla + initify) change 00 102936576 (0x622b000) 102678528 (0x61ec000) -258048 03 28680192 (0x1b5a000)29081600 (0x1bbc000) +401408 00 .text .notes __ex_table .rodata __bug_table .pci_fixup .builtin_fw .tracedata __ksymtab __ksymtab_gpl __ksymtab_strings __init_rodata __param __modver 03 .init.text .altinstr_aux .init.data .x86_cpu_dev.init .parainstructions .altinstructions .altinstr_replacement .iommu_table .apicdrivers .exit.text .exit.data .smp_locks .bss .brk On defconfig (amd64, gcc-6): * 1957 initified strings * 29 initified functions On defconfig (amd64, gcc-6): section vanilla vanilla + initifychange --- .rodata 2524240 (0x268450) 2462800 (0x259450) -61440 .init.data 560256 (0x088c80) 644000 (0x09d3a0) +83744 .text 9377367 (0x8f1657) 9373079 (0x8f0597) -4288 .init.text 438586 (0x06b13a) 441828 (0x06bde4) +3242 .exit.data0 832 (0x000340)+832 .exit.text 8857 (0x002299) 8857 (0x002299) 0 FileSiz (vanilla) FileSiz (vanilla + initify) change 00 13398016 (0xcc7000) 13336576 (0xcb8000) -61440 03 2203648 (0x21a000) 2293760 (0x23) +90112 00 .text .notes __ex_table .rodata __bug_table .pci_fixup .builtin_fw .tracedata __ksymtab __ksymtab_gpl __ksymtab_strings __init_rodata __param __modver 03 .init.text .altinstr_aux .init.data .x86_cpu_dev.init .parainstructions .altinstructions .altinstr_replacement .iommu_table .apicdrivers .exit.text .exit.data .smp_locks .bss .brk Emese Revfy (7): Move type casts into is_kernel_rodata Split up struct warn_args to enable dataflow verification by the initify plugin Constify some function parameters Add the initify gcc plugin Mark functions with the __nocapture attribute Mark a few functions with the printf attribute Mark functions with the __unverified_nocapture attribute Changed from v2: * Check all uses when walking a use-def chain. * Check all uses of initialized local variables and initify them if they have only nocapture uses. Previously only uses in call arguments determined whether the initializer value could be initified. * Handle the format gcc attribute from the plugin too. * Verify nocapture parameters of calls. Track uses of these parameters and verify that all uses are not captured. Verify only the nocapture attribute (The format attribute should be verified too.). * Fixed wrong indexing of function arguments. * Fixed decl comparison. When comparing two decls the tree codes must be the same. * Search capture uses of the return value. Use negative nocapture attribute parameter on a function
Re: [PATCH v2 1/3] Add the initify gcc plugin
On Tue, 12 Jul 2016 18:38:47 -0400 Kees Cook <keesc...@chromium.org> wrote: > On Tue, Jul 12, 2016 at 6:08 PM, Russell King - ARM Linux > <li...@armlinux.org.uk> wrote: > > On Tue, Jul 12, 2016 at 03:45:56PM -0400, Kees Cook wrote: > >> On Mon, Jul 4, 2016 at 7:40 PM, Emese Revfy <re.em...@gmail.com> wrote: > > That sounds like a problem for architectures that still discard the > > __exit section at link time to reduce the size of the linked kernel > > image - though, obviously, if using the plugin results in a smaller > > kernel image _with_ the exit sections, then there's a net benefit > > size-wise. > > Ah right, __exit is dropped for non-modular builds. So, for "both > __init and __exit" it sounds like the behavior depends on the build: > > - if modular: remove __init marking (since we need it after init) > - if non-modular: remove __exit marking (since we'll never call exit) When gcc compiles vmlinux these functions should be in __init and when it compiles *.ko then they can be in __exit. I have no time to do this now but I added it to my todo list. The temporary fix can be that I enable this section move only on x86 (on other archs it will decrase the coverage). -- Emese
Re: [PATCH v2 1/3] Add the initify gcc plugin
On Tue, 12 Jul 2016 18:38:47 -0400 Kees Cook wrote: > On Tue, Jul 12, 2016 at 6:08 PM, Russell King - ARM Linux > wrote: > > On Tue, Jul 12, 2016 at 03:45:56PM -0400, Kees Cook wrote: > >> On Mon, Jul 4, 2016 at 7:40 PM, Emese Revfy wrote: > > That sounds like a problem for architectures that still discard the > > __exit section at link time to reduce the size of the linked kernel > > image - though, obviously, if using the plugin results in a smaller > > kernel image _with_ the exit sections, then there's a net benefit > > size-wise. > > Ah right, __exit is dropped for non-modular builds. So, for "both > __init and __exit" it sounds like the behavior depends on the build: > > - if modular: remove __init marking (since we need it after init) > - if non-modular: remove __exit marking (since we'll never call exit) When gcc compiles vmlinux these functions should be in __init and when it compiles *.ko then they can be in __exit. I have no time to do this now but I added it to my todo list. The temporary fix can be that I enable this section move only on x86 (on other archs it will decrase the coverage). -- Emese
Re: [PATCH v2 1/3] Add the initify gcc plugin
On Tue, 12 Jul 2016 15:45:56 -0400 Kees Cook <keesc...@chromium.org> wrote: > On Mon, Jul 4, 2016 at 7:40 PM, Emese Revfy <re.em...@gmail.com> wrote: > > If a function is called by __init and __exit functions as well then > > the plugin moves it to the __exit section. This causes false positive > > section mismatch errors/warnings that I don't know how to handle yet. > > Should the mismatch checker be updated to recognize this case? Without > the plugin, I assume these kinds of functions would only ever be > marked for __exit? If so, should the plugin strip the __init marking > and only add __exit? I don't modify the existing attributes. I just add a new __init/__exit when a function hasn't a section attribute yet. There are three cases: * when the function is called only by __init functions then the plugin adds the __init attribute * when the function is called only by __exit functions then the plugin adds the __exit attribute * when the function is called by __init and __exit functions too then the plugin adds the __exit attribute. The last case causes the false positive(?) message of the section mismatch. -- Emese
Re: [PATCH v2 1/3] Add the initify gcc plugin
On Tue, 12 Jul 2016 15:45:56 -0400 Kees Cook wrote: > On Mon, Jul 4, 2016 at 7:40 PM, Emese Revfy wrote: > > If a function is called by __init and __exit functions as well then > > the plugin moves it to the __exit section. This causes false positive > > section mismatch errors/warnings that I don't know how to handle yet. > > Should the mismatch checker be updated to recognize this case? Without > the plugin, I assume these kinds of functions would only ever be > marked for __exit? If so, should the plugin strip the __init marking > and only add __exit? I don't modify the existing attributes. I just add a new __init/__exit when a function hasn't a section attribute yet. There are three cases: * when the function is called only by __init functions then the plugin adds the __init attribute * when the function is called only by __exit functions then the plugin adds the __exit attribute * when the function is called by __init and __exit functions too then the plugin adds the __exit attribute. The last case causes the false positive(?) message of the section mismatch. -- Emese
Re: [PATCH v2 1/3] Add the initify gcc plugin
On Tue, 12 Jul 2016 16:05:45 -0400 Kees Cookwrote: > /* > * The initify gcc-plugin attempts to identify const arguments that are only > * used during init (see __init), so they can be moved to the .init.rodata > * section. If an argument is passed to a non-init function, it must > * normally be assumed that such an argument has been captured by that > * function and may be used in the future when .init has been unmapped from > * memory. In order to identify functions that are confirmed to not capture > * their arguments, the __nocapture() attribute is used so that initify can > * better identify candidate variables. > */ > #ifdef INITIFY_PLUGIN > # define __nocapture(...) __attribute__((nocapture(__VA_ARGS__))) > #endif Thanks, I'll take it in the next patch set with some additions (the attribute also handles __exit functions and the plugin does other things e.g., it can identify candidate init/exit functions and move them automatically to init.text/exit.text). -- Emese
Re: [PATCH v2 1/3] Add the initify gcc plugin
On Tue, 12 Jul 2016 16:05:45 -0400 Kees Cook wrote: > /* > * The initify gcc-plugin attempts to identify const arguments that are only > * used during init (see __init), so they can be moved to the .init.rodata > * section. If an argument is passed to a non-init function, it must > * normally be assumed that such an argument has been captured by that > * function and may be used in the future when .init has been unmapped from > * memory. In order to identify functions that are confirmed to not capture > * their arguments, the __nocapture() attribute is used so that initify can > * better identify candidate variables. > */ > #ifdef INITIFY_PLUGIN > # define __nocapture(...) __attribute__((nocapture(__VA_ARGS__))) > #endif Thanks, I'll take it in the next patch set with some additions (the attribute also handles __exit functions and the plugin does other things e.g., it can identify candidate init/exit functions and move them automatically to init.text/exit.text). -- Emese
Re: [PATCH v2 1/3] Add the initify gcc plugin
On Tue, 12 Jul 2016 15:45:56 -0400 Kees Cook <keesc...@chromium.org> wrote: > On Mon, Jul 4, 2016 at 7:40 PM, Emese Revfy <re.em...@gmail.com> wrote: > Thanks for sending this! I'll get it added to my tree for some 0day > build testing, and then get it into my -next tree. I'll send a new patch set soon. I'm working on some fixes and I would like to implement the handling of return uses to increase the coverage (which decreases because of the bug fixes :) ). So please hold off with testing until the next patch. -- Emese
Re: [PATCH v2 1/3] Add the initify gcc plugin
On Tue, 12 Jul 2016 15:45:56 -0400 Kees Cook wrote: > On Mon, Jul 4, 2016 at 7:40 PM, Emese Revfy wrote: > Thanks for sending this! I'll get it added to my tree for some 0day > build testing, and then get it into my -next tree. I'll send a new patch set soon. I'm working on some fixes and I would like to implement the handling of return uses to increase the coverage (which decreases because of the bug fixes :) ). So please hold off with testing until the next patch. -- Emese
Re: [PATCH v2 3/3] Constify some function parameters
On Tue, 5 Jul 2016 07:58:04 +0800 kbuild test robotwrote: > All warnings (new ones prefixed by >>): > >drivers/isdn/hisax/config.c: In function 'VHiSax_putstatus': > >> drivers/isdn/hisax/config.c:688:5: warning: assignment discards 'const' > >> qualifier from pointer target type [-Wdiscarded-qualifiers] > p = fmt; Hi, Thanks for the report, I resent "[PATCH v2 3/3] Constify some function parameters" with the fix. -- Emese
Re: [PATCH v2 3/3] Constify some function parameters
On Tue, 5 Jul 2016 07:58:04 +0800 kbuild test robot wrote: > All warnings (new ones prefixed by >>): > >drivers/isdn/hisax/config.c: In function 'VHiSax_putstatus': > >> drivers/isdn/hisax/config.c:688:5: warning: assignment discards 'const' > >> qualifier from pointer target type [-Wdiscarded-qualifiers] > p = fmt; Hi, Thanks for the report, I resent "[PATCH v2 3/3] Constify some function parameters" with the fix. -- Emese
[PATCH v2 3/3] Constify some function parameters
Initify needs const pointer types, the initify plugin caught some __printf arguments that weren't const yet. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- drivers/isdn/hisax/config.c | 16 drivers/isdn/hisax/hisax.h | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index bf04d2a..2d12c6c 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -659,7 +659,7 @@ int jiftime(char *s, long mark) static u_char tmpbuf[HISAX_STATUS_BUFSIZE]; -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, +void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args) { /* if head == NULL the fmt contains the full info */ @@ -669,23 +669,24 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, u_char *p; isdn_ctrl ic; int len; + const u_char*data; if (!cs) { printk(KERN_WARNING "HiSax: No CardStatus for message"); return; } spin_lock_irqsave(>statlock, flags); - p = tmpbuf; if (head) { + p = tmpbuf; p += jiftime(p, jiffies); p += sprintf(p, " %s", head); p += vsprintf(p, fmt, args); *p++ = '\n'; *p = 0; len = p - tmpbuf; - p = tmpbuf; + data = tmpbuf; } else { - p = fmt; + data = fmt; len = strlen(fmt); } if (len > HISAX_STATUS_BUFSIZE) { @@ -699,13 +700,12 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, if (i >= len) i = len; len -= i; - memcpy(cs->status_write, p, i); + memcpy(cs->status_write, data, i); cs->status_write += i; if (cs->status_write > cs->status_end) cs->status_write = cs->status_buf; - p += i; if (len) { - memcpy(cs->status_write, p, len); + memcpy(cs->status_write, data + i, len); cs->status_write += len; } #ifdef KERNELSTACK_DEBUG @@ -729,7 +729,7 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, } } -void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...) +void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...) { va_list args; diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index 6ead6314..338d040 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h @@ -1288,9 +1288,9 @@ int jiftime(char *s, long mark); int HiSax_command(isdn_ctrl *ic); int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb); __printf(3, 4) -void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...); +void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...); __printf(3, 0) -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args); +void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args); void HiSax_reportcard(int cardnr, int sel); int QuickHex(char *txt, u_char *p, int cnt); void LogFrame(struct IsdnCardState *cs, u_char *p, int size); -- 2.8.1
[PATCH v2 3/3] Constify some function parameters
Initify needs const pointer types, the initify plugin caught some __printf arguments that weren't const yet. Signed-off-by: Emese Revfy --- drivers/isdn/hisax/config.c | 16 drivers/isdn/hisax/hisax.h | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index bf04d2a..2d12c6c 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -659,7 +659,7 @@ int jiftime(char *s, long mark) static u_char tmpbuf[HISAX_STATUS_BUFSIZE]; -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, +void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args) { /* if head == NULL the fmt contains the full info */ @@ -669,23 +669,24 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, u_char *p; isdn_ctrl ic; int len; + const u_char*data; if (!cs) { printk(KERN_WARNING "HiSax: No CardStatus for message"); return; } spin_lock_irqsave(>statlock, flags); - p = tmpbuf; if (head) { + p = tmpbuf; p += jiftime(p, jiffies); p += sprintf(p, " %s", head); p += vsprintf(p, fmt, args); *p++ = '\n'; *p = 0; len = p - tmpbuf; - p = tmpbuf; + data = tmpbuf; } else { - p = fmt; + data = fmt; len = strlen(fmt); } if (len > HISAX_STATUS_BUFSIZE) { @@ -699,13 +700,12 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, if (i >= len) i = len; len -= i; - memcpy(cs->status_write, p, i); + memcpy(cs->status_write, data, i); cs->status_write += i; if (cs->status_write > cs->status_end) cs->status_write = cs->status_buf; - p += i; if (len) { - memcpy(cs->status_write, p, len); + memcpy(cs->status_write, data + i, len); cs->status_write += len; } #ifdef KERNELSTACK_DEBUG @@ -729,7 +729,7 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, } } -void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...) +void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...) { va_list args; diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index 6ead6314..338d040 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h @@ -1288,9 +1288,9 @@ int jiftime(char *s, long mark); int HiSax_command(isdn_ctrl *ic); int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb); __printf(3, 4) -void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...); +void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...); __printf(3, 0) -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args); +void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args); void HiSax_reportcard(int cardnr, int sel); int QuickHex(char *txt, u_char *p, int cnt); void LogFrame(struct IsdnCardState *cs, u_char *p, int size); -- 2.8.1
[PATCH v2 3/3] Constify some function parameters
Initify needs const pointer types, the initify plugin caught some __printf arguments that weren't const yet. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- drivers/isdn/hisax/config.c | 4 ++-- drivers/isdn/hisax/hisax.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index bf04d2a..a7d53c9 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -659,7 +659,7 @@ int jiftime(char *s, long mark) static u_char tmpbuf[HISAX_STATUS_BUFSIZE]; -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, +void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args) { /* if head == NULL the fmt contains the full info */ @@ -729,7 +729,7 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, } } -void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...) +void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...) { va_list args; diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index 6ead6314..338d040 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h @@ -1288,9 +1288,9 @@ int jiftime(char *s, long mark); int HiSax_command(isdn_ctrl *ic); int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb); __printf(3, 4) -void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...); +void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...); __printf(3, 0) -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args); +void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args); void HiSax_reportcard(int cardnr, int sel); int QuickHex(char *txt, u_char *p, int cnt); void LogFrame(struct IsdnCardState *cs, u_char *p, int size); -- 2.8.1
[PATCH v2 3/3] Constify some function parameters
Initify needs const pointer types, the initify plugin caught some __printf arguments that weren't const yet. Signed-off-by: Emese Revfy --- drivers/isdn/hisax/config.c | 4 ++-- drivers/isdn/hisax/hisax.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index bf04d2a..a7d53c9 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -659,7 +659,7 @@ int jiftime(char *s, long mark) static u_char tmpbuf[HISAX_STATUS_BUFSIZE]; -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, +void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args) { /* if head == NULL the fmt contains the full info */ @@ -729,7 +729,7 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, } } -void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...) +void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...) { va_list args; diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index 6ead6314..338d040 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h @@ -1288,9 +1288,9 @@ int jiftime(char *s, long mark); int HiSax_command(isdn_ctrl *ic); int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb); __printf(3, 4) -void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...); +void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, ...); __printf(3, 0) -void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args); +void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, va_list args); void HiSax_reportcard(int cardnr, int sel); int QuickHex(char *txt, u_char *p, int cnt); void LogFrame(struct IsdnCardState *cs, u_char *p, int size); -- 2.8.1
[PATCH v2 2/3] Mark functions with the __nocapture attribute
The nocapture gcc attribute can be on functions only. The attribute takes one or more unsigned integer constants as parameters that specify the function argument(s) of const char* type to initify. If the marked argument is a vararg then the plugin initifies all vararg arguments. I couldn't test the arm, arm64 and powerpc architectures. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- arch/arm/include/asm/string.h | 4 +-- arch/arm64/include/asm/string.h | 19 ++-- arch/powerpc/include/asm/string.h | 19 ++-- arch/x86/include/asm/string_32.h | 21 ++--- arch/x86/include/asm/string_64.h | 20 ++--- arch/x86/kernel/hpet.c| 2 +- include/asm-generic/bug.h | 6 ++-- include/linux/compiler-gcc.h | 10 +-- include/linux/compiler.h | 4 +++ include/linux/fs.h| 5 ++-- include/linux/printk.h| 2 +- include/linux/string.h| 63 --- 12 files changed, 96 insertions(+), 79 deletions(-) diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h index cf4f3aa..ddb9d58 100644 --- a/arch/arm/include/asm/string.h +++ b/arch/arm/include/asm/string.h @@ -13,10 +13,10 @@ extern char * strrchr(const char * s, int c); extern char * strchr(const char * s, int c); #define __HAVE_ARCH_MEMCPY -extern void * memcpy(void *, const void *, __kernel_size_t); +extern void * memcpy(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMMOVE -extern void * memmove(void *, const void *, __kernel_size_t); +extern void * memmove(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMCHR extern void * memchr(const void *, int, __kernel_size_t); diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h index 2eb714c..4263a27 100644 --- a/arch/arm64/include/asm/string.h +++ b/arch/arm64/include/asm/string.h @@ -23,24 +23,25 @@ extern char *strrchr(const char *, int c); extern char *strchr(const char *, int c); #define __HAVE_ARCH_STRCMP -extern int strcmp(const char *, const char *); +extern int strcmp(const char *, const char *) __nocapture(1, 2); #define __HAVE_ARCH_STRNCMP -extern int strncmp(const char *, const char *, __kernel_size_t); +extern int +strncmp(const char *, const char *, __kernel_size_t) __nocapture(1, 2); #define __HAVE_ARCH_STRLEN -extern __kernel_size_t strlen(const char *); +extern __kernel_size_t strlen(const char *) __nocapture(1); #define __HAVE_ARCH_STRNLEN -extern __kernel_size_t strnlen(const char *, __kernel_size_t); +extern __kernel_size_t strnlen(const char *, __kernel_size_t) __nocapture(1); #define __HAVE_ARCH_MEMCPY -extern void *memcpy(void *, const void *, __kernel_size_t); -extern void *__memcpy(void *, const void *, __kernel_size_t); +extern void *memcpy(void *, const void *, __kernel_size_t) __nocapture(2); +extern void *__memcpy(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMMOVE -extern void *memmove(void *, const void *, __kernel_size_t); -extern void *__memmove(void *, const void *, __kernel_size_t); +extern void *memmove(void *, const void *, __kernel_size_t) __nocapture(2); +extern void *__memmove(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMCHR extern void *memchr(const void *, int, __kernel_size_t); @@ -50,7 +51,7 @@ extern void *memset(void *, int, __kernel_size_t); extern void *__memset(void *, int, __kernel_size_t); #define __HAVE_ARCH_MEMCMP -extern int memcmp(const void *, const void *, size_t); +extern int memcmp(const void *, const void *, size_t) __nocapture(1, 2); #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h index da3cdff..e67f1eb 100644 --- a/arch/powerpc/include/asm/string.h +++ b/arch/powerpc/include/asm/string.h @@ -11,16 +11,17 @@ #define __HAVE_ARCH_MEMCMP #define __HAVE_ARCH_MEMCHR -extern char * strcpy(char *,const char *); -extern char * strncpy(char *,const char *, __kernel_size_t); -extern __kernel_size_t strlen(const char *); -extern int strcmp(const char *,const char *); -extern int strncmp(const char *, const char *, __kernel_size_t); -extern char * strcat(char *, const char *); +extern char * strcpy(char *,const char *) __nocapture(2); +extern char * strncpy(char *,const char *, __kernel_size_t) __nocapture(2); +extern __kernel_size_t strlen(const char *) __nocapture(1); +extern int strcmp(const char *,const char *) __nocapture(1, 2); +extern int +strncmp(const char *, const char *, __kernel_size_t) __nocapture(1, 2); +extern char * strcat(char *, const char *) __nocapture(2); extern void * memset(void *,int,__kernel_size_t); -extern void * memcpy(void *,const void *,__kernel_size_t); -extern void * memmove(void *,const void *,__kernel_size_t); -extern int memcmp(const void *,const void *,__kernel_size_t)
[PATCH v2 2/3] Mark functions with the __nocapture attribute
The nocapture gcc attribute can be on functions only. The attribute takes one or more unsigned integer constants as parameters that specify the function argument(s) of const char* type to initify. If the marked argument is a vararg then the plugin initifies all vararg arguments. I couldn't test the arm, arm64 and powerpc architectures. Signed-off-by: Emese Revfy --- arch/arm/include/asm/string.h | 4 +-- arch/arm64/include/asm/string.h | 19 ++-- arch/powerpc/include/asm/string.h | 19 ++-- arch/x86/include/asm/string_32.h | 21 ++--- arch/x86/include/asm/string_64.h | 20 ++--- arch/x86/kernel/hpet.c| 2 +- include/asm-generic/bug.h | 6 ++-- include/linux/compiler-gcc.h | 10 +-- include/linux/compiler.h | 4 +++ include/linux/fs.h| 5 ++-- include/linux/printk.h| 2 +- include/linux/string.h| 63 --- 12 files changed, 96 insertions(+), 79 deletions(-) diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h index cf4f3aa..ddb9d58 100644 --- a/arch/arm/include/asm/string.h +++ b/arch/arm/include/asm/string.h @@ -13,10 +13,10 @@ extern char * strrchr(const char * s, int c); extern char * strchr(const char * s, int c); #define __HAVE_ARCH_MEMCPY -extern void * memcpy(void *, const void *, __kernel_size_t); +extern void * memcpy(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMMOVE -extern void * memmove(void *, const void *, __kernel_size_t); +extern void * memmove(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMCHR extern void * memchr(const void *, int, __kernel_size_t); diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h index 2eb714c..4263a27 100644 --- a/arch/arm64/include/asm/string.h +++ b/arch/arm64/include/asm/string.h @@ -23,24 +23,25 @@ extern char *strrchr(const char *, int c); extern char *strchr(const char *, int c); #define __HAVE_ARCH_STRCMP -extern int strcmp(const char *, const char *); +extern int strcmp(const char *, const char *) __nocapture(1, 2); #define __HAVE_ARCH_STRNCMP -extern int strncmp(const char *, const char *, __kernel_size_t); +extern int +strncmp(const char *, const char *, __kernel_size_t) __nocapture(1, 2); #define __HAVE_ARCH_STRLEN -extern __kernel_size_t strlen(const char *); +extern __kernel_size_t strlen(const char *) __nocapture(1); #define __HAVE_ARCH_STRNLEN -extern __kernel_size_t strnlen(const char *, __kernel_size_t); +extern __kernel_size_t strnlen(const char *, __kernel_size_t) __nocapture(1); #define __HAVE_ARCH_MEMCPY -extern void *memcpy(void *, const void *, __kernel_size_t); -extern void *__memcpy(void *, const void *, __kernel_size_t); +extern void *memcpy(void *, const void *, __kernel_size_t) __nocapture(2); +extern void *__memcpy(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMMOVE -extern void *memmove(void *, const void *, __kernel_size_t); -extern void *__memmove(void *, const void *, __kernel_size_t); +extern void *memmove(void *, const void *, __kernel_size_t) __nocapture(2); +extern void *__memmove(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMCHR extern void *memchr(const void *, int, __kernel_size_t); @@ -50,7 +51,7 @@ extern void *memset(void *, int, __kernel_size_t); extern void *__memset(void *, int, __kernel_size_t); #define __HAVE_ARCH_MEMCMP -extern int memcmp(const void *, const void *, size_t); +extern int memcmp(const void *, const void *, size_t) __nocapture(1, 2); #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h index da3cdff..e67f1eb 100644 --- a/arch/powerpc/include/asm/string.h +++ b/arch/powerpc/include/asm/string.h @@ -11,16 +11,17 @@ #define __HAVE_ARCH_MEMCMP #define __HAVE_ARCH_MEMCHR -extern char * strcpy(char *,const char *); -extern char * strncpy(char *,const char *, __kernel_size_t); -extern __kernel_size_t strlen(const char *); -extern int strcmp(const char *,const char *); -extern int strncmp(const char *, const char *, __kernel_size_t); -extern char * strcat(char *, const char *); +extern char * strcpy(char *,const char *) __nocapture(2); +extern char * strncpy(char *,const char *, __kernel_size_t) __nocapture(2); +extern __kernel_size_t strlen(const char *) __nocapture(1); +extern int strcmp(const char *,const char *) __nocapture(1, 2); +extern int +strncmp(const char *, const char *, __kernel_size_t) __nocapture(1, 2); +extern char * strcat(char *, const char *) __nocapture(2); extern void * memset(void *,int,__kernel_size_t); -extern void * memcpy(void *,const void *,__kernel_size_t); -extern void * memmove(void *,const void *,__kernel_size_t); -extern int memcmp(const void *,const void *,__kernel_size_t); +extern void * memcpy(void
[PATCH v2 1/3] Add the initify gcc plugin
The kernel already has a mechanism to free up code and data memory that is only used during kernel or module initialization. This plugin will teach the compiler to find more such code and data that can be freed after initialization. It has two passes. The first one tries to find all functions that can be become __init/__exit. The second one moves string constants (local variables and function string arguments marked by the nocapture attribute) only referenced in __init/__exit functions to the __initconst/__exitconst sections. It reduces memory usage. This plugin can be useful for embedded systems. If a function is called by __init and __exit functions as well then the plugin moves it to the __exit section. This causes false positive section mismatch errors/warnings that I don't know how to handle yet. The instrumentation pass of the latent_entropy plugin must run after the initify plugin to increase coverage. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- arch/Kconfig | 23 + include/asm-generic/vmlinux.lds.h|2 + scripts/Makefile.gcc-plugins |4 + scripts/gcc-plugins/gcc-common.h | 41 ++ scripts/gcc-plugins/initify_plugin.c | 1183 ++ 5 files changed, 1253 insertions(+) create mode 100644 scripts/gcc-plugins/initify_plugin.c diff --git a/arch/Kconfig b/arch/Kconfig index 1c91f52..0c877f6 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -417,6 +417,29 @@ config GCC_PLUGIN_LATENT_ENTROPY * https://grsecurity.net/ * https://pax.grsecurity.net/ +config GCC_PLUGIN_INITIFY + bool "Free more kernel memory after init" + depends on GCC_PLUGINS + help + The kernel has a mechanism to free up code and data memory that is + only used during kernel or module initialization. Enabling this + feature will teach the compiler to find more such code and data + that can be freed after initialization. + + This plugin is the part of grsecurity/PaX. More information at: + * https://grsecurity.net/ + * https://pax.grsecurity.net/ + +config GCC_PLUGIN_INITIFY_VERBOSE + bool "Verbose" + depends on GCC_PLUGIN_INITIFY + help + Print all initified strings and all functions which should be + __init/__exit. + Note that the candidates identified for __init/__exit markings + depend on the current kernel configuration and thus should be verified + manually before the source code is patched. + config HAVE_CC_STACKPROTECTOR bool help diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index ec3b78d..c73537a 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -531,6 +531,7 @@ MEM_DISCARD(init.data) \ KERNEL_CTORS() \ MCOUNT_REC()\ + *(.init.rodata.str) \ *(.init.rodata) \ FTRACE_EVENTS() \ TRACE_SYSCALLS()\ @@ -555,6 +556,7 @@ #define EXIT_DATA \ *(.exit.data) \ MEM_DISCARD(exit.data) \ + *(.exit.rodata.str) \ MEM_DISCARD(exit.rodata) #define EXIT_TEXT \ diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 1f922df..0ce8392 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -12,6 +12,10 @@ ifdef CONFIG_GCC_PLUGINS DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable endif + gcc-plugin-$(CONFIG_GCC_PLUGIN_INITIFY) += initify_plugin.so + gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_INITIFY) += -DINITIFY_PLUGIN -fplugin-arg-initify_plugin-search_init_exit_functions + gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_INITIFY_VERBOSE)+= -fplugin-arg-initify_plugin-verbose + ifdef CONFIG_GCC_PLUGIN_SANCOV ifeq ($(CFLAGS_KCOV),) # It is needed because of the gcc-plugin.sh and gcc version checks. diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h index 172850b..7f2eb16 100644 --- a/scripts/gcc-plugins/gcc-common.h +++ b/scripts/gcc-plugins/gcc-common.h @@ -286,6 +286,26 @@ static inline struct cgraph_node *cgraph_next_function_with_gimple_body(struct c return NULL; } +static inline bool cgraph_for_node_and_aliases(cgraph_node_ptr node, + bool (
[PATCH v2 1/3] Add the initify gcc plugin
The kernel already has a mechanism to free up code and data memory that is only used during kernel or module initialization. This plugin will teach the compiler to find more such code and data that can be freed after initialization. It has two passes. The first one tries to find all functions that can be become __init/__exit. The second one moves string constants (local variables and function string arguments marked by the nocapture attribute) only referenced in __init/__exit functions to the __initconst/__exitconst sections. It reduces memory usage. This plugin can be useful for embedded systems. If a function is called by __init and __exit functions as well then the plugin moves it to the __exit section. This causes false positive section mismatch errors/warnings that I don't know how to handle yet. The instrumentation pass of the latent_entropy plugin must run after the initify plugin to increase coverage. Signed-off-by: Emese Revfy --- arch/Kconfig | 23 + include/asm-generic/vmlinux.lds.h|2 + scripts/Makefile.gcc-plugins |4 + scripts/gcc-plugins/gcc-common.h | 41 ++ scripts/gcc-plugins/initify_plugin.c | 1183 ++ 5 files changed, 1253 insertions(+) create mode 100644 scripts/gcc-plugins/initify_plugin.c diff --git a/arch/Kconfig b/arch/Kconfig index 1c91f52..0c877f6 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -417,6 +417,29 @@ config GCC_PLUGIN_LATENT_ENTROPY * https://grsecurity.net/ * https://pax.grsecurity.net/ +config GCC_PLUGIN_INITIFY + bool "Free more kernel memory after init" + depends on GCC_PLUGINS + help + The kernel has a mechanism to free up code and data memory that is + only used during kernel or module initialization. Enabling this + feature will teach the compiler to find more such code and data + that can be freed after initialization. + + This plugin is the part of grsecurity/PaX. More information at: + * https://grsecurity.net/ + * https://pax.grsecurity.net/ + +config GCC_PLUGIN_INITIFY_VERBOSE + bool "Verbose" + depends on GCC_PLUGIN_INITIFY + help + Print all initified strings and all functions which should be + __init/__exit. + Note that the candidates identified for __init/__exit markings + depend on the current kernel configuration and thus should be verified + manually before the source code is patched. + config HAVE_CC_STACKPROTECTOR bool help diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index ec3b78d..c73537a 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -531,6 +531,7 @@ MEM_DISCARD(init.data) \ KERNEL_CTORS() \ MCOUNT_REC()\ + *(.init.rodata.str) \ *(.init.rodata) \ FTRACE_EVENTS() \ TRACE_SYSCALLS()\ @@ -555,6 +556,7 @@ #define EXIT_DATA \ *(.exit.data) \ MEM_DISCARD(exit.data) \ + *(.exit.rodata.str) \ MEM_DISCARD(exit.rodata) #define EXIT_TEXT \ diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 1f922df..0ce8392 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -12,6 +12,10 @@ ifdef CONFIG_GCC_PLUGINS DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable endif + gcc-plugin-$(CONFIG_GCC_PLUGIN_INITIFY) += initify_plugin.so + gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_INITIFY) += -DINITIFY_PLUGIN -fplugin-arg-initify_plugin-search_init_exit_functions + gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_INITIFY_VERBOSE)+= -fplugin-arg-initify_plugin-verbose + ifdef CONFIG_GCC_PLUGIN_SANCOV ifeq ($(CFLAGS_KCOV),) # It is needed because of the gcc-plugin.sh and gcc version checks. diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h index 172850b..7f2eb16 100644 --- a/scripts/gcc-plugins/gcc-common.h +++ b/scripts/gcc-plugins/gcc-common.h @@ -286,6 +286,26 @@ static inline struct cgraph_node *cgraph_next_function_with_gimple_body(struct c return NULL; } +static inline bool cgraph_for_node_and_aliases(cgraph_node_ptr node, + bool (*callback)(c
[PATCH v2 0/3] Introduce the initify gcc plugin
I would like to introduce the initify gcc plugin. The kernel already has a mechanism to free up code and data memory that is only used during kernel or module initialization. This plugin will teach the compiler to find more such code and data that can be freed after initialization. It reduces memory usage. The initify gcc plugin can be useful for embedded systems. It is a CII project supported by the Linux Foundation. This plugin is the part of grsecurity/PaX. The plugin supports all gcc versions from 4.5 to 6.0. I made some changes on top of the PaX version (since March 6.). These are the important ones: * move all local strings to init.rodata.str and exit.rodata.str (not just __func__) * report all initified strings and functions (GCC_PLUGIN_INITIFY_VERBOSE config option) * automatically discover init/exit functions and apply the __init or __exit attributes on them You can find more about the changes here: https://github.com/ephox-gcc-plugins/initify This patch set is based on the "Add support for complex gcc plugins that don't fit in a single file" patch set (https://github.com/ephox-gcc-plugins/gcc-plugins_linux-next.git#initify HEAD: e08eda5d85f7f52641640). Some statistics about the plugin: On allyes config (amd64, gcc-6): * 7765 initified strings * 231 initified functions On allmod config (i386, gcc-6): * 9177 initified strings * 288 initified functions On allyes config (amd64, gcc-6): section vanilla vanilla + initifychange --- .rodata 19054824 (0x122c0e8)18841832 (0x11f80e8)-212992 .init.data 1273768 (0x136fa8) 1583496 (0x182988)+309728 .text 46126301 (0x2bfd4dd)46099805 (0x2bf6d5d) -26496 .init.text836339 (0x0cc2f3) 855952 (0x0d0f90) +19613 .exit.data 104 (0x68) 16736 (0x004160) +16632 .exit.text125511 (0x01ea47) 133267 (0x020893) +7756 FileSiz (vanilla) FileSiz (vanilla + initify) change 00 67727360 (0x4097000)65417216 (0x3e63000)-2310144 03 2453504 (0x257000) 2809856 (0x2ae000) +356352 00 .text .notes __ex_table .rodata __bug_table .pci_fixup .builtin_fw .tracedata __ksymtab __ksymtab_gpl __ksymtab_strings __init_rodata __param __modver 03 .init.text .altinstr_aux .init.data .x86_cpu_dev.init .parainstructions .altinstructions .altinstr_replacement .iommu_table .apicdrivers .exit.text .exit.data .smp_locks .bss .brk On defconfig (amd64, gcc-6): * 2044 initified strings * 43 initified functions On defconfig (amd64, gcc-6): section vanilla vanilla + initifychange --- .rodata 2466736 (0x25a3b0) 2405296 (0x24b3b0) -61440 .init.data 564656 (0x089db0) 645616 (0x09d9f0) +80960 .text 9364727 (0x8ee4f7) 9360823 (0x8ed5b7) -3904 .init.text 436097 (0x06a781) 439161 (0x06b379) +3064 .exit.data0 864 (0x000360)+864 .exit.text 8806 (0x002266) 9824 (0x002660) +1018 FileSiz (vanilla) FileSiz (vanilla + initify) change 00 13340672 (0xcb9000) 13279232 (0xcaa000) -61440 03 1097728 (0x10c000) 1183744 (0x121000) +86016 00 .text .notes __ex_table .rodata __bug_table .pci_fixup .builtin_fw .tracedata __ksymtab __ksymtab_gpl __ksymtab_strings __init_rodata __param __modver 03 .init.text .altinstr_aux .init.data .x86_cpu_dev.init .parainstructions .altinstructions .altinstr_replacement .iommu_table .apicdrivers .exit.text .exit.data .smp_locks .bss .brk Emese Revfy (3): Add the initify gcc plugin Mark functions with the __nocapture attribute Constify some function parameters Changes from v1: * Removed unnecessary nocapture attributes from boot code (Reported-by: PaX Team <pagee...@freemail.hu>) * Removed nocapture attributes from functions that return the marked parameter (Reported-by: Rasmus Villemoes <li...@rasmusvillemoes.dk>) * Added nocapture attribute to strlen() * Updated gcc-common.h from PaX * Don't forcibly constify initified string types this caused the size reduction of the .data section (initify_plugin.c) * Added the section mismatch problem in the commit message --- arch/Kconfig | 23 + arch/arm/include/asm/string.h|4 +- arch/arm64/include/asm/string.h | 19 +- arch/powerpc/include/asm/string.h| 19 +- arch/x86/include/asm/string_32.h | 21 +- arch/x86/include/asm/string_64.h
[PATCH v2 0/3] Introduce the initify gcc plugin
I would like to introduce the initify gcc plugin. The kernel already has a mechanism to free up code and data memory that is only used during kernel or module initialization. This plugin will teach the compiler to find more such code and data that can be freed after initialization. It reduces memory usage. The initify gcc plugin can be useful for embedded systems. It is a CII project supported by the Linux Foundation. This plugin is the part of grsecurity/PaX. The plugin supports all gcc versions from 4.5 to 6.0. I made some changes on top of the PaX version (since March 6.). These are the important ones: * move all local strings to init.rodata.str and exit.rodata.str (not just __func__) * report all initified strings and functions (GCC_PLUGIN_INITIFY_VERBOSE config option) * automatically discover init/exit functions and apply the __init or __exit attributes on them You can find more about the changes here: https://github.com/ephox-gcc-plugins/initify This patch set is based on the "Add support for complex gcc plugins that don't fit in a single file" patch set (https://github.com/ephox-gcc-plugins/gcc-plugins_linux-next.git#initify HEAD: e08eda5d85f7f52641640). Some statistics about the plugin: On allyes config (amd64, gcc-6): * 7765 initified strings * 231 initified functions On allmod config (i386, gcc-6): * 9177 initified strings * 288 initified functions On allyes config (amd64, gcc-6): section vanilla vanilla + initifychange --- .rodata 19054824 (0x122c0e8)18841832 (0x11f80e8)-212992 .init.data 1273768 (0x136fa8) 1583496 (0x182988)+309728 .text 46126301 (0x2bfd4dd)46099805 (0x2bf6d5d) -26496 .init.text836339 (0x0cc2f3) 855952 (0x0d0f90) +19613 .exit.data 104 (0x68) 16736 (0x004160) +16632 .exit.text125511 (0x01ea47) 133267 (0x020893) +7756 FileSiz (vanilla) FileSiz (vanilla + initify) change 00 67727360 (0x4097000)65417216 (0x3e63000)-2310144 03 2453504 (0x257000) 2809856 (0x2ae000) +356352 00 .text .notes __ex_table .rodata __bug_table .pci_fixup .builtin_fw .tracedata __ksymtab __ksymtab_gpl __ksymtab_strings __init_rodata __param __modver 03 .init.text .altinstr_aux .init.data .x86_cpu_dev.init .parainstructions .altinstructions .altinstr_replacement .iommu_table .apicdrivers .exit.text .exit.data .smp_locks .bss .brk On defconfig (amd64, gcc-6): * 2044 initified strings * 43 initified functions On defconfig (amd64, gcc-6): section vanilla vanilla + initifychange --- .rodata 2466736 (0x25a3b0) 2405296 (0x24b3b0) -61440 .init.data 564656 (0x089db0) 645616 (0x09d9f0) +80960 .text 9364727 (0x8ee4f7) 9360823 (0x8ed5b7) -3904 .init.text 436097 (0x06a781) 439161 (0x06b379) +3064 .exit.data0 864 (0x000360)+864 .exit.text 8806 (0x002266) 9824 (0x002660) +1018 FileSiz (vanilla) FileSiz (vanilla + initify) change 00 13340672 (0xcb9000) 13279232 (0xcaa000) -61440 03 1097728 (0x10c000) 1183744 (0x121000) +86016 00 .text .notes __ex_table .rodata __bug_table .pci_fixup .builtin_fw .tracedata __ksymtab __ksymtab_gpl __ksymtab_strings __init_rodata __param __modver 03 .init.text .altinstr_aux .init.data .x86_cpu_dev.init .parainstructions .altinstructions .altinstr_replacement .iommu_table .apicdrivers .exit.text .exit.data .smp_locks .bss .brk Emese Revfy (3): Add the initify gcc plugin Mark functions with the __nocapture attribute Constify some function parameters Changes from v1: * Removed unnecessary nocapture attributes from boot code (Reported-by: PaX Team ) * Removed nocapture attributes from functions that return the marked parameter (Reported-by: Rasmus Villemoes ) * Added nocapture attribute to strlen() * Updated gcc-common.h from PaX * Don't forcibly constify initified string types this caused the size reduction of the .data section (initify_plugin.c) * Added the section mismatch problem in the commit message --- arch/Kconfig | 23 + arch/arm/include/asm/string.h|4 +- arch/arm64/include/asm/string.h | 19 +- arch/powerpc/include/asm/string.h| 19 +- arch/x86/include/asm/string_32.h | 21 +- arch/x86/include/asm/string_64.h | 20 +- arch/x86/kernel/hpet.c |2 +- dr
Re: [PATCH v1 2/2] Mark functions with the __nocapture attribute
On Wed, 29 Jun 2016 17:12:45 -0700 Joe Perches <j...@perches.com> wrote: > On Wed, 2016-06-29 at 20:42 +0200, Emese Revfy wrote: > > On Tue, 28 Jun 2016 14:00:57 -0700 Joe Perches <j...@perches.com> wrote: > > > On Tue, 2016-06-28 at 22:40 +0200, Emese Revfy wrote: > > > > On Tue, 28 Jun 2016 09:43:31 -0700 Joe Perches <j...@perches.com> wrote: > > > > > On Tue, 2016-06-28 at 13:36 +0200, Emese Revfy wrote: > > > > > > The nocapture gcc attribute can be on functions only. > > > > > > The attribute takes one or more unsigned integer constants as > > > > > > parameters > > > > > > that specify the function argument(s) of const char* type to > > > > > > initify. > > > > > Perhaps this should be const * > > > > For me function arguments are the values passed to a function call so > > > > the const char* type is good because this is the only one that the > > > > plugin handles > > > > (for now at least). > > > OK, but this function prototype specified takes a const void * > > > > > > +extern void * memcpy(void *, const void *, __kernel_size_t) > > > __nocapture(2); > > What matters for the plugin is the type of the passed arguments (which can > > be const char* > > in the current implementation), not that of the parameters. > > And how does this work when the prototype requires the compiler to > implicit cast to const void * before calling the function? The plugin searches for the nocapture attribute that does not depend on the type. If the function argument is not a string constant just a pointer then the plugin walks the data flow (use-def chain) and tries to find a string constant. If there is a cast to void * then the use-def chain will walk across it. -- Emese
Re: [PATCH v1 2/2] Mark functions with the __nocapture attribute
On Wed, 29 Jun 2016 17:12:45 -0700 Joe Perches wrote: > On Wed, 2016-06-29 at 20:42 +0200, Emese Revfy wrote: > > On Tue, 28 Jun 2016 14:00:57 -0700 Joe Perches wrote: > > > On Tue, 2016-06-28 at 22:40 +0200, Emese Revfy wrote: > > > > On Tue, 28 Jun 2016 09:43:31 -0700 Joe Perches wrote: > > > > > On Tue, 2016-06-28 at 13:36 +0200, Emese Revfy wrote: > > > > > > The nocapture gcc attribute can be on functions only. > > > > > > The attribute takes one or more unsigned integer constants as > > > > > > parameters > > > > > > that specify the function argument(s) of const char* type to > > > > > > initify. > > > > > Perhaps this should be const * > > > > For me function arguments are the values passed to a function call so > > > > the const char* type is good because this is the only one that the > > > > plugin handles > > > > (for now at least). > > > OK, but this function prototype specified takes a const void * > > > > > > +extern void * memcpy(void *, const void *, __kernel_size_t) > > > __nocapture(2); > > What matters for the plugin is the type of the passed arguments (which can > > be const char* > > in the current implementation), not that of the parameters. > > And how does this work when the prototype requires the compiler to > implicit cast to const void * before calling the function? The plugin searches for the nocapture attribute that does not depend on the type. If the function argument is not a string constant just a pointer then the plugin walks the data flow (use-def chain) and tries to find a string constant. If there is a cast to void * then the use-def chain will walk across it. -- Emese
Re: [PATCH v1 1/2] Add the initify gcc plugin
On Tue, 28 Jun 2016 23:05:56 +0200 Rasmus Villemoes <li...@rasmusvillemoes.dk> wrote: > On Tue, Jun 28 2016, Emese Revfy <re.em...@gmail.com> wrote: > > > The kernel already has a mechanism to free up code and data memory that > > is only used during kernel or module initialization. > > This plugin will teach the compiler to find more such code and data that > > can be freed after initialization. > > It has two passes. The first one tries to find all functions that > > can be become __init/__exit. The second one moves string constants > > (local variables and function string arguments marked by > > the nocapture attribute) only referenced in __init/__exit functions > > to the __initconst/__exitconst sections. > > It reduces memory usage. This plugin can be useful for embedded systems. > > May I suggest, as a followup patch, a debug option/plugin parameter to > put the strings in a section which will not be reaped after init, but > just marked inaccessible, with graceful handling of bad accesses (print > a big fat warning, make the page(s) readable, continue)? I think even better would be to verify the whole init section. Unfortunately, I won't implement it anytime soon because my project ends this week. -- Emese
Re: [PATCH v1 1/2] Add the initify gcc plugin
On Tue, 28 Jun 2016 23:05:56 +0200 Rasmus Villemoes wrote: > On Tue, Jun 28 2016, Emese Revfy wrote: > > > The kernel already has a mechanism to free up code and data memory that > > is only used during kernel or module initialization. > > This plugin will teach the compiler to find more such code and data that > > can be freed after initialization. > > It has two passes. The first one tries to find all functions that > > can be become __init/__exit. The second one moves string constants > > (local variables and function string arguments marked by > > the nocapture attribute) only referenced in __init/__exit functions > > to the __initconst/__exitconst sections. > > It reduces memory usage. This plugin can be useful for embedded systems. > > May I suggest, as a followup patch, a debug option/plugin parameter to > put the strings in a section which will not be reaped after init, but > just marked inaccessible, with graceful handling of bad accesses (print > a big fat warning, make the page(s) readable, continue)? I think even better would be to verify the whole init section. Unfortunately, I won't implement it anytime soon because my project ends this week. -- Emese
Re: [PATCH v1 2/2] Mark functions with the __nocapture attribute
On Tue, 28 Jun 2016 14:00:57 -0700 Joe Perches <j...@perches.com> wrote: > On Tue, 2016-06-28 at 22:40 +0200, Emese Revfy wrote: > > On Tue, 28 Jun 2016 09:43:31 -0700 Joe Perches <j...@perches.com> wrote: > > > On Tue, 2016-06-28 at 13:36 +0200, Emese Revfy wrote: > > > > The nocapture gcc attribute can be on functions only. > > > > The attribute takes one or more unsigned integer constants as parameters > > > > that specify the function argument(s) of const char* type to initify. > > > Perhaps this should be const * > > For me function arguments are the values passed to a function call so > > the const char* type is good because this is the only one that the plugin > > handles > > (for now at least). > > OK, but this function prototype specified takes a const void * > > +extern void * memcpy(void *, const void *, __kernel_size_t) __nocapture(2); What matters for the plugin is the type of the passed arguments (which can be const char* in the current implementation), not that of the parameters. -- Emese
Re: [PATCH v1 2/2] Mark functions with the __nocapture attribute
On Tue, 28 Jun 2016 14:00:57 -0700 Joe Perches wrote: > On Tue, 2016-06-28 at 22:40 +0200, Emese Revfy wrote: > > On Tue, 28 Jun 2016 09:43:31 -0700 Joe Perches wrote: > > > On Tue, 2016-06-28 at 13:36 +0200, Emese Revfy wrote: > > > > The nocapture gcc attribute can be on functions only. > > > > The attribute takes one or more unsigned integer constants as parameters > > > > that specify the function argument(s) of const char* type to initify. > > > Perhaps this should be const * > > For me function arguments are the values passed to a function call so > > the const char* type is good because this is the only one that the plugin > > handles > > (for now at least). > > OK, but this function prototype specified takes a const void * > > +extern void * memcpy(void *, const void *, __kernel_size_t) __nocapture(2); What matters for the plugin is the type of the passed arguments (which can be const char* in the current implementation), not that of the parameters. -- Emese
Re: [PATCH v1 2/2] Mark functions with the __nocapture attribute
On Tue, 28 Jun 2016 22:50:55 +0200 Rasmus Villemoes <li...@rasmusvillemoes.dk> wrote: > On Tue, Jun 28 2016, Emese Revfy <re.em...@gmail.com> wrote: > > diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h > > index 6f96247..4cdf266 100644 > > --- a/include/asm-generic/bug.h > > +++ b/include/asm-generic/bug.h > > @@ -62,13 +62,13 @@ struct bug_entry { > > * to provide better diagnostics. > > */ > > #ifndef __WARN_TAINT > > -extern __printf(3, 4) > > +extern __printf(3, 4) __nocapture(1, 3, 4) > > void warn_slowpath_fmt(const char *file, const int line, > >const char *fmt, ...); > > -extern __printf(4, 5) > > +extern __printf(4, 5) __nocapture(1, 4, 5) > > void warn_slowpath_fmt_taint(const char *file, const int line, unsigned > > taint, > > const char *fmt, ...); > > The 3,4 and 4,5 parts seem redundant when __printf automatically supplies > those. Thanks, I'll fix them in the next patch set. -- Emese
Re: [PATCH v1 2/2] Mark functions with the __nocapture attribute
On Tue, 28 Jun 2016 22:50:55 +0200 Rasmus Villemoes wrote: > On Tue, Jun 28 2016, Emese Revfy wrote: > > diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h > > index 6f96247..4cdf266 100644 > > --- a/include/asm-generic/bug.h > > +++ b/include/asm-generic/bug.h > > @@ -62,13 +62,13 @@ struct bug_entry { > > * to provide better diagnostics. > > */ > > #ifndef __WARN_TAINT > > -extern __printf(3, 4) > > +extern __printf(3, 4) __nocapture(1, 3, 4) > > void warn_slowpath_fmt(const char *file, const int line, > >const char *fmt, ...); > > -extern __printf(4, 5) > > +extern __printf(4, 5) __nocapture(1, 4, 5) > > void warn_slowpath_fmt_taint(const char *file, const int line, unsigned > > taint, > > const char *fmt, ...); > > The 3,4 and 4,5 parts seem redundant when __printf automatically supplies > those. Thanks, I'll fix them in the next patch set. -- Emese
Re: [kernel-hardening] [PATCH v1 0/2] Introduce the initify gcc plugin
On Wed, 29 Jun 2016 18:52:27 +0100 Mark Rutland <mark.rutl...@arm.com> wrote: > On Wed, Jun 29, 2016 at 09:21:37AM +0100, Mark Rutland wrote: > > On Tue, Jun 28, 2016 at 01:46:04PM -0700, Kees Cook wrote: > > > On Tue, Jun 28, 2016 at 9:14 AM, Emese Revfy <re.em...@gmail.com> wrote: > > > > On Tue, 28 Jun 2016 13:57:49 +0100 > > > > Mark Rutland <mark.rutl...@arm.com> wrote: > > > > > > > >> On Tue, Jun 28, 2016 at 01:34:07PM +0200, Emese Revfy wrote: > > > >> > This patch set is based on the "Add support for complex gcc plugins > > > >> > that > > > >> > don't fit in a single file" patch set (git/kees/linux.git#kspp HEAD: > > > >> > e5d4798b284cd192c8b). > > > >> > > > >> I was hoping to give this a spin on arm/arm64, but I couldn't find the > > > >> prerequisite branch/tag/commit in that tree: > > > >> > > > >> https://git.kernel.org/cgit/linux/kernel/git/kees/linux.git/commit/?id=e5d4798b284cd192c8b > > > >> > > > >> Where should I be looking? > > > > > > > > Sorry, this commit was disappear. You can apply these patches to this > > > > tree: > > > > https://github.com/ephox-gcc-plugins/gcc-plugins_linux-next.git > > > > (initify branch) > > g++: fatal error: no input files > compilation terminated. > make[1]: *** [scripts/gcc-plugins/initify_plugin.so] Error 4 > make: *** [gcc-plugins] Error 2 Hi, There are some missing patches from Kees tree that's why I suggested my tree above. -- Emese
Re: [kernel-hardening] [PATCH v1 0/2] Introduce the initify gcc plugin
On Wed, 29 Jun 2016 18:52:27 +0100 Mark Rutland wrote: > On Wed, Jun 29, 2016 at 09:21:37AM +0100, Mark Rutland wrote: > > On Tue, Jun 28, 2016 at 01:46:04PM -0700, Kees Cook wrote: > > > On Tue, Jun 28, 2016 at 9:14 AM, Emese Revfy wrote: > > > > On Tue, 28 Jun 2016 13:57:49 +0100 > > > > Mark Rutland wrote: > > > > > > > >> On Tue, Jun 28, 2016 at 01:34:07PM +0200, Emese Revfy wrote: > > > >> > This patch set is based on the "Add support for complex gcc plugins > > > >> > that > > > >> > don't fit in a single file" patch set (git/kees/linux.git#kspp HEAD: > > > >> > e5d4798b284cd192c8b). > > > >> > > > >> I was hoping to give this a spin on arm/arm64, but I couldn't find the > > > >> prerequisite branch/tag/commit in that tree: > > > >> > > > >> https://git.kernel.org/cgit/linux/kernel/git/kees/linux.git/commit/?id=e5d4798b284cd192c8b > > > >> > > > >> Where should I be looking? > > > > > > > > Sorry, this commit was disappear. You can apply these patches to this > > > > tree: > > > > https://github.com/ephox-gcc-plugins/gcc-plugins_linux-next.git > > > > (initify branch) > > g++: fatal error: no input files > compilation terminated. > make[1]: *** [scripts/gcc-plugins/initify_plugin.so] Error 4 > make: *** [gcc-plugins] Error 2 Hi, There are some missing patches from Kees tree that's why I suggested my tree above. -- Emese
Re: [PATCH v1 2/2] Mark functions with the __nocapture attribute
On Tue, 28 Jun 2016 09:43:31 -0700 Joe Perches <j...@perches.com> wrote: > On Tue, 2016-06-28 at 13:36 +0200, Emese Revfy wrote: > > The nocapture gcc attribute can be on functions only. > > The attribute takes one or more unsigned integer constants as parameters > > that specify the function argument(s) of const char* type to initify. > > Perhaps this should be const * For me function arguments are the values passed to a function call so the const char* type is good because this is the only one that the plugin handles (for now at least). -- Emese
Re: [PATCH v1 2/2] Mark functions with the __nocapture attribute
On Tue, 28 Jun 2016 09:43:31 -0700 Joe Perches wrote: > On Tue, 2016-06-28 at 13:36 +0200, Emese Revfy wrote: > > The nocapture gcc attribute can be on functions only. > > The attribute takes one or more unsigned integer constants as parameters > > that specify the function argument(s) of const char* type to initify. > > Perhaps this should be const * For me function arguments are the values passed to a function call so the const char* type is good because this is the only one that the plugin handles (for now at least). -- Emese
Re: [PATCH v1 0/2] Introduce the initify gcc plugin
On Tue, 28 Jun 2016 21:02:54 +0200 Rasmus Villemoeswrote: > It'll get placed in multiple sections by the compiler, and nothing bad > happens. String deduplication is something the linker does to sections > equipped with appropriate flags. So in this case that of course means Note that I didn't add such flags to my sections yet, but I have it on my todo list. > that the kernel image itself would be slightly bigger, while the used > data after init would be the same. But I don't think there's a lot of > these cases. (Also, "initfunc" would at least vanish). -- Emese
Re: [PATCH v1 0/2] Introduce the initify gcc plugin
On Tue, 28 Jun 2016 21:02:54 +0200 Rasmus Villemoes wrote: > It'll get placed in multiple sections by the compiler, and nothing bad > happens. String deduplication is something the linker does to sections > equipped with appropriate flags. So in this case that of course means Note that I didn't add such flags to my sections yet, but I have it on my todo list. > that the kernel image itself would be slightly bigger, while the used > data after init would be the same. But I don't think there's a lot of > these cases. (Also, "initfunc" would at least vanish). -- Emese
Re: [PATCH v1 0/2] Introduce the initify gcc plugin
On Tue, 28 Jun 2016 19:00:22 +0200 Mathias Krausewrote: > > section vanilla vanilla + initifychange > > --- > > .rodata 39059688 (0x25400e8)38527210 (0x24be0ea)-532478 > > .data 45744128 (0x2ba)45404160 (0x2b4d000)-339968 > > .init.data 1361144 (0x14c4f8) 1674200 (0x198bd8)+313056 > > .text 77615128 (0x4a05018)77576664 (0x49fb9d8) -38464 > > .init.text 1108455 (0x10e9e7) 1137618 (0x115bd2) +29163 > > You should probably provide numbers for .init.rodata.str, .exit.rodata.str > and .exit.text as well. Otherwise this delta calculation suggests a rather > gigantic image size reduction which is probably not the case ;) init.rodata.str is an input section that merges into the INIT_DATA output section. I didn't make statistics for exit* yet because I have a problem with that (I asked for help in a previous e-mail). > Also a comparison of the final kernel image size would be nice to see if I no longer have the vmlinux images but I saved away the readelf outputs, here's the PT_LOAD size data: FileSiz (vanilla) FileSiz (vanilla+initify) change --- 00 119189504 (0x71ab000) 118657024 (0x7129000) -532480 01 45838336 (0x2bb7000)45498368 (0x2b64000) -339968 032830336 (0x2b3000) 3198976 (0x30d000) +368640 00 .text .text.exit .text.startup .notes __ex_table .rodata __bug_table .pci_fixup .builtin_fw .tracedata __ksymtab __ksymtab_gpl __ksymtab_strings __init_rodata __param __modver 01 .data .fini_array .vvar 03 .init.text .altinstr_aux .init.data .x86_cpu_dev.init .parainstructions .altinstructions .altinstr_replacement .iommu_table .apicdrivers .exit.text .exit.data .smp_locks .bss .brk I think the smaller .data section is wrong, so I'll look into it. -- Emese
Re: [PATCH v1 0/2] Introduce the initify gcc plugin
On Tue, 28 Jun 2016 19:00:22 +0200 Mathias Krause wrote: > > section vanilla vanilla + initifychange > > --- > > .rodata 39059688 (0x25400e8)38527210 (0x24be0ea)-532478 > > .data 45744128 (0x2ba)45404160 (0x2b4d000)-339968 > > .init.data 1361144 (0x14c4f8) 1674200 (0x198bd8)+313056 > > .text 77615128 (0x4a05018)77576664 (0x49fb9d8) -38464 > > .init.text 1108455 (0x10e9e7) 1137618 (0x115bd2) +29163 > > You should probably provide numbers for .init.rodata.str, .exit.rodata.str > and .exit.text as well. Otherwise this delta calculation suggests a rather > gigantic image size reduction which is probably not the case ;) init.rodata.str is an input section that merges into the INIT_DATA output section. I didn't make statistics for exit* yet because I have a problem with that (I asked for help in a previous e-mail). > Also a comparison of the final kernel image size would be nice to see if I no longer have the vmlinux images but I saved away the readelf outputs, here's the PT_LOAD size data: FileSiz (vanilla) FileSiz (vanilla+initify) change --- 00 119189504 (0x71ab000) 118657024 (0x7129000) -532480 01 45838336 (0x2bb7000)45498368 (0x2b64000) -339968 032830336 (0x2b3000) 3198976 (0x30d000) +368640 00 .text .text.exit .text.startup .notes __ex_table .rodata __bug_table .pci_fixup .builtin_fw .tracedata __ksymtab __ksymtab_gpl __ksymtab_strings __init_rodata __param __modver 01 .data .fini_array .vvar 03 .init.text .altinstr_aux .init.data .x86_cpu_dev.init .parainstructions .altinstructions .altinstr_replacement .iommu_table .apicdrivers .exit.text .exit.data .smp_locks .bss .brk I think the smaller .data section is wrong, so I'll look into it. -- Emese
Re: [kernel-hardening] [PATCH v1 0/2] Introduce the initify gcc plugin
On Tue, 28 Jun 2016 13:57:49 +0100 Mark Rutland <mark.rutl...@arm.com> wrote: > On Tue, Jun 28, 2016 at 01:34:07PM +0200, Emese Revfy wrote: > > This patch set is based on the "Add support for complex gcc plugins that > > don't fit in a single file" patch set (git/kees/linux.git#kspp HEAD: > > e5d4798b284cd192c8b). > > I was hoping to give this a spin on arm/arm64, but I couldn't find the > prerequisite branch/tag/commit in that tree: > > https://git.kernel.org/cgit/linux/kernel/git/kees/linux.git/commit/?id=e5d4798b284cd192c8b > > Where should I be looking? Sorry, this commit was disappear. You can apply these patches to this tree: https://github.com/ephox-gcc-plugins/gcc-plugins_linux-next.git (initify branch) -- Emese
Re: [kernel-hardening] [PATCH v1 0/2] Introduce the initify gcc plugin
On Tue, 28 Jun 2016 13:57:49 +0100 Mark Rutland wrote: > On Tue, Jun 28, 2016 at 01:34:07PM +0200, Emese Revfy wrote: > > This patch set is based on the "Add support for complex gcc plugins that > > don't fit in a single file" patch set (git/kees/linux.git#kspp HEAD: > > e5d4798b284cd192c8b). > > I was hoping to give this a spin on arm/arm64, but I couldn't find the > prerequisite branch/tag/commit in that tree: > > https://git.kernel.org/cgit/linux/kernel/git/kees/linux.git/commit/?id=e5d4798b284cd192c8b > > Where should I be looking? Sorry, this commit was disappear. You can apply these patches to this tree: https://github.com/ephox-gcc-plugins/gcc-plugins_linux-next.git (initify branch) -- Emese
Re: [PATCH v1 0/2] Introduce the initify gcc plugin
On Tue, 28 Jun 2016 13:34:07 +0200 Emese Revfy <re.em...@gmail.com> wrote: > * automatically discover init/exit functions and apply the __init or >__exit attributes on them Hi, I have a question about this. If a function is called by __init and __exit functions as well then I move it to the __exit section. I think this is correct because such a function is available to both __init and __exit functions as well at runtime. However this generates a section mismatch (from scripts/mod/modpost.c) e.g., WARNING: vmlinux.o(.init.text+0x196849): Section mismatch in reference from the function sctp_init() to the function .exit.text:sctp_v4_del_protocol() The function __init sctp_init() references a function __exit sctp_v4_del_protocol(). This is often seen when error handling in the init function uses functionality in the exit path. The fix is often to remove the __exit annotation of sctp_v4_del_protocol() so it may be used outside an exit section. This check was introduced by this commit (588ccd732ba2d): kbuild: add verbose option to Section mismatch reporting in modpost If this move doesn't cause a problem then I would like to keep it because there are a lot of functions that can become __exit and I would like to remove this warning. Thanks -- Emese
Re: [PATCH v1 0/2] Introduce the initify gcc plugin
On Tue, 28 Jun 2016 13:34:07 +0200 Emese Revfy wrote: > * automatically discover init/exit functions and apply the __init or >__exit attributes on them Hi, I have a question about this. If a function is called by __init and __exit functions as well then I move it to the __exit section. I think this is correct because such a function is available to both __init and __exit functions as well at runtime. However this generates a section mismatch (from scripts/mod/modpost.c) e.g., WARNING: vmlinux.o(.init.text+0x196849): Section mismatch in reference from the function sctp_init() to the function .exit.text:sctp_v4_del_protocol() The function __init sctp_init() references a function __exit sctp_v4_del_protocol(). This is often seen when error handling in the init function uses functionality in the exit path. The fix is often to remove the __exit annotation of sctp_v4_del_protocol() so it may be used outside an exit section. This check was introduced by this commit (588ccd732ba2d): kbuild: add verbose option to Section mismatch reporting in modpost If this move doesn't cause a problem then I would like to keep it because there are a lot of functions that can become __exit and I would like to remove this warning. Thanks -- Emese
[PATCH v1 2/2] Mark functions with the __nocapture attribute
The nocapture gcc attribute can be on functions only. The attribute takes one or more unsigned integer constants as parameters that specify the function argument(s) of const char* type to initify. If the marked argument is a vararg then the plugin initifies all vararg arguments. I couldn't test the arm, arm64 and powerpc architectures. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- arch/arm/include/asm/string.h | 10 +++--- arch/arm64/include/asm/string.h | 23 ++-- arch/powerpc/include/asm/string.h | 19 +- arch/x86/boot/string.h| 4 +-- arch/x86/include/asm/string_32.h | 21 +-- arch/x86/include/asm/string_64.h | 18 +- arch/x86/kernel/hpet.c| 2 +- include/asm-generic/bug.h | 6 ++-- include/linux/compiler-gcc.h | 10 -- include/linux/compiler.h | 4 +++ include/linux/fs.h| 5 +-- include/linux/printk.h| 2 +- include/linux/string.h| 73 --- 13 files changed, 107 insertions(+), 90 deletions(-) diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h index cf4f3aa..3f68273 100644 --- a/arch/arm/include/asm/string.h +++ b/arch/arm/include/asm/string.h @@ -7,19 +7,19 @@ */ #define __HAVE_ARCH_STRRCHR -extern char * strrchr(const char * s, int c); +extern char * strrchr(const char * s, int c) __nocapture(1); #define __HAVE_ARCH_STRCHR -extern char * strchr(const char * s, int c); +extern char * strchr(const char * s, int c) __nocapture(1); #define __HAVE_ARCH_MEMCPY -extern void * memcpy(void *, const void *, __kernel_size_t); +extern void * memcpy(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMMOVE -extern void * memmove(void *, const void *, __kernel_size_t); +extern void * memmove(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMCHR -extern void * memchr(const void *, int, __kernel_size_t); +extern void * memchr(const void *, int, __kernel_size_t) __nocapture(1); #define __HAVE_ARCH_MEMSET extern void * memset(void *, int, __kernel_size_t); diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h index 2eb714c..0b3662b 100644 --- a/arch/arm64/include/asm/string.h +++ b/arch/arm64/include/asm/string.h @@ -17,40 +17,41 @@ #define __ASM_STRING_H #define __HAVE_ARCH_STRRCHR -extern char *strrchr(const char *, int c); +extern char *strrchr(const char *, int c) __nocapture(1); #define __HAVE_ARCH_STRCHR -extern char *strchr(const char *, int c); +extern char *strchr(const char *, int c) __nocapture(1); #define __HAVE_ARCH_STRCMP -extern int strcmp(const char *, const char *); +extern int strcmp(const char *, const char *) __nocapture(1, 2); #define __HAVE_ARCH_STRNCMP -extern int strncmp(const char *, const char *, __kernel_size_t); +extern int +strncmp(const char *, const char *, __kernel_size_t) __nocapture(1, 2); #define __HAVE_ARCH_STRLEN extern __kernel_size_t strlen(const char *); #define __HAVE_ARCH_STRNLEN -extern __kernel_size_t strnlen(const char *, __kernel_size_t); +extern __kernel_size_t strnlen(const char *, __kernel_size_t) __nocapture(1); #define __HAVE_ARCH_MEMCPY -extern void *memcpy(void *, const void *, __kernel_size_t); -extern void *__memcpy(void *, const void *, __kernel_size_t); +extern void *memcpy(void *, const void *, __kernel_size_t) __nocapture(2); +extern void *__memcpy(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMMOVE -extern void *memmove(void *, const void *, __kernel_size_t); -extern void *__memmove(void *, const void *, __kernel_size_t); +extern void *memmove(void *, const void *, __kernel_size_t) __nocapture(2); +extern void *__memmove(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMCHR -extern void *memchr(const void *, int, __kernel_size_t); +extern void *memchr(const void *, int, __kernel_size_t) __nocapture(1); #define __HAVE_ARCH_MEMSET extern void *memset(void *, int, __kernel_size_t); extern void *__memset(void *, int, __kernel_size_t); #define __HAVE_ARCH_MEMCMP -extern int memcmp(const void *, const void *, size_t); +extern int memcmp(const void *, const void *, size_t) __nocapture(1, 2); #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h index e40010a..b29fc74 100644 --- a/arch/powerpc/include/asm/string.h +++ b/arch/powerpc/include/asm/string.h @@ -15,17 +15,18 @@ #define __HAVE_ARCH_MEMCMP #define __HAVE_ARCH_MEMCHR -extern char * strcpy(char *,const char *); -extern char * strncpy(char *,const char *, __kernel_size_t); +extern char * strcpy(char *,const char *) __nocapture(2); +extern char * strncpy(char *,const char *, __kernel_size_t) __nocapture(2); extern __kernel_size_t strlen(const char *); -extern int strcmp(const char *,const char *); -exte
[PATCH v1 1/2] Add the initify gcc plugin
The kernel already has a mechanism to free up code and data memory that is only used during kernel or module initialization. This plugin will teach the compiler to find more such code and data that can be freed after initialization. It has two passes. The first one tries to find all functions that can be become __init/__exit. The second one moves string constants (local variables and function string arguments marked by the nocapture attribute) only referenced in __init/__exit functions to the __initconst/__exitconst sections. It reduces memory usage. This plugin can be useful for embedded systems. The instrumentation pass of the latent_entropy plugin must run after the initify plugin to increase coverage. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- arch/Kconfig | 23 + include/asm-generic/vmlinux.lds.h|2 + scripts/Makefile.gcc-plugins |4 + scripts/gcc-plugins/initify_plugin.c | 1147 ++ 4 files changed, 1176 insertions(+) create mode 100644 scripts/gcc-plugins/initify_plugin.c diff --git a/arch/Kconfig b/arch/Kconfig index 9f8c6ee..35b01a4 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -417,6 +417,29 @@ config GCC_PLUGIN_LATENT_ENTROPY * https://grsecurity.net/ * https://pax.grsecurity.net/ +config GCC_PLUGIN_INITIFY + bool "Free more kernel memory after init" + depends on GCC_PLUGINS + help + The kernel has a mechanism to free up code and data memory that is + only used during kernel or module initialization. Enabling this + feature will teach the compiler to find more such code and data + that can be freed after initialization. + + This plugin is the part of grsecurity/PaX. More information at: + * https://grsecurity.net/ + * https://pax.grsecurity.net/ + +config GCC_PLUGIN_INITIFY_VERBOSE + bool "Verbose" + depends on GCC_PLUGIN_INITIFY + help + Print all initified strings and all functions which should be + __init/__exit. + Note that the candidates identified for __init/__exit markings + depend on the current kernel configuration and thus should be verified + manually before the source code is patched. + config HAVE_CC_STACKPROTECTOR bool help diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 6a67ab9..651980b 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -523,6 +523,7 @@ MEM_DISCARD(init.data) \ KERNEL_CTORS() \ MCOUNT_REC()\ + *(.init.rodata.str) \ *(.init.rodata) \ FTRACE_EVENTS() \ TRACE_SYSCALLS()\ @@ -547,6 +548,7 @@ #define EXIT_DATA \ *(.exit.data) \ MEM_DISCARD(exit.data) \ + *(.exit.rodata.str) \ MEM_DISCARD(exit.rodata) #define EXIT_TEXT \ diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 1f922df..0ce8392 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -12,6 +12,10 @@ ifdef CONFIG_GCC_PLUGINS DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable endif + gcc-plugin-$(CONFIG_GCC_PLUGIN_INITIFY) += initify_plugin.so + gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_INITIFY) += -DINITIFY_PLUGIN -fplugin-arg-initify_plugin-search_init_exit_functions + gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_INITIFY_VERBOSE)+= -fplugin-arg-initify_plugin-verbose + ifdef CONFIG_GCC_PLUGIN_SANCOV ifeq ($(CFLAGS_KCOV),) # It is needed because of the gcc-plugin.sh and gcc version checks. diff --git a/scripts/gcc-plugins/initify_plugin.c b/scripts/gcc-plugins/initify_plugin.c new file mode 100644 index 000..d5dfce5 --- /dev/null +++ b/scripts/gcc-plugins/initify_plugin.c @@ -0,0 +1,1147 @@ +/* + * Copyright 2015-2016 by Emese Revfy <re.em...@gmail.com> + * Licensed under the GPL v2 + * + * Homepage: + * https://github.com/ephox-gcc-plugins/initify + * + * This plugin has two passes. The first one tries to find all functions that + * can be become __init/__exit. The second one moves string constants + * (local variables and function string arguments marked by + * the nocapture attribute) only referenced in __init/__exit functions + * to __initconst
[PATCH v1 2/2] Mark functions with the __nocapture attribute
The nocapture gcc attribute can be on functions only. The attribute takes one or more unsigned integer constants as parameters that specify the function argument(s) of const char* type to initify. If the marked argument is a vararg then the plugin initifies all vararg arguments. I couldn't test the arm, arm64 and powerpc architectures. Signed-off-by: Emese Revfy --- arch/arm/include/asm/string.h | 10 +++--- arch/arm64/include/asm/string.h | 23 ++-- arch/powerpc/include/asm/string.h | 19 +- arch/x86/boot/string.h| 4 +-- arch/x86/include/asm/string_32.h | 21 +-- arch/x86/include/asm/string_64.h | 18 +- arch/x86/kernel/hpet.c| 2 +- include/asm-generic/bug.h | 6 ++-- include/linux/compiler-gcc.h | 10 -- include/linux/compiler.h | 4 +++ include/linux/fs.h| 5 +-- include/linux/printk.h| 2 +- include/linux/string.h| 73 --- 13 files changed, 107 insertions(+), 90 deletions(-) diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h index cf4f3aa..3f68273 100644 --- a/arch/arm/include/asm/string.h +++ b/arch/arm/include/asm/string.h @@ -7,19 +7,19 @@ */ #define __HAVE_ARCH_STRRCHR -extern char * strrchr(const char * s, int c); +extern char * strrchr(const char * s, int c) __nocapture(1); #define __HAVE_ARCH_STRCHR -extern char * strchr(const char * s, int c); +extern char * strchr(const char * s, int c) __nocapture(1); #define __HAVE_ARCH_MEMCPY -extern void * memcpy(void *, const void *, __kernel_size_t); +extern void * memcpy(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMMOVE -extern void * memmove(void *, const void *, __kernel_size_t); +extern void * memmove(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMCHR -extern void * memchr(const void *, int, __kernel_size_t); +extern void * memchr(const void *, int, __kernel_size_t) __nocapture(1); #define __HAVE_ARCH_MEMSET extern void * memset(void *, int, __kernel_size_t); diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h index 2eb714c..0b3662b 100644 --- a/arch/arm64/include/asm/string.h +++ b/arch/arm64/include/asm/string.h @@ -17,40 +17,41 @@ #define __ASM_STRING_H #define __HAVE_ARCH_STRRCHR -extern char *strrchr(const char *, int c); +extern char *strrchr(const char *, int c) __nocapture(1); #define __HAVE_ARCH_STRCHR -extern char *strchr(const char *, int c); +extern char *strchr(const char *, int c) __nocapture(1); #define __HAVE_ARCH_STRCMP -extern int strcmp(const char *, const char *); +extern int strcmp(const char *, const char *) __nocapture(1, 2); #define __HAVE_ARCH_STRNCMP -extern int strncmp(const char *, const char *, __kernel_size_t); +extern int +strncmp(const char *, const char *, __kernel_size_t) __nocapture(1, 2); #define __HAVE_ARCH_STRLEN extern __kernel_size_t strlen(const char *); #define __HAVE_ARCH_STRNLEN -extern __kernel_size_t strnlen(const char *, __kernel_size_t); +extern __kernel_size_t strnlen(const char *, __kernel_size_t) __nocapture(1); #define __HAVE_ARCH_MEMCPY -extern void *memcpy(void *, const void *, __kernel_size_t); -extern void *__memcpy(void *, const void *, __kernel_size_t); +extern void *memcpy(void *, const void *, __kernel_size_t) __nocapture(2); +extern void *__memcpy(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMMOVE -extern void *memmove(void *, const void *, __kernel_size_t); -extern void *__memmove(void *, const void *, __kernel_size_t); +extern void *memmove(void *, const void *, __kernel_size_t) __nocapture(2); +extern void *__memmove(void *, const void *, __kernel_size_t) __nocapture(2); #define __HAVE_ARCH_MEMCHR -extern void *memchr(const void *, int, __kernel_size_t); +extern void *memchr(const void *, int, __kernel_size_t) __nocapture(1); #define __HAVE_ARCH_MEMSET extern void *memset(void *, int, __kernel_size_t); extern void *__memset(void *, int, __kernel_size_t); #define __HAVE_ARCH_MEMCMP -extern int memcmp(const void *, const void *, size_t); +extern int memcmp(const void *, const void *, size_t) __nocapture(1, 2); #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h index e40010a..b29fc74 100644 --- a/arch/powerpc/include/asm/string.h +++ b/arch/powerpc/include/asm/string.h @@ -15,17 +15,18 @@ #define __HAVE_ARCH_MEMCMP #define __HAVE_ARCH_MEMCHR -extern char * strcpy(char *,const char *); -extern char * strncpy(char *,const char *, __kernel_size_t); +extern char * strcpy(char *,const char *) __nocapture(2); +extern char * strncpy(char *,const char *, __kernel_size_t) __nocapture(2); extern __kernel_size_t strlen(const char *); -extern int strcmp(const char *,const char *); -extern int strncmp(const char
[PATCH v1 1/2] Add the initify gcc plugin
The kernel already has a mechanism to free up code and data memory that is only used during kernel or module initialization. This plugin will teach the compiler to find more such code and data that can be freed after initialization. It has two passes. The first one tries to find all functions that can be become __init/__exit. The second one moves string constants (local variables and function string arguments marked by the nocapture attribute) only referenced in __init/__exit functions to the __initconst/__exitconst sections. It reduces memory usage. This plugin can be useful for embedded systems. The instrumentation pass of the latent_entropy plugin must run after the initify plugin to increase coverage. Signed-off-by: Emese Revfy --- arch/Kconfig | 23 + include/asm-generic/vmlinux.lds.h|2 + scripts/Makefile.gcc-plugins |4 + scripts/gcc-plugins/initify_plugin.c | 1147 ++ 4 files changed, 1176 insertions(+) create mode 100644 scripts/gcc-plugins/initify_plugin.c diff --git a/arch/Kconfig b/arch/Kconfig index 9f8c6ee..35b01a4 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -417,6 +417,29 @@ config GCC_PLUGIN_LATENT_ENTROPY * https://grsecurity.net/ * https://pax.grsecurity.net/ +config GCC_PLUGIN_INITIFY + bool "Free more kernel memory after init" + depends on GCC_PLUGINS + help + The kernel has a mechanism to free up code and data memory that is + only used during kernel or module initialization. Enabling this + feature will teach the compiler to find more such code and data + that can be freed after initialization. + + This plugin is the part of grsecurity/PaX. More information at: + * https://grsecurity.net/ + * https://pax.grsecurity.net/ + +config GCC_PLUGIN_INITIFY_VERBOSE + bool "Verbose" + depends on GCC_PLUGIN_INITIFY + help + Print all initified strings and all functions which should be + __init/__exit. + Note that the candidates identified for __init/__exit markings + depend on the current kernel configuration and thus should be verified + manually before the source code is patched. + config HAVE_CC_STACKPROTECTOR bool help diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 6a67ab9..651980b 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -523,6 +523,7 @@ MEM_DISCARD(init.data) \ KERNEL_CTORS() \ MCOUNT_REC()\ + *(.init.rodata.str) \ *(.init.rodata) \ FTRACE_EVENTS() \ TRACE_SYSCALLS()\ @@ -547,6 +548,7 @@ #define EXIT_DATA \ *(.exit.data) \ MEM_DISCARD(exit.data) \ + *(.exit.rodata.str) \ MEM_DISCARD(exit.rodata) #define EXIT_TEXT \ diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 1f922df..0ce8392 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -12,6 +12,10 @@ ifdef CONFIG_GCC_PLUGINS DISABLE_LATENT_ENTROPY_PLUGIN += -fplugin-arg-latent_entropy_plugin-disable endif + gcc-plugin-$(CONFIG_GCC_PLUGIN_INITIFY) += initify_plugin.so + gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_INITIFY) += -DINITIFY_PLUGIN -fplugin-arg-initify_plugin-search_init_exit_functions + gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_INITIFY_VERBOSE)+= -fplugin-arg-initify_plugin-verbose + ifdef CONFIG_GCC_PLUGIN_SANCOV ifeq ($(CFLAGS_KCOV),) # It is needed because of the gcc-plugin.sh and gcc version checks. diff --git a/scripts/gcc-plugins/initify_plugin.c b/scripts/gcc-plugins/initify_plugin.c new file mode 100644 index 000..d5dfce5 --- /dev/null +++ b/scripts/gcc-plugins/initify_plugin.c @@ -0,0 +1,1147 @@ +/* + * Copyright 2015-2016 by Emese Revfy + * Licensed under the GPL v2 + * + * Homepage: + * https://github.com/ephox-gcc-plugins/initify + * + * This plugin has two passes. The first one tries to find all functions that + * can be become __init/__exit. The second one moves string constants + * (local variables and function string arguments marked by + * the nocapture attribute) only referenced in __init/__exit functions + * to __initconst/__exitconst sections. + * Based on an idea
[PATCH v1 0/2] Introduce the initify gcc plugin
I would like to introduce the initify gcc plugin. The kernel already has a mechanism to free up code and data memory that is only used during kernel or module initialization. This plugin will teach the compiler to find more such code and data that can be freed after initialization. It reduces memory usage. The initify gcc plugin can be useful for embedded systems. It is a CII project supported by the Linux Foundation. This plugin is the part of grsecurity/PaX. The plugin supports all gcc versions from 4.5 to 6.0. I made some changes on top of the PaX version (since March 6.). These are the important ones: * move all local strings to init.rodata.str and exit.rodata.str (not just __func__) * report all initified strings and functions (GCC_PLUGIN_INITIFY_VERBOSE config option) * automatically discover init/exit functions and apply the __init or __exit attributes on them You can find more about the changes here: https://github.com/ephox-gcc-plugins/initify This patch set is based on the "Add support for complex gcc plugins that don't fit in a single file" patch set (git/kees/linux.git#kspp HEAD: e5d4798b284cd192c8b). Some statistics about the plugin: On allyes config (amd64, gcc-6): * 7731 initified strings * 231 initified functions On allmod config (i386, gcc-6): * 8846 initified strings * 252 initified functions On allyes config (amd64, gcc-6): section vanilla vanilla + initifychange --- .rodata 39059688 (0x25400e8)38527210 (0x24be0ea)-532478 .data 45744128 (0x2ba)45404160 (0x2b4d000)-339968 .init.data 1361144 (0x14c4f8) 1674200 (0x198bd8)+313056 .text 77615128 (0x4a05018)77576664 (0x49fb9d8) -38464 .init.text 1108455 (0x10e9e7) 1137618 (0x115bd2) +29163 Emese Revfy (2): Add the initify gcc plugin Mark functions with the __nocapture attribute --- arch/Kconfig | 23 + arch/arm/include/asm/string.h| 10 +- arch/arm64/include/asm/string.h | 23 +- arch/powerpc/include/asm/string.h| 19 +- arch/x86/boot/string.h |4 +- arch/x86/include/asm/string_32.h | 21 +- arch/x86/include/asm/string_64.h | 18 +- arch/x86/kernel/hpet.c |2 +- include/asm-generic/bug.h|6 +- include/asm-generic/vmlinux.lds.h|2 + include/linux/compiler-gcc.h | 10 +- include/linux/compiler.h |4 + include/linux/fs.h |5 +- include/linux/printk.h |2 +- include/linux/string.h | 73 +-- scripts/Makefile.gcc-plugins |4 + scripts/gcc-plugins/initify_plugin.c | 1147 ++ 17 files changed, 1283 insertions(+), 90 deletions(-)
[PATCH v1 0/2] Introduce the initify gcc plugin
I would like to introduce the initify gcc plugin. The kernel already has a mechanism to free up code and data memory that is only used during kernel or module initialization. This plugin will teach the compiler to find more such code and data that can be freed after initialization. It reduces memory usage. The initify gcc plugin can be useful for embedded systems. It is a CII project supported by the Linux Foundation. This plugin is the part of grsecurity/PaX. The plugin supports all gcc versions from 4.5 to 6.0. I made some changes on top of the PaX version (since March 6.). These are the important ones: * move all local strings to init.rodata.str and exit.rodata.str (not just __func__) * report all initified strings and functions (GCC_PLUGIN_INITIFY_VERBOSE config option) * automatically discover init/exit functions and apply the __init or __exit attributes on them You can find more about the changes here: https://github.com/ephox-gcc-plugins/initify This patch set is based on the "Add support for complex gcc plugins that don't fit in a single file" patch set (git/kees/linux.git#kspp HEAD: e5d4798b284cd192c8b). Some statistics about the plugin: On allyes config (amd64, gcc-6): * 7731 initified strings * 231 initified functions On allmod config (i386, gcc-6): * 8846 initified strings * 252 initified functions On allyes config (amd64, gcc-6): section vanilla vanilla + initifychange --- .rodata 39059688 (0x25400e8)38527210 (0x24be0ea)-532478 .data 45744128 (0x2ba)45404160 (0x2b4d000)-339968 .init.data 1361144 (0x14c4f8) 1674200 (0x198bd8)+313056 .text 77615128 (0x4a05018)77576664 (0x49fb9d8) -38464 .init.text 1108455 (0x10e9e7) 1137618 (0x115bd2) +29163 Emese Revfy (2): Add the initify gcc plugin Mark functions with the __nocapture attribute --- arch/Kconfig | 23 + arch/arm/include/asm/string.h| 10 +- arch/arm64/include/asm/string.h | 23 +- arch/powerpc/include/asm/string.h| 19 +- arch/x86/boot/string.h |4 +- arch/x86/include/asm/string_32.h | 21 +- arch/x86/include/asm/string_64.h | 18 +- arch/x86/kernel/hpet.c |2 +- include/asm-generic/bug.h|6 +- include/asm-generic/vmlinux.lds.h|2 + include/linux/compiler-gcc.h | 10 +- include/linux/compiler.h |4 + include/linux/fs.h |5 +- include/linux/printk.h |2 +- include/linux/string.h | 73 +-- scripts/Makefile.gcc-plugins |4 + scripts/gcc-plugins/initify_plugin.c | 1147 ++ 17 files changed, 1283 insertions(+), 90 deletions(-)
[PATCH v4 4/4] Add the extra_latent_entropy kernel parameter
When extra_latent_entropy is passed on the kernel command line, entropy will be extracted from up to the first 4GB of RAM while the runtime memory allocator is being initialized. Based on work created by the PaX Team. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- Documentation/kernel-parameters.txt | 5 + arch/Kconfig| 5 + mm/page_alloc.c | 26 ++ 3 files changed, 36 insertions(+) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 82b42c9..d870702 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2862,6 +2862,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. the specified number of seconds. This is to be used if your oopses keep scrolling off the screen. + extra_latent_entropy + Enable a very simple form of latent entropy extraction + from the first 4GB of memory as the bootmem allocator + passes the memory pages to the buddy allocator. + pcbit= [HW,ISDN] pcd.[PARIDE] diff --git a/arch/Kconfig b/arch/Kconfig index 4b7cc2f..3374d50 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -404,6 +404,11 @@ config GCC_PLUGIN_LATENT_ENTROPY is some slowdown of the boot process (about 0.5%) and fork and irq processing. + When extra_latent_entropy is passed on the kernel command line, + entropy will be extracted from up to the first 4GB of RAM while the + runtime memory allocator is being initialized. This costs even more + slowdown of the boot process. + Note that entropy extracted this way is not cryptographically secure! diff --git a/mm/page_alloc.c b/mm/page_alloc.c index ffc4f4a..0a40c12 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include @@ -1234,6 +1235,15 @@ static void __free_pages_ok(struct page *page, unsigned int order) local_irq_restore(flags); } +bool __meminitdata extra_latent_entropy; + +static int __init setup_extra_latent_entropy(char *str) +{ + extra_latent_entropy = true; + return 0; +} +early_param("extra_latent_entropy", setup_extra_latent_entropy); + #ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY volatile u64 latent_entropy __latent_entropy; EXPORT_SYMBOL(latent_entropy); @@ -1254,6 +1264,22 @@ static void __init __free_pages_boot_core(struct page *page, unsigned int order) __ClearPageReserved(p); set_page_count(p, 0); + if (extra_latent_entropy && !PageHighMem(page) && + page_to_pfn(page) < 0x10) { + u64 hash = 0; + size_t index, end = PAGE_SIZE * nr_pages / sizeof(hash); + const u64 *data = lowmem_page_address(page); + + for (index = 0; index < end; index++) + hash ^= hash + data[index]; +#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY + latent_entropy ^= hash; + add_device_randomness((const void *)_entropy, sizeof(latent_entropy)); +#else + add_device_randomness((const void *), sizeof(hash)); +#endif + } + page_zone(page)->managed_pages += nr_pages; set_page_refcounted(page); __free_pages(page, order); -- 2.8.1
[PATCH v4 4/4] Add the extra_latent_entropy kernel parameter
When extra_latent_entropy is passed on the kernel command line, entropy will be extracted from up to the first 4GB of RAM while the runtime memory allocator is being initialized. Based on work created by the PaX Team. Signed-off-by: Emese Revfy --- Documentation/kernel-parameters.txt | 5 + arch/Kconfig| 5 + mm/page_alloc.c | 26 ++ 3 files changed, 36 insertions(+) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 82b42c9..d870702 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2862,6 +2862,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted. the specified number of seconds. This is to be used if your oopses keep scrolling off the screen. + extra_latent_entropy + Enable a very simple form of latent entropy extraction + from the first 4GB of memory as the bootmem allocator + passes the memory pages to the buddy allocator. + pcbit= [HW,ISDN] pcd.[PARIDE] diff --git a/arch/Kconfig b/arch/Kconfig index 4b7cc2f..3374d50 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -404,6 +404,11 @@ config GCC_PLUGIN_LATENT_ENTROPY is some slowdown of the boot process (about 0.5%) and fork and irq processing. + When extra_latent_entropy is passed on the kernel command line, + entropy will be extracted from up to the first 4GB of RAM while the + runtime memory allocator is being initialized. This costs even more + slowdown of the boot process. + Note that entropy extracted this way is not cryptographically secure! diff --git a/mm/page_alloc.c b/mm/page_alloc.c index ffc4f4a..0a40c12 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -63,6 +63,7 @@ #include #include #include +#include #include #include @@ -1234,6 +1235,15 @@ static void __free_pages_ok(struct page *page, unsigned int order) local_irq_restore(flags); } +bool __meminitdata extra_latent_entropy; + +static int __init setup_extra_latent_entropy(char *str) +{ + extra_latent_entropy = true; + return 0; +} +early_param("extra_latent_entropy", setup_extra_latent_entropy); + #ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY volatile u64 latent_entropy __latent_entropy; EXPORT_SYMBOL(latent_entropy); @@ -1254,6 +1264,22 @@ static void __init __free_pages_boot_core(struct page *page, unsigned int order) __ClearPageReserved(p); set_page_count(p, 0); + if (extra_latent_entropy && !PageHighMem(page) && + page_to_pfn(page) < 0x10) { + u64 hash = 0; + size_t index, end = PAGE_SIZE * nr_pages / sizeof(hash); + const u64 *data = lowmem_page_address(page); + + for (index = 0; index < end; index++) + hash ^= hash + data[index]; +#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY + latent_entropy ^= hash; + add_device_randomness((const void *)_entropy, sizeof(latent_entropy)); +#else + add_device_randomness((const void *), sizeof(hash)); +#endif + } + page_zone(page)->managed_pages += nr_pages; set_page_refcounted(page); __free_pages(page, order); -- 2.8.1
[PATCH v4 3/4] Mark functions with the latent_entropy attribute
The latent_entropy gcc attribute can be only on functions and variables. If it is on a function then the plugin will instrument it. If the attribute is on a variable then the plugin will initialize it with a random value. The variable must be an integer, an integer array type or a structure with integer fields. These functions have been selected because they are init functions or are called at random times or they have variable loops. Signed-off-by: Emese Revfy <re.em...@gmail.com> --- block/blk-softirq.c | 2 +- drivers/char/random.c| 6 +++--- fs/namespace.c | 1 + include/linux/compiler-gcc.h | 7 +++ include/linux/compiler.h | 4 include/linux/fdtable.h | 2 +- include/linux/genhd.h| 2 +- include/linux/init.h | 5 +++-- include/linux/random.h | 4 ++-- kernel/fork.c| 6 -- kernel/rcu/tiny.c| 2 +- kernel/rcu/tree.c| 2 +- kernel/sched/fair.c | 2 +- kernel/softirq.c | 4 ++-- kernel/time/timer.c | 2 +- lib/irq_poll.c | 2 +- lib/random32.c | 2 +- mm/page_alloc.c | 2 +- net/core/dev.c | 4 ++-- 19 files changed, 38 insertions(+), 23 deletions(-) diff --git a/block/blk-softirq.c b/block/blk-softirq.c index 53b1737..489eab8 100644 --- a/block/blk-softirq.c +++ b/block/blk-softirq.c @@ -18,7 +18,7 @@ static DEFINE_PER_CPU(struct list_head, blk_cpu_done); * Softirq action handler - move entries to local list and loop over them * while passing them to the queue registered handler. */ -static void blk_done_softirq(struct softirq_action *h) +static __latent_entropy void blk_done_softirq(struct softirq_action *h) { struct list_head *cpu_list, local_list; diff --git a/drivers/char/random.c b/drivers/char/random.c index 0158d3b..6cca3ed 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -443,9 +443,9 @@ struct entropy_store { }; static void push_to_pool(struct work_struct *work); -static __u32 input_pool_data[INPUT_POOL_WORDS]; -static __u32 blocking_pool_data[OUTPUT_POOL_WORDS]; -static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS]; +static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy; +static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy; +static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy; static struct entropy_store input_pool = { .poolinfo = _table[0], diff --git a/fs/namespace.c b/fs/namespace.c index 4fb1691..0951eca 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2778,6 +2778,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) return new_ns; } +__latent_entropy struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, struct user_namespace *user_ns, struct fs_struct *new_fs) { diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index e294939..0ef8329 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -188,6 +188,13 @@ #endif /* GCC_VERSION >= 40300 */ #if GCC_VERSION >= 40500 + +#ifndef __CHECKER__ +#ifdef LATENT_ENTROPY_PLUGIN +#define __latent_entropy __attribute__((latent_entropy)) +#endif +#endif + /* * Mark a position in code as unreachable. This can be used to * suppress control flow warnings after asm blocks that transfer diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 793c082..c65327b 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -425,6 +425,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s # define __attribute_const__ /* unimplemented */ #endif +#ifndef __latent_entropy +# define __latent_entropy +#endif + /* * Tell gcc if a function is cold. The compiler will assume any path * directly leading to the call is unlikely. diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index 5295535..9852c7e 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h @@ -105,7 +105,7 @@ struct files_struct *get_files_struct(struct task_struct *); void put_files_struct(struct files_struct *fs); void reset_files_struct(struct files_struct *); int unshare_files(struct files_struct **); -struct files_struct *dup_fd(struct files_struct *, int *); +struct files_struct *dup_fd(struct files_struct *, int *) __latent_entropy; void do_close_on_exec(struct files_struct *); int iterate_fd(struct files_struct *, unsigned, int (*)(const void *, struct file *, unsigned), diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 359a8e4..8736c1f 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -433,7 +433,7 @@ extern void disk_flush_events(struct gendisk *disk, unsigned int mask); extern unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask); /* drivers/char/random.c */ -extern void add_dis
[PATCH v4 3/4] Mark functions with the latent_entropy attribute
The latent_entropy gcc attribute can be only on functions and variables. If it is on a function then the plugin will instrument it. If the attribute is on a variable then the plugin will initialize it with a random value. The variable must be an integer, an integer array type or a structure with integer fields. These functions have been selected because they are init functions or are called at random times or they have variable loops. Signed-off-by: Emese Revfy --- block/blk-softirq.c | 2 +- drivers/char/random.c| 6 +++--- fs/namespace.c | 1 + include/linux/compiler-gcc.h | 7 +++ include/linux/compiler.h | 4 include/linux/fdtable.h | 2 +- include/linux/genhd.h| 2 +- include/linux/init.h | 5 +++-- include/linux/random.h | 4 ++-- kernel/fork.c| 6 -- kernel/rcu/tiny.c| 2 +- kernel/rcu/tree.c| 2 +- kernel/sched/fair.c | 2 +- kernel/softirq.c | 4 ++-- kernel/time/timer.c | 2 +- lib/irq_poll.c | 2 +- lib/random32.c | 2 +- mm/page_alloc.c | 2 +- net/core/dev.c | 4 ++-- 19 files changed, 38 insertions(+), 23 deletions(-) diff --git a/block/blk-softirq.c b/block/blk-softirq.c index 53b1737..489eab8 100644 --- a/block/blk-softirq.c +++ b/block/blk-softirq.c @@ -18,7 +18,7 @@ static DEFINE_PER_CPU(struct list_head, blk_cpu_done); * Softirq action handler - move entries to local list and loop over them * while passing them to the queue registered handler. */ -static void blk_done_softirq(struct softirq_action *h) +static __latent_entropy void blk_done_softirq(struct softirq_action *h) { struct list_head *cpu_list, local_list; diff --git a/drivers/char/random.c b/drivers/char/random.c index 0158d3b..6cca3ed 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -443,9 +443,9 @@ struct entropy_store { }; static void push_to_pool(struct work_struct *work); -static __u32 input_pool_data[INPUT_POOL_WORDS]; -static __u32 blocking_pool_data[OUTPUT_POOL_WORDS]; -static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS]; +static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy; +static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy; +static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy; static struct entropy_store input_pool = { .poolinfo = _table[0], diff --git a/fs/namespace.c b/fs/namespace.c index 4fb1691..0951eca 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2778,6 +2778,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) return new_ns; } +__latent_entropy struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, struct user_namespace *user_ns, struct fs_struct *new_fs) { diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index e294939..0ef8329 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -188,6 +188,13 @@ #endif /* GCC_VERSION >= 40300 */ #if GCC_VERSION >= 40500 + +#ifndef __CHECKER__ +#ifdef LATENT_ENTROPY_PLUGIN +#define __latent_entropy __attribute__((latent_entropy)) +#endif +#endif + /* * Mark a position in code as unreachable. This can be used to * suppress control flow warnings after asm blocks that transfer diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 793c082..c65327b 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -425,6 +425,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s # define __attribute_const__ /* unimplemented */ #endif +#ifndef __latent_entropy +# define __latent_entropy +#endif + /* * Tell gcc if a function is cold. The compiler will assume any path * directly leading to the call is unlikely. diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index 5295535..9852c7e 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h @@ -105,7 +105,7 @@ struct files_struct *get_files_struct(struct task_struct *); void put_files_struct(struct files_struct *fs); void reset_files_struct(struct files_struct *); int unshare_files(struct files_struct **); -struct files_struct *dup_fd(struct files_struct *, int *); +struct files_struct *dup_fd(struct files_struct *, int *) __latent_entropy; void do_close_on_exec(struct files_struct *); int iterate_fd(struct files_struct *, unsigned, int (*)(const void *, struct file *, unsigned), diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 359a8e4..8736c1f 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -433,7 +433,7 @@ extern void disk_flush_events(struct gendisk *disk, unsigned int mask); extern unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask); /* drivers/char/random.c */ -extern void add_disk_randomness(struct gendisk
[PATCH v4 2/4] Add the latent_entropy gcc plugin
This plugin mitigates the problem of the kernel having too little entropy during and after boot for generating crypto keys. It creates a local variable in every marked function. The value of this variable is modified by randomly chosen operations (add, xor and rol) and random values (gcc generates them at compile time and the stack pointer at runtime). It depends on the control flow (e.g., loops, conditions). Before the function returns the plugin writes this local variable into the latent_entropy global variable. The value of this global variable is added to the kernel entropy pool in do_one_initcall() and _do_fork(). Signed-off-by: Emese Revfy <re.em...@gmail.com> --- arch/Kconfig| 18 + arch/powerpc/kernel/Makefile| 4 + include/linux/random.h | 10 + init/main.c | 1 + kernel/fork.c | 1 + mm/page_alloc.c | 5 + scripts/Makefile.gcc-plugins| 8 +- scripts/gcc-plugins/Makefile| 1 + scripts/gcc-plugins/latent_entropy_plugin.c | 639 9 files changed, 686 insertions(+), 1 deletion(-) create mode 100644 scripts/gcc-plugins/latent_entropy_plugin.c diff --git a/arch/Kconfig b/arch/Kconfig index 05f1e95..4b7cc2f 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -393,6 +393,24 @@ config GCC_PLUGIN_SANCOV gcc-4.5 on). It is based on the commit "Add fuzzing coverage support" by Dmitry Vyukov <dvyu...@google.com>. +config GCC_PLUGIN_LATENT_ENTROPY + bool "Generate some entropy during boot and runtime" + depends on GCC_PLUGINS + help + By saying Y here the kernel will instrument some kernel code to + extract some entropy from both original and artificially created + program state. This will help especially embedded systems where + there is little 'natural' source of entropy normally. The cost + is some slowdown of the boot process (about 0.5%) and fork and + irq processing. + + Note that entropy extracted this way is not cryptographically + secure! + + This plugin was ported from grsecurity/PaX. More information at: + * https://grsecurity.net/ + * https://pax.grsecurity.net/ + config HAVE_CC_STACKPROTECTOR bool help diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 2da380f..01935b8 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -15,6 +15,10 @@ CFLAGS_btext.o += -fPIC endif ifdef CONFIG_FUNCTION_TRACER +CFLAGS_cputable.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) +CFLAGS_init.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) +CFLAGS_btext.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) +CFLAGS_prom.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) # Do not trace early boot code CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_prom_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) diff --git a/include/linux/random.h b/include/linux/random.h index e47e533..752e7df 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -18,6 +18,16 @@ struct random_ready_callback { }; extern void add_device_randomness(const void *, unsigned int); + +#if defined(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) && !defined(__CHECKER__) +static inline void add_latent_entropy(void) +{ + add_device_randomness((const void *)_entropy, sizeof(latent_entropy)); +} +#else +static inline void add_latent_entropy(void) {} +#endif + extern void add_input_randomness(unsigned int type, unsigned int code, unsigned int value); extern void add_interrupt_randomness(int irq, int irq_flags); diff --git a/init/main.c b/init/main.c index 4c17fda..07e4174 100644 --- a/init/main.c +++ b/init/main.c @@ -781,6 +781,7 @@ int __init_or_module do_one_initcall(initcall_t fn) } WARN(msgbuf[0], "initcall %pF returned with %s\n", fn, msgbuf); + add_latent_entropy(); return ret; } diff --git a/kernel/fork.c b/kernel/fork.c index 5c2c355..fd1b3c2 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1761,6 +1761,7 @@ long _do_fork(unsigned long clone_flags, p = copy_process(clone_flags, stack_start, stack_size, child_tidptr, NULL, trace, tls, NUMA_NO_NODE); + add_latent_entropy(); /* * Do this prior waking up the new thread - the thread pointer * might get invalid after that point, if the thread exits quickly. diff --git a/mm/page_alloc.c b/mm/page_alloc.c index f8f3bfc..d10324e 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1234,6 +1234,11 @@ static void __free_pages_ok(struct page *page, unsigned int order) local_irq_restore(flags); } +#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY +volatile u64 latent_entropy; +EXP
[PATCH v4 2/4] Add the latent_entropy gcc plugin
This plugin mitigates the problem of the kernel having too little entropy during and after boot for generating crypto keys. It creates a local variable in every marked function. The value of this variable is modified by randomly chosen operations (add, xor and rol) and random values (gcc generates them at compile time and the stack pointer at runtime). It depends on the control flow (e.g., loops, conditions). Before the function returns the plugin writes this local variable into the latent_entropy global variable. The value of this global variable is added to the kernel entropy pool in do_one_initcall() and _do_fork(). Signed-off-by: Emese Revfy --- arch/Kconfig| 18 + arch/powerpc/kernel/Makefile| 4 + include/linux/random.h | 10 + init/main.c | 1 + kernel/fork.c | 1 + mm/page_alloc.c | 5 + scripts/Makefile.gcc-plugins| 8 +- scripts/gcc-plugins/Makefile| 1 + scripts/gcc-plugins/latent_entropy_plugin.c | 639 9 files changed, 686 insertions(+), 1 deletion(-) create mode 100644 scripts/gcc-plugins/latent_entropy_plugin.c diff --git a/arch/Kconfig b/arch/Kconfig index 05f1e95..4b7cc2f 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -393,6 +393,24 @@ config GCC_PLUGIN_SANCOV gcc-4.5 on). It is based on the commit "Add fuzzing coverage support" by Dmitry Vyukov . +config GCC_PLUGIN_LATENT_ENTROPY + bool "Generate some entropy during boot and runtime" + depends on GCC_PLUGINS + help + By saying Y here the kernel will instrument some kernel code to + extract some entropy from both original and artificially created + program state. This will help especially embedded systems where + there is little 'natural' source of entropy normally. The cost + is some slowdown of the boot process (about 0.5%) and fork and + irq processing. + + Note that entropy extracted this way is not cryptographically + secure! + + This plugin was ported from grsecurity/PaX. More information at: + * https://grsecurity.net/ + * https://pax.grsecurity.net/ + config HAVE_CC_STACKPROTECTOR bool help diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 2da380f..01935b8 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -15,6 +15,10 @@ CFLAGS_btext.o += -fPIC endif ifdef CONFIG_FUNCTION_TRACER +CFLAGS_cputable.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) +CFLAGS_init.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) +CFLAGS_btext.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) +CFLAGS_prom.o += $(DISABLE_LATENT_ENTROPY_PLUGIN) # Do not trace early boot code CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_prom_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) diff --git a/include/linux/random.h b/include/linux/random.h index e47e533..752e7df 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -18,6 +18,16 @@ struct random_ready_callback { }; extern void add_device_randomness(const void *, unsigned int); + +#if defined(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) && !defined(__CHECKER__) +static inline void add_latent_entropy(void) +{ + add_device_randomness((const void *)_entropy, sizeof(latent_entropy)); +} +#else +static inline void add_latent_entropy(void) {} +#endif + extern void add_input_randomness(unsigned int type, unsigned int code, unsigned int value); extern void add_interrupt_randomness(int irq, int irq_flags); diff --git a/init/main.c b/init/main.c index 4c17fda..07e4174 100644 --- a/init/main.c +++ b/init/main.c @@ -781,6 +781,7 @@ int __init_or_module do_one_initcall(initcall_t fn) } WARN(msgbuf[0], "initcall %pF returned with %s\n", fn, msgbuf); + add_latent_entropy(); return ret; } diff --git a/kernel/fork.c b/kernel/fork.c index 5c2c355..fd1b3c2 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1761,6 +1761,7 @@ long _do_fork(unsigned long clone_flags, p = copy_process(clone_flags, stack_start, stack_size, child_tidptr, NULL, trace, tls, NUMA_NO_NODE); + add_latent_entropy(); /* * Do this prior waking up the new thread - the thread pointer * might get invalid after that point, if the thread exits quickly. diff --git a/mm/page_alloc.c b/mm/page_alloc.c index f8f3bfc..d10324e 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1234,6 +1234,11 @@ static void __free_pages_ok(struct page *page, unsigned int order) local_irq_restore(flags); } +#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY +volatile u64 latent_entropy; +EXPORT_SYMBOL(latent_entropy); +#endif + static void __i