01 Aug, 2019

1 commit

  • While no uses in the kernel triggered this case, it was possible to have
    a false negative where a struct contains other structs which contain only
    function pointers because of unreachable code in is_pure_ops_struct().

    Signed-off-by: Joonwon Kang
    Link: https://lore.kernel.org/r/20190727155841.GA13586@host
    Fixes: 313dd1b62921 ("gcc-plugins: Add the randstruct plugin")
    Cc: stable@vger.kernel.org
    Signed-off-by: Kees Cook

    Joonwon Kang
     

31 Mar, 2018

1 commit

  • This changes security_hook_heads to use hlist_heads instead of
    the circular doubly-linked list heads. This should cut down
    the size of the struct by about half.

    In addition, it allows mutation of the hooks at the tail of the
    callback list without having to modify the head. The longer-term
    purpose of this is to enable making the heads read only.

    Signed-off-by: Sargun Dhillon
    Reviewed-by: Tetsuo Handa
    Acked-by: Casey Schaufler
    Signed-off-by: James Morris

    Sargun Dhillon
     

06 Feb, 2018

1 commit

  • 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
    Signed-off-by: Kees Cook

    Kees Cook
     

02 Aug, 2017

1 commit


23 Jun, 2017

5 commits

  • 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
    Signed-off-by: Kees Cook

    Kees 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
    Signed-off-by: Kees Cook

    Kees 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
    Cc: David S. Miller
    Signed-off-by: Kees Cook

    Kees 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
    Cc: James Morris
    Signed-off-by: Kees Cook

    Kees 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

    Kees Cook