From e758aba1ea02851e071a1b583cee37e5cfd77f77 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Tue, 25 Jul 2017 14:42:36 -0700 Subject: drm/amd/powerplay: rv: Use designated initializers As done for vega10 in commit 3ddd396f6b57 ("drm/amd/powerplay: Use designated initializers") mark other tableFunction entries with designated initializers. The randstruct plugin requires designated initializers for structures that are entirely function pointers. Cc: Rex Zhu Cc: Hawking Zhang Signed-off-by: Kees Cook Acked-by: Alex Deucher --- drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c index 4c7f430b36eb..8e6cfd89c7e0 100644 --- a/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c +++ b/drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c @@ -308,8 +308,8 @@ static int rv_tf_set_num_active_display(struct pp_hwmgr *hwmgr, void *input, } static const struct phm_master_table_item rv_set_power_state_list[] = { - { NULL, rv_tf_set_clock_limit }, - { NULL, rv_tf_set_num_active_display }, + { .tableFunction = rv_tf_set_clock_limit }, + { .tableFunction = rv_tf_set_num_active_display }, { } }; @@ -382,7 +382,7 @@ static int rv_tf_disable_gfx_off(struct pp_hwmgr *hwmgr, } static const struct phm_master_table_item rv_disable_dpm_list[] = { - {NULL, rv_tf_disable_gfx_off}, + { .tableFunction = rv_tf_disable_gfx_off }, { }, }; @@ -407,7 +407,7 @@ static int rv_tf_enable_gfx_off(struct pp_hwmgr *hwmgr, } static const struct phm_master_table_item rv_enable_dpm_list[] = { - {NULL, rv_tf_enable_gfx_off}, + { .tableFunction = rv_tf_enable_gfx_off }, { }, }; -- cgit From 3598f5d0872ff574c5b6704024f12ca4a3056860 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Sun, 30 Jul 2017 18:15:45 -0700 Subject: drivers/net/wan/z85230.c: Use designated initializers In preparation for the randstruct gcc plugin performing randomization of structures that are entirely function pointers, use designated initializers so the compiler doesn't get angry. Reported-by: kbuild test robot Signed-off-by: Kees Cook Acked-by: David S. Miller --- drivers/net/wan/z85230.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c index 2f0bd6955f33..deea41e96f01 100644 --- a/drivers/net/wan/z85230.c +++ b/drivers/net/wan/z85230.c @@ -483,11 +483,10 @@ static void z8530_status(struct z8530_channel *chan) write_zsctrl(chan, RES_H_IUS); } -struct z8530_irqhandler z8530_sync = -{ - z8530_rx, - z8530_tx, - z8530_status +struct z8530_irqhandler z8530_sync = { + .rx = z8530_rx, + .tx = z8530_tx, + .status = z8530_status, }; EXPORT_SYMBOL(z8530_sync); @@ -605,15 +604,15 @@ static void z8530_dma_status(struct z8530_channel *chan) } static struct z8530_irqhandler z8530_dma_sync = { - z8530_dma_rx, - z8530_dma_tx, - z8530_dma_status + .rx = z8530_dma_rx, + .tx = z8530_dma_tx, + .status = z8530_dma_status, }; static struct z8530_irqhandler z8530_txdma_sync = { - z8530_rx, - z8530_dma_tx, - z8530_dma_status + .rx = z8530_rx, + .tx = z8530_dma_tx, + .status = z8530_dma_status, }; /** @@ -678,11 +677,10 @@ static void z8530_status_clear(struct z8530_channel *chan) write_zsctrl(chan, RES_H_IUS); } -struct z8530_irqhandler z8530_nop= -{ - z8530_rx_clear, - z8530_tx_clear, - z8530_status_clear +struct z8530_irqhandler z8530_nop = { + .rx = z8530_rx_clear, + .tx = z8530_tx_clear, + .status = z8530_status_clear, }; -- cgit From 9225331b310821760f39ba55b00b8973602adbb5 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 5 May 2017 23:56:07 -0700 Subject: randstruct: Enable function pointer struct detection This enables the automatic structure selection logic in the randstruct GCC plugin. The selection logic randomizes all structures that contain only function pointers, unless marked with __no_randomize_layout. Signed-off-by: Kees Cook --- arch/Kconfig | 12 +++++++----- scripts/gcc-plugins/randomize_layout_plugin.c | 3 --- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 21d0089117fe..4ada3209146a 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -473,11 +473,13 @@ config GCC_PLUGIN_RANDSTRUCT depends on GCC_PLUGINS select MODVERSIONS if MODULES help - If you say Y here, the layouts of structures explicitly - marked by __randomize_layout will be randomized at - compile-time. This can introduce the requirement of an - additional information exposure vulnerability for exploits - targeting these structure types. + If you say Y here, the layouts of structures that are entirely + function pointers (and have not been manually annotated with + __no_randomize_layout), or structures that have been explicitly + marked with __randomize_layout, will be randomized at compile-time. + This can introduce the requirement of an additional information + exposure vulnerability for exploits targeting these structure + types. Enabling this feature will introduce some performance impact, slightly increase memory usage, and prevent the use of forensic diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c index cdaac8c66734..0073af326449 100644 --- a/scripts/gcc-plugins/randomize_layout_plugin.c +++ b/scripts/gcc-plugins/randomize_layout_plugin.c @@ -436,9 +436,6 @@ static int is_pure_ops_struct(const_tree node) gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE); - /* XXX: Do not apply randomization to all-ftpr structs yet. */ - return 0; - for (field = TYPE_FIELDS(node); field; field = TREE_CHAIN(field)) { const_tree fieldtype = get_field_type(field); enum tree_code code = TREE_CODE(fieldtype); -- cgit From f7dd2507893cc3425d3ffc2369559619960befb0 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sun, 6 Aug 2017 12:06:27 +0100 Subject: gcc-plugins: structleak: add option to init all vars used as byref args In the Linux kernel, struct type variables are rarely passed by-value, and so functions that initialize such variables typically take an input reference to the variable rather than returning a value that can subsequently be used in an assignment. If the initalization function is not part of the same compilation unit, the lack of an assignment operation defeats any analysis the compiler can perform as to whether the variable may be used before having been initialized. This means we may end up passing on such variables uninitialized, resulting in potential information leaks. So extend the existing structleak GCC plugin so it will [optionally] apply to all struct type variables that have their address taken at any point, rather than only to variables of struct types that have a __user annotation. Signed-off-by: Ard Biesheuvel Signed-off-by: Kees Cook --- arch/Kconfig | 7 +++++++ scripts/Makefile.gcc-plugins | 1 + scripts/gcc-plugins/structleak_plugin.c | 13 +++++++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 21d0089117fe..0f1621489bf0 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -458,6 +458,13 @@ config GCC_PLUGIN_STRUCTLEAK * https://grsecurity.net/ * https://pax.grsecurity.net/ +config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL + bool "Force initialize all struct type variables passed by reference" + depends on GCC_PLUGIN_STRUCTLEAK + help + Zero initialize any struct type local variable that may be passed by + reference without having been initialized. + config GCC_PLUGIN_STRUCTLEAK_VERBOSE bool "Report forcefully initialized variables" depends on GCC_PLUGIN_STRUCTLEAK diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins index 2e0e2eaa397f..d1f7b0d6be66 100644 --- a/scripts/Makefile.gcc-plugins +++ b/scripts/Makefile.gcc-plugins @@ -27,6 +27,7 @@ ifdef CONFIG_GCC_PLUGINS gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += structleak_plugin.so gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) += -fplugin-arg-structleak_plugin-verbose + gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) += -fplugin-arg-structleak_plugin-byref-all gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += -DSTRUCTLEAK_PLUGIN gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so diff --git a/scripts/gcc-plugins/structleak_plugin.c b/scripts/gcc-plugins/structleak_plugin.c index fa3d7a4b26f2..3f8dd4868178 100644 --- a/scripts/gcc-plugins/structleak_plugin.c +++ b/scripts/gcc-plugins/structleak_plugin.c @@ -16,6 +16,7 @@ * Options: * -fplugin-arg-structleak_plugin-disable * -fplugin-arg-structleak_plugin-verbose + * -fplugin-arg-structleak_plugin-byref-all * * Usage: * $ # for 4.5/4.6/C based 4.7 @@ -42,6 +43,7 @@ static struct plugin_info structleak_plugin_info = { }; static bool verbose; +static bool byref_all; static tree handle_user_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) { @@ -150,7 +152,9 @@ static void initialize(tree var) /* these aren't the 0days you're looking for */ if (verbose) inform(DECL_SOURCE_LOCATION(var), - "userspace variable will be forcibly initialized"); + "%s variable will be forcibly initialized", + (byref_all && TREE_ADDRESSABLE(var)) ? "byref" + : "userspace"); /* build the initializer expression */ initializer = build_constructor(TREE_TYPE(var), NULL); @@ -190,7 +194,8 @@ static unsigned int structleak_execute(void) continue; /* if the type is of interest, examine the variable */ - if (TYPE_USERSPACE(type)) + if (TYPE_USERSPACE(type) || + (byref_all && TREE_ADDRESSABLE(var))) initialize(var); } @@ -232,6 +237,10 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gc verbose = true; continue; } + if (!strcmp(argv[i].key, "byref-all")) { + byref_all = true; + continue; + } error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); } -- cgit