Merge tag 'gcc-plugins-v4.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux

Pull gcc plugins update from Kees Cook:
"This finishes the porting work on randstruct, and introduces a new
option to structleak, both noted below:

- For the randstruct plugin, enable automatic randomization of
structures that are entirely function pointers (along with a couple
designated initializer fixes).

- For the structleak plugin, provide an option to perform zeroing
initialization of all otherwise uninitialized stack variables that
are passed by reference (Ard Biesheuvel)"

* tag 'gcc-plugins-v4.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
gcc-plugins: structleak: add option to init all vars used as byref args
randstruct: Enable function pointer struct detection
drivers/net/wan/z85230.c: Use designated initializers
drm/amd/powerplay: rv: Use designated initializers

+44 -30
+14 -5
arch/Kconfig
··· 458 * https://grsecurity.net/ 459 * https://pax.grsecurity.net/ 460 461 config GCC_PLUGIN_STRUCTLEAK_VERBOSE 462 bool "Report forcefully initialized variables" 463 depends on GCC_PLUGIN_STRUCTLEAK ··· 480 depends on GCC_PLUGINS 481 select MODVERSIONS if MODULES 482 help 483 - If you say Y here, the layouts of structures explicitly 484 - marked by __randomize_layout will be randomized at 485 - compile-time. This can introduce the requirement of an 486 - additional information exposure vulnerability for exploits 487 - targeting these structure types. 488 489 Enabling this feature will introduce some performance impact, 490 slightly increase memory usage, and prevent the use of forensic
··· 458 * https://grsecurity.net/ 459 * https://pax.grsecurity.net/ 460 461 + config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL 462 + bool "Force initialize all struct type variables passed by reference" 463 + depends on GCC_PLUGIN_STRUCTLEAK 464 + help 465 + Zero initialize any struct type local variable that may be passed by 466 + reference without having been initialized. 467 + 468 config GCC_PLUGIN_STRUCTLEAK_VERBOSE 469 bool "Report forcefully initialized variables" 470 depends on GCC_PLUGIN_STRUCTLEAK ··· 473 depends on GCC_PLUGINS 474 select MODVERSIONS if MODULES 475 help 476 + If you say Y here, the layouts of structures that are entirely 477 + function pointers (and have not been manually annotated with 478 + __no_randomize_layout), or structures that have been explicitly 479 + marked with __randomize_layout, will be randomized at compile-time. 480 + This can introduce the requirement of an additional information 481 + exposure vulnerability for exploits targeting these structure 482 + types. 483 484 Enabling this feature will introduce some performance impact, 485 slightly increase memory usage, and prevent the use of forensic
+4 -4
drivers/gpu/drm/amd/powerplay/hwmgr/rv_hwmgr.c
··· 317 } 318 319 static const struct phm_master_table_item rv_set_power_state_list[] = { 320 - { NULL, rv_tf_set_clock_limit }, 321 - { NULL, rv_tf_set_num_active_display }, 322 { } 323 }; 324 ··· 391 } 392 393 static const struct phm_master_table_item rv_disable_dpm_list[] = { 394 - {NULL, rv_tf_disable_gfx_off}, 395 { }, 396 }; 397 ··· 416 } 417 418 static const struct phm_master_table_item rv_enable_dpm_list[] = { 419 - {NULL, rv_tf_enable_gfx_off}, 420 { }, 421 }; 422
··· 317 } 318 319 static const struct phm_master_table_item rv_set_power_state_list[] = { 320 + { .tableFunction = rv_tf_set_clock_limit }, 321 + { .tableFunction = rv_tf_set_num_active_display }, 322 { } 323 }; 324 ··· 391 } 392 393 static const struct phm_master_table_item rv_disable_dpm_list[] = { 394 + { .tableFunction = rv_tf_disable_gfx_off }, 395 { }, 396 }; 397 ··· 416 } 417 418 static const struct phm_master_table_item rv_enable_dpm_list[] = { 419 + { .tableFunction = rv_tf_enable_gfx_off }, 420 { }, 421 }; 422
+14 -16
drivers/net/wan/z85230.c
··· 483 write_zsctrl(chan, RES_H_IUS); 484 } 485 486 - struct z8530_irqhandler z8530_sync = 487 - { 488 - z8530_rx, 489 - z8530_tx, 490 - z8530_status 491 }; 492 493 EXPORT_SYMBOL(z8530_sync); ··· 604 } 605 606 static struct z8530_irqhandler z8530_dma_sync = { 607 - z8530_dma_rx, 608 - z8530_dma_tx, 609 - z8530_dma_status 610 }; 611 612 static struct z8530_irqhandler z8530_txdma_sync = { 613 - z8530_rx, 614 - z8530_dma_tx, 615 - z8530_dma_status 616 }; 617 618 /** ··· 677 write_zsctrl(chan, RES_H_IUS); 678 } 679 680 - struct z8530_irqhandler z8530_nop= 681 - { 682 - z8530_rx_clear, 683 - z8530_tx_clear, 684 - z8530_status_clear 685 }; 686 687
··· 483 write_zsctrl(chan, RES_H_IUS); 484 } 485 486 + struct z8530_irqhandler z8530_sync = { 487 + .rx = z8530_rx, 488 + .tx = z8530_tx, 489 + .status = z8530_status, 490 }; 491 492 EXPORT_SYMBOL(z8530_sync); ··· 605 } 606 607 static struct z8530_irqhandler z8530_dma_sync = { 608 + .rx = z8530_dma_rx, 609 + .tx = z8530_dma_tx, 610 + .status = z8530_dma_status, 611 }; 612 613 static struct z8530_irqhandler z8530_txdma_sync = { 614 + .rx = z8530_rx, 615 + .tx = z8530_dma_tx, 616 + .status = z8530_dma_status, 617 }; 618 619 /** ··· 678 write_zsctrl(chan, RES_H_IUS); 679 } 680 681 + struct z8530_irqhandler z8530_nop = { 682 + .rx = z8530_rx_clear, 683 + .tx = z8530_tx_clear, 684 + .status = z8530_status_clear, 685 }; 686 687
+1
scripts/Makefile.gcc-plugins
··· 27 28 gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += structleak_plugin.so 29 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) += -fplugin-arg-structleak_plugin-verbose 30 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += -DSTRUCTLEAK_PLUGIN 31 32 gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so
··· 27 28 gcc-plugin-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += structleak_plugin.so 29 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) += -fplugin-arg-structleak_plugin-verbose 30 + gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) += -fplugin-arg-structleak_plugin-byref-all 31 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += -DSTRUCTLEAK_PLUGIN 32 33 gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so
-3
scripts/gcc-plugins/randomize_layout_plugin.c
··· 436 437 gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE); 438 439 - /* XXX: Do not apply randomization to all-ftpr structs yet. */ 440 - return 0; 441 - 442 for (field = TYPE_FIELDS(node); field; field = TREE_CHAIN(field)) { 443 const_tree fieldtype = get_field_type(field); 444 enum tree_code code = TREE_CODE(fieldtype);
··· 436 437 gcc_assert(TREE_CODE(node) == RECORD_TYPE || TREE_CODE(node) == UNION_TYPE); 438 439 for (field = TYPE_FIELDS(node); field; field = TREE_CHAIN(field)) { 440 const_tree fieldtype = get_field_type(field); 441 enum tree_code code = TREE_CODE(fieldtype);
+11 -2
scripts/gcc-plugins/structleak_plugin.c
··· 16 * Options: 17 * -fplugin-arg-structleak_plugin-disable 18 * -fplugin-arg-structleak_plugin-verbose 19 * 20 * Usage: 21 * $ # for 4.5/4.6/C based 4.7 ··· 43 }; 44 45 static bool verbose; 46 47 static tree handle_user_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) 48 { ··· 152 /* these aren't the 0days you're looking for */ 153 if (verbose) 154 inform(DECL_SOURCE_LOCATION(var), 155 - "userspace variable will be forcibly initialized"); 156 157 /* build the initializer expression */ 158 initializer = build_constructor(TREE_TYPE(var), NULL); ··· 194 continue; 195 196 /* if the type is of interest, examine the variable */ 197 - if (TYPE_USERSPACE(type)) 198 initialize(var); 199 } 200 ··· 235 } 236 if (!strcmp(argv[i].key, "verbose")) { 237 verbose = true; 238 continue; 239 } 240 error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
··· 16 * Options: 17 * -fplugin-arg-structleak_plugin-disable 18 * -fplugin-arg-structleak_plugin-verbose 19 + * -fplugin-arg-structleak_plugin-byref-all 20 * 21 * Usage: 22 * $ # for 4.5/4.6/C based 4.7 ··· 42 }; 43 44 static bool verbose; 45 + static bool byref_all; 46 47 static tree handle_user_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs) 48 { ··· 150 /* these aren't the 0days you're looking for */ 151 if (verbose) 152 inform(DECL_SOURCE_LOCATION(var), 153 + "%s variable will be forcibly initialized", 154 + (byref_all && TREE_ADDRESSABLE(var)) ? "byref" 155 + : "userspace"); 156 157 /* build the initializer expression */ 158 initializer = build_constructor(TREE_TYPE(var), NULL); ··· 190 continue; 191 192 /* if the type is of interest, examine the variable */ 193 + if (TYPE_USERSPACE(type) || 194 + (byref_all && TREE_ADDRESSABLE(var))) 195 initialize(var); 196 } 197 ··· 230 } 231 if (!strcmp(argv[i].key, "verbose")) { 232 verbose = true; 233 + continue; 234 + } 235 + if (!strcmp(argv[i].key, "byref-all")) { 236 + byref_all = true; 237 continue; 238 } 239 error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);