summaryrefslogtreecommitdiff
path: root/scripts/gcc-plugins/randomize_layout_plugin.c
AgeCommit message (Collapse)Author
2018-02-05gcc-plugins: Use dynamic initializersKees Cook
GCC 8 changed the order of some fields and is very picky about ordering in static initializers, so instead just move to dynamic initializers, and drop the redundant already-zero field assignments. Suggested-by: Valdis Kletnieks <valdis.kletnieks@vt.edu> Signed-off-by: Kees Cook <keescook@chromium.org>
2017-08-01randstruct: Enable function pointer struct detectionKees Cook
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 <keescook@chromium.org>
2017-06-22randstruct: Whitelist NIU struct page overloadingKees Cook
The NIU ethernet driver intentionally stores a page struct pointer on top of the "mapping" field. Whitelist this case: drivers/net/ethernet/sun/niu.c: In function ‘niu_rx_pkt_ignore’: drivers/net/ethernet/sun/niu.c:3402:10: note: found mismatched ssa struct pointer types: ‘struct page’ and ‘struct address_space’ *link = (struct page *) page->mapping; ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Cc: David S. Miller <davem@davemloft.net> Signed-off-by: Kees Cook <keescook@chromium.org>
2017-06-22randstruct: Whitelist big_key path struct overloadingKees Cook
The big_key payload structure intentionally stores a struct path in two void pointers to avoid header soup. Whitelist this case: security/keys/big_key.c: In function ‘big_key_read’: security/keys/big_key.c:293:16: note: found mismatched rhs struct pointer types: ‘struct path’ and ‘void *’ struct path *path = (struct path *)&key->payload.data[big_key_path]; ^~~~ Cc: David Howells <dhowells@redhat.com> Signed-off-by: Kees Cook <keescook@chromium.org>
2017-06-22randstruct: Whitelist UNIXCB castKees Cook
This is another false positive in bad cast detection: net/unix/af_unix.c: In function ‘unix_skb_scm_eq’: net/unix/af_unix.c:1621:31: note: found mismatched rhs struct pointer types: ‘struct unix_skb_parms’ and ‘char’ const struct unix_skb_parms *u = &UNIXCB(skb); ^ UNIXCB is: #define UNIXCB(skb) (*(struct unix_skb_parms *)&((skb)->cb)) And ->cb is: char cb[48] __aligned(8); This is a rather crazy cast, but appears to be safe in the face of randomization, so whitelist it in the plugin. Cc: Hannes Frederic Sowa <hannes@stressinduktion.org> Cc: David S. Miller <davem@davemloft.net> Signed-off-by: Kees Cook <keescook@chromium.org>
2017-06-22randstruct: Whitelist struct security_hook_heads castKees Cook
The LSM initialization routines walk security_hook_heads as an array of struct list_head instead of via names to avoid a ton of needless source. Whitelist this to avoid the false positive warning from the plugin: security/security.c: In function ‘security_init’: security/security.c:59:20: note: found mismatched op0 struct pointer types: ‘struct list_head’ and ‘struct security_hook_heads’ struct list_head *list = (struct list_head *) &security_hook_heads; ^ Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Cc: James Morris <james.l.morris@oracle.com> Signed-off-by: Kees Cook <keescook@chromium.org>
2017-06-22gcc-plugins: Add the randstruct pluginKees Cook
This randstruct plugin is modified from Brad Spengler/PaX Team's code in the last public patch of grsecurity/PaX based on my understanding of the code. Changes or omissions from the original code are mine and don't reflect the original grsecurity/PaX code. The randstruct GCC plugin randomizes the layout of selected structures at compile time, as a probabilistic defense against attacks that need to know the layout of structures within the kernel. This is most useful for "in-house" kernel builds where neither the randomization seed nor other build artifacts are made available to an attacker. While less useful for distribution kernels (where the randomization seed must be exposed for third party kernel module builds), it still has some value there since now all kernel builds would need to be tracked by an attacker. In more performance sensitive scenarios, GCC_PLUGIN_RANDSTRUCT_PERFORMANCE can be selected to make a best effort to restrict randomization to cacheline-sized groups of elements, and will not randomize bitfields. This comes at the cost of reduced randomization. Two annotations are defined,__randomize_layout and __no_randomize_layout, which respectively tell the plugin to either randomize or not to randomize instances of the struct in question. Follow-on patches enable the auto-detection logic for selecting structures for randomization that contain only function pointers. It is disabled here to assist with bisection. Since any randomized structs must be initialized using designated initializers, __randomize_layout includes the __designated_init annotation even when the plugin is disabled so that all builds will require the needed initialization. (With the plugin enabled, annotations for automatically chosen structures are marked as well.) The main differences between this implemenation and grsecurity are: - disable automatic struct selection (to be enabled in follow-up patch) - add designated_init attribute at runtime and for manual marking - clarify debugging output to differentiate bad cast warnings - add whitelisting infrastructure - support gcc 7's DECL_ALIGN and DECL_MODE changes (Laura Abbott) - raise minimum required GCC version to 4.7 Earlier versions of this patch series were ported by Michael Leibowitz. Signed-off-by: Kees Cook <keescook@chromium.org>