mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-19 21:21:09 +00:00
increased structleak coverage
- And scalar and array initialization coverage - Refactor Kconfig to make options more clear - Add self-test module for testing automatic initialization -----BEGIN PGP SIGNATURE----- Comment: Kees Cook <kees@outflux.net> iQJKBAABCgA0FiEEpcP2jyKd1g9yPm4TiXL039xtwCYFAlx9YaIWHGtlZXNjb29r QGNocm9taXVtLm9yZwAKCRCJcvTf3G3AJuJ3D/93rm0lxwlokyZH7ik//G8ha6c/ eH2EelxybyHeK39syY6TG1KeSP1LhvvyHrhuJMnMHfvd7wHJrMyIWZWhbqLTk/+e CzrlFg0gbeLacmT5+mwSiyl+iZgpwREyHI96R6cW1AQC/gCh4d828uRKsDB2btGg 89h6F4vp2AmjbEJgdembPHk8RmdrhStbqxc53WON1217huC8f1fmLsTpPlBSJHV5 AZFjbmG5bSoWbRD/0NnsKbctO1XTE+WBvZPAWhCqhTjIVL2a/k0OybvlJw26mcmV zKOj35uzZ5S6ZBSd23EsAlJNzC9LO2sLQdT+iX9sBKeRqfdcoP7eoeM4KXsXzSHD gQ2zcSqYEyNSxJWxtdOX02Yx8rowHAcFB3ZIxK/dN91JAVhF22EAkeenT8Uus0SB NkIkp70bHaAscvJ18Ahdkd7GOCk06BWyb/K4Lejy9TBMGXFztZRIHg1YwLiYlSiW RNr0STU+vcK56v4sixcNeeLKFVIcne4RbBlaJMv5y5PygVuN3xZTGsg2lhvJNnHA EwsPV6D8fx5U8w0taX+U/5IpigIIxfLQU6VTnjydDk1EScpXLy4JCFqE4N9aksqy F9PfrP3XXuwULyNd/cRxhHVwyXoQA6xaMZ4Sf4Sp7YHfxMRIWlN/aYfZFanvxQMA HJaoHZfjLt/NKCI3JQ== =6iu3 -----END PGP SIGNATURE----- Merge tag 'gcc-plugins-v5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux Pull gcc-plugins updates from Kees Cook: "This adds additional type coverage to the existing structleak plugin and adds a large set of selftests to help evaluate stack variable zero-initialization coverage. That can be used to test whatever instrumentation might be performing zero-initialization: either with the structleak plugin or with Clang's coming "-ftrivial-auto-var-init=zero" option. Summary: - Add scalar and array initialization coverage - Refactor Kconfig to make options more clear - Add self-test module for testing automatic initialization" * tag 'gcc-plugins-v5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: lib: Introduce test_stackinit module gcc-plugins: structleak: Generalize to all variable types
This commit is contained in:
commit
2bb995405f
6 changed files with 462 additions and 21 deletions
|
@ -15,6 +15,8 @@ gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV) += sancov_plugin.so
|
|||
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) \
|
||||
+= -fplugin-arg-structleak_plugin-byref
|
||||
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL) \
|
||||
+= -fplugin-arg-structleak_plugin-byref-all
|
||||
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) \
|
||||
|
|
|
@ -67,23 +67,59 @@ config GCC_PLUGIN_LATENT_ENTROPY
|
|||
* https://pax.grsecurity.net/
|
||||
|
||||
config GCC_PLUGIN_STRUCTLEAK
|
||||
bool "Force initialization of variables containing userspace addresses"
|
||||
bool "Zero initialize stack variables"
|
||||
help
|
||||
This plugin zero-initializes any structures containing a
|
||||
__user attribute. This can prevent some classes of information
|
||||
exposures.
|
||||
While the kernel is built with warnings enabled for any missed
|
||||
stack variable initializations, this warning is silenced for
|
||||
anything passed by reference to another function, under the
|
||||
occasionally misguided assumption that the function will do
|
||||
the initialization. As this regularly leads to exploitable
|
||||
flaws, this plugin is available to identify and zero-initialize
|
||||
such variables, depending on the chosen level of coverage.
|
||||
|
||||
This plugin was ported from grsecurity/PaX. More information at:
|
||||
This plugin was originally ported from grsecurity/PaX. More
|
||||
information at:
|
||||
* https://grsecurity.net/
|
||||
* https://pax.grsecurity.net/
|
||||
|
||||
config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL
|
||||
bool "Force initialize all struct type variables passed by reference"
|
||||
choice
|
||||
prompt "Coverage"
|
||||
depends on GCC_PLUGIN_STRUCTLEAK
|
||||
depends on !COMPILE_TEST
|
||||
default GCC_PLUGIN_STRUCTLEAK_BYREF_ALL
|
||||
help
|
||||
Zero initialize any struct type local variable that may be passed by
|
||||
reference without having been initialized.
|
||||
This chooses the level of coverage over classes of potentially
|
||||
uninitialized variables. The selected class will be
|
||||
zero-initialized before use.
|
||||
|
||||
config GCC_PLUGIN_STRUCTLEAK_USER
|
||||
bool "structs marked for userspace"
|
||||
help
|
||||
Zero-initialize any structures on the stack containing
|
||||
a __user attribute. This can prevent some classes of
|
||||
uninitialized stack variable exploits and information
|
||||
exposures, like CVE-2013-2141:
|
||||
https://git.kernel.org/linus/b9e146d8eb3b9eca
|
||||
|
||||
config GCC_PLUGIN_STRUCTLEAK_BYREF
|
||||
bool "structs passed by reference"
|
||||
help
|
||||
Zero-initialize any structures on the stack that may
|
||||
be passed by reference and had not already been
|
||||
explicitly initialized. This can prevent most classes
|
||||
of uninitialized stack variable exploits and information
|
||||
exposures, like CVE-2017-1000410:
|
||||
https://git.kernel.org/linus/06e7e776ca4d3654
|
||||
|
||||
config GCC_PLUGIN_STRUCTLEAK_BYREF_ALL
|
||||
bool "anything passed by reference"
|
||||
help
|
||||
Zero-initialize any stack variables that may be passed
|
||||
by reference and had not already been explicitly
|
||||
initialized. This is intended to eliminate all classes
|
||||
of uninitialized stack variable exploits and information
|
||||
exposures.
|
||||
|
||||
endchoice
|
||||
|
||||
config GCC_PLUGIN_STRUCTLEAK_VERBOSE
|
||||
bool "Report forcefully initialized variables"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
* Options:
|
||||
* -fplugin-arg-structleak_plugin-disable
|
||||
* -fplugin-arg-structleak_plugin-verbose
|
||||
* -fplugin-arg-structleak_plugin-byref
|
||||
* -fplugin-arg-structleak_plugin-byref-all
|
||||
*
|
||||
* Usage:
|
||||
|
@ -26,7 +27,6 @@
|
|||
* $ gcc -fplugin=./structleak_plugin.so test.c -O2
|
||||
*
|
||||
* TODO: eliminate redundant initializers
|
||||
* increase type coverage
|
||||
*/
|
||||
|
||||
#include "gcc-common.h"
|
||||
|
@ -37,13 +37,18 @@
|
|||
__visible int plugin_is_GPL_compatible;
|
||||
|
||||
static struct plugin_info structleak_plugin_info = {
|
||||
.version = "201607271510vanilla",
|
||||
.version = "20190125vanilla",
|
||||
.help = "disable\tdo not activate plugin\n"
|
||||
"verbose\tprint all initialized variables\n",
|
||||
"byref\tinit structs passed by reference\n"
|
||||
"byref-all\tinit anything passed by reference\n"
|
||||
"verbose\tprint all initialized variables\n",
|
||||
};
|
||||
|
||||
#define BYREF_STRUCT 1
|
||||
#define BYREF_ALL 2
|
||||
|
||||
static bool verbose;
|
||||
static bool byref_all;
|
||||
static int byref;
|
||||
|
||||
static tree handle_user_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attrs)
|
||||
{
|
||||
|
@ -118,6 +123,7 @@ static void initialize(tree var)
|
|||
gimple_stmt_iterator gsi;
|
||||
tree initializer;
|
||||
gimple init_stmt;
|
||||
tree type;
|
||||
|
||||
/* this is the original entry bb before the forced split */
|
||||
bb = single_succ(ENTRY_BLOCK_PTR_FOR_FN(cfun));
|
||||
|
@ -148,11 +154,15 @@ static void initialize(tree var)
|
|||
if (verbose)
|
||||
inform(DECL_SOURCE_LOCATION(var),
|
||||
"%s variable will be forcibly initialized",
|
||||
(byref_all && TREE_ADDRESSABLE(var)) ? "byref"
|
||||
: "userspace");
|
||||
(byref && TREE_ADDRESSABLE(var)) ? "byref"
|
||||
: "userspace");
|
||||
|
||||
/* build the initializer expression */
|
||||
initializer = build_constructor(TREE_TYPE(var), NULL);
|
||||
type = TREE_TYPE(var);
|
||||
if (AGGREGATE_TYPE_P(type))
|
||||
initializer = build_constructor(type, NULL);
|
||||
else
|
||||
initializer = fold_convert(type, integer_zero_node);
|
||||
|
||||
/* build the initializer stmt */
|
||||
init_stmt = gimple_build_assign(var, initializer);
|
||||
|
@ -184,13 +194,13 @@ static unsigned int structleak_execute(void)
|
|||
if (!auto_var_in_fn_p(var, current_function_decl))
|
||||
continue;
|
||||
|
||||
/* only care about structure types */
|
||||
if (TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE)
|
||||
/* only care about structure types unless byref-all */
|
||||
if (byref != BYREF_ALL && TREE_CODE(type) != RECORD_TYPE && TREE_CODE(type) != UNION_TYPE)
|
||||
continue;
|
||||
|
||||
/* if the type is of interest, examine the variable */
|
||||
if (TYPE_USERSPACE(type) ||
|
||||
(byref_all && TREE_ADDRESSABLE(var)))
|
||||
(byref && TREE_ADDRESSABLE(var)))
|
||||
initialize(var);
|
||||
}
|
||||
|
||||
|
@ -232,8 +242,12 @@ __visible int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gc
|
|||
verbose = true;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i].key, "byref")) {
|
||||
byref = BYREF_STRUCT;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i].key, "byref-all")) {
|
||||
byref_all = true;
|
||||
byref = BYREF_ALL;
|
||||
continue;
|
||||
}
|
||||
error(G_("unknown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue