randstruct: Mark various structs for randomization
authorKees Cook <keescook@chromium.org>
Fri, 28 Oct 2016 08:22:25 +0000 (01:22 -0700)
committerKees Cook <keescook@chromium.org>
Fri, 30 Jun 2017 19:00:51 +0000 (12:00 -0700)
This marks many critical kernel structures for randomization. These are
structures that have been targeted in the past in security exploits, or
contain functions pointers, pointers to function pointer tables, lists,
workqueues, ref-counters, credentials, permissions, or are otherwise
sensitive. This initial list was extracted 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.

Left out of this list is task_struct, which requires special handling
and will be covered in a subsequent patch.

Signed-off-by: Kees Cook <keescook@chromium.org>
38 files changed:
arch/x86/include/asm/processor.h
fs/mount.h
fs/namei.c
fs/proc/internal.h
include/linux/binfmts.h
include/linux/cdev.h
include/linux/cred.h
include/linux/dcache.h
include/linux/fs.h
include/linux/fs_struct.h
include/linux/ipc.h
include/linux/ipc_namespace.h
include/linux/key-type.h
include/linux/kmod.h
include/linux/kobject.h
include/linux/lsm_hooks.h
include/linux/mm_types.h
include/linux/module.h
include/linux/mount.h
include/linux/msg.h
include/linux/path.h
include/linux/pid_namespace.h
include/linux/proc_ns.h
include/linux/sched.h
include/linux/sched/signal.h
include/linux/sem.h
include/linux/shm.h
include/linux/sysctl.h
include/linux/tty.h
include/linux/tty_driver.h
include/linux/user_namespace.h
include/linux/utsname.h
include/net/af_unix.h
include/net/neighbour.h
include/net/net_namespace.h
include/net/sock.h
kernel/futex.c
security/keys/internal.h

index 3cada99..e2335ed 100644 (file)
@@ -129,7 +129,7 @@ struct cpuinfo_x86 {
        /* Index into per_cpu list: */
        u16                     cpu_index;
        u32                     microcode;
-};
+} __randomize_layout;
 
 struct cpuid_regs {
        u32 eax, ebx, ecx, edx;
index bf1fda6..e406b28 100644 (file)
@@ -16,7 +16,7 @@ struct mnt_namespace {
        u64 event;
        unsigned int            mounts; /* # of mounts in the namespace */
        unsigned int            pending_mounts;
-};
+} __randomize_layout;
 
 struct mnt_pcp {
        int mnt_count;
@@ -68,7 +68,7 @@ struct mount {
        struct hlist_head mnt_pins;
        struct fs_pin mnt_umount;
        struct dentry *mnt_ex_mountpoint;
-};
+} __randomize_layout;
 
 #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
 
index 6571a5f..1764620 100644 (file)
@@ -524,7 +524,7 @@ struct nameidata {
        struct inode    *link_inode;
        unsigned        root_seq;
        int             dfd;
-};
+} __randomize_layout;
 
 static void set_nameidata(struct nameidata *p, int dfd, struct filename *name)
 {
index c5ae09b..07b1631 100644 (file)
@@ -51,7 +51,7 @@ struct proc_dir_entry {
        spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
        u8 namelen;
        char name[];
-};
+} __randomize_layout;
 
 union proc_op {
        int (*proc_get_link)(struct dentry *, struct path *);
@@ -70,7 +70,7 @@ struct proc_inode {
        struct list_head sysctl_inodes;
        const struct proc_ns_operations *ns_ops;
        struct inode vfs_inode;
-};
+} __randomize_layout;
 
 /*
  * General functions
@@ -279,7 +279,7 @@ struct proc_maps_private {
 #ifdef CONFIG_NUMA
        struct mempolicy *task_mempolicy;
 #endif
-};
+} __randomize_layout;
 
 struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode);
 
index 05488da..3ae9013 100644 (file)
@@ -46,7 +46,7 @@ struct linux_binprm {
        unsigned interp_flags;
        unsigned interp_data;
        unsigned long loader, exec;
-};
+} __randomize_layout;
 
 #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
 #define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT)
@@ -81,7 +81,7 @@ struct linux_binfmt {
        int (*load_shlib)(struct file *);
        int (*core_dump)(struct coredump_params *cprm);
        unsigned long min_coredump;     /* minimal dump size */
-};
+} __randomize_layout;
 
 extern void __register_binfmt(struct linux_binfmt *fmt, int insert);
 
index 408bc09..cb28eb2 100644 (file)
@@ -17,7 +17,7 @@ struct cdev {
        struct list_head list;
        dev_t dev;
        unsigned int count;
-};
+} __randomize_layout;
 
 void cdev_init(struct cdev *, const struct file_operations *);
 
index b03e7d0..82c8a9e 100644 (file)
@@ -31,7 +31,7 @@ struct group_info {
        atomic_t        usage;
        int             ngroups;
        kgid_t          gid[0];
-};
+} __randomize_layout;
 
 /**
  * get_group_info - Get a reference to a group info structure
@@ -145,7 +145,7 @@ struct cred {
        struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */
        struct group_info *group_info;  /* supplementary groups for euid/fsgid */
        struct rcu_head rcu;            /* RCU deletion hook */
-};
+} __randomize_layout;
 
 extern void __put_cred(struct cred *);
 extern void exit_creds(struct task_struct *);
index d2e38dc..7eb262e 100644 (file)
@@ -113,7 +113,7 @@ struct dentry {
                struct hlist_bl_node d_in_lookup_hash;  /* only for in-lookup ones */
                struct rcu_head d_rcu;
        } d_u;
-};
+} __randomize_layout;
 
 /*
  * dentry->d_lock spinlock nesting subclasses:
index 803e5a9..8f28143 100644 (file)
@@ -275,7 +275,7 @@ struct kiocb {
        void (*ki_complete)(struct kiocb *iocb, long ret, long ret2);
        void                    *private;
        int                     ki_flags;
-};
+} __randomize_layout;
 
 static inline bool is_sync_kiocb(struct kiocb *kiocb)
 {
@@ -392,7 +392,7 @@ struct address_space {
        gfp_t                   gfp_mask;       /* implicit gfp mask for allocations */
        struct list_head        private_list;   /* ditto */
        void                    *private_data;  /* ditto */
-} __attribute__((aligned(sizeof(long))));
+} __attribute__((aligned(sizeof(long)))) __randomize_layout;
        /*
         * On most architectures that alignment is already the case; but
         * must be enforced here for CRIS, to let the least significant bit
@@ -435,7 +435,7 @@ struct block_device {
        int                     bd_fsfreeze_count;
        /* Mutex for freeze */
        struct mutex            bd_fsfreeze_mutex;
-};
+} __randomize_layout;
 
 /*
  * Radix-tree tags, for tagging dirty and writeback pages within the pagecache
@@ -653,7 +653,7 @@ struct inode {
 #endif
 
        void                    *i_private; /* fs or device private pointer */
-};
+} __randomize_layout;
 
 static inline unsigned int i_blocksize(const struct inode *node)
 {
@@ -868,7 +868,8 @@ struct file {
        struct list_head        f_tfile_llink;
 #endif /* #ifdef CONFIG_EPOLL */
        struct address_space    *f_mapping;
-} __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
+} __randomize_layout
+  __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
 
 struct file_handle {
        __u32 handle_bytes;
@@ -1005,7 +1006,7 @@ struct file_lock {
                        int state;              /* state of grant or error if -ve */
                } afs;
        } fl_u;
-};
+} __randomize_layout;
 
 struct file_lock_context {
        spinlock_t              flc_lock;
@@ -1404,7 +1405,7 @@ struct super_block {
 
        spinlock_t              s_inode_wblist_lock;
        struct list_head        s_inodes_wb;    /* writeback inodes */
-};
+} __randomize_layout;
 
 /* Helper functions so that in most cases filesystems will
  * not need to deal directly with kuid_t and kgid_t and can
@@ -1690,7 +1691,7 @@ struct file_operations {
                        u64);
        ssize_t (*dedupe_file_range)(struct file *, u64, u64, struct file *,
                        u64);
-};
+} __randomize_layout;
 
 struct inode_operations {
        struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
index 0efc3e6..7a02624 100644 (file)
@@ -12,7 +12,7 @@ struct fs_struct {
        int umask;
        int in_exec;
        struct path root, pwd;
-};
+} __randomize_layout;
 
 extern struct kmem_cache *fs_cachep;
 
index 71fd92d..ea0eb0b 100644 (file)
@@ -20,6 +20,6 @@ struct kern_ipc_perm {
        umode_t         mode;
        unsigned long   seq;
        void            *security;
-} ____cacheline_aligned_in_smp;
+} ____cacheline_aligned_in_smp __randomize_layout;
 
 #endif /* _LINUX_IPC_H */
index 848e579..65327ee 100644 (file)
@@ -61,7 +61,7 @@ struct ipc_namespace {
        struct ucounts *ucounts;
 
        struct ns_common ns;
-};
+} __randomize_layout;
 
 extern struct ipc_namespace init_ipc_ns;
 extern spinlock_t mq_lock;
index 8496cf6..9520fc3 100644 (file)
@@ -45,7 +45,7 @@ struct key_preparsed_payload {
        size_t          datalen;        /* Raw datalen */
        size_t          quotalen;       /* Quota length for proposed payload */
        time_t          expiry;         /* Expiry time of key */
-};
+} __randomize_layout;
 
 typedef int (*request_key_actor_t)(struct key_construction *key,
                                   const char *op, void *aux);
@@ -158,7 +158,7 @@ struct key_type {
        /* internal fields */
        struct list_head        link;           /* link in types list */
        struct lock_class_key   lock_class;     /* key->sem lock class */
-};
+} __randomize_layout;
 
 extern struct key_type key_type_keyring;
 
index c4e441e..655082c 100644 (file)
@@ -64,7 +64,7 @@ struct subprocess_info {
        int (*init)(struct subprocess_info *info, struct cred *new);
        void (*cleanup)(struct subprocess_info *info);
        void *data;
-};
+} __randomize_layout;
 
 extern int
 call_usermodehelper(const char *path, char **argv, char **envp, int wait);
index ca85cb8..0845133 100644 (file)
@@ -172,7 +172,7 @@ struct kset {
        spinlock_t list_lock;
        struct kobject kobj;
        const struct kset_uevent_ops *uevent_ops;
-};
+} __randomize_layout;
 
 extern void kset_init(struct kset *kset);
 extern int __must_check kset_register(struct kset *kset);
index 080f34e..565163f 100644 (file)
@@ -1876,7 +1876,7 @@ struct security_hook_heads {
        struct list_head audit_rule_match;
        struct list_head audit_rule_free;
 #endif /* CONFIG_AUDIT */
-};
+} __randomize_layout;
 
 /*
  * Security module hook list structure.
@@ -1887,7 +1887,7 @@ struct security_hook_list {
        struct list_head                *head;
        union security_list_options     hook;
        char                            *lsm;
-};
+} __randomize_layout;
 
 /*
  * Initializing a security_hook_list structure takes
index 45cdb27..ff15181 100644 (file)
@@ -342,7 +342,7 @@ struct vm_area_struct {
        struct mempolicy *vm_policy;    /* NUMA policy for the VMA */
 #endif
        struct vm_userfaultfd_ctx vm_userfaultfd_ctx;
-};
+} __randomize_layout;
 
 struct core_thread {
        struct task_struct *task;
@@ -500,7 +500,7 @@ struct mm_struct {
        atomic_long_t hugetlb_usage;
 #endif
        struct work_struct async_put_work;
-};
+} __randomize_layout;
 
 extern struct mm_struct init_mm;
 
index 21f5639..d93111d 100644 (file)
@@ -45,7 +45,7 @@ struct module_kobject {
        struct kobject *drivers_dir;
        struct module_param_attrs *mp;
        struct completion *kobj_completion;
-};
+} __randomize_layout;
 
 struct module_attribute {
        struct attribute attr;
@@ -475,7 +475,7 @@ struct module {
        ctor_fn_t *ctors;
        unsigned int num_ctors;
 #endif
-} ____cacheline_aligned;
+} ____cacheline_aligned __randomize_layout;
 #ifndef MODULE_ARCH_INIT
 #define MODULE_ARCH_INIT {}
 #endif
index 8e0352a..1ce85e6 100644 (file)
@@ -67,7 +67,7 @@ struct vfsmount {
        struct dentry *mnt_root;        /* root of the mounted tree */
        struct super_block *mnt_sb;     /* pointer to superblock */
        int mnt_flags;
-};
+} __randomize_layout;
 
 struct file; /* forward dec */
 struct path;
index f3f302f..a001305 100644 (file)
@@ -29,7 +29,7 @@ struct msg_queue {
        struct list_head q_messages;
        struct list_head q_receivers;
        struct list_head q_senders;
-};
+} __randomize_layout;
 
 /* Helper routines for sys_msgsnd and sys_msgrcv */
 extern long do_msgsnd(int msqid, long mtype, void __user *mtext,
index d137218..cde895c 100644 (file)
@@ -7,7 +7,7 @@ struct vfsmount;
 struct path {
        struct vfsmount *mnt;
        struct dentry *dentry;
-};
+} __randomize_layout;
 
 extern void path_get(const struct path *);
 extern void path_put(const struct path *);
index c2a989d..b09136f 100644 (file)
@@ -52,7 +52,7 @@ struct pid_namespace {
        int hide_pid;
        int reboot;     /* group exit code if this pidns was rebooted */
        struct ns_common ns;
-};
+} __randomize_layout;
 
 extern struct pid_namespace init_pid_ns;
 
index 58ab28d..06844b5 100644 (file)
@@ -21,7 +21,7 @@ struct proc_ns_operations {
        int (*install)(struct nsproxy *nsproxy, struct ns_common *ns);
        struct user_namespace *(*owner)(struct ns_common *ns);
        struct ns_common *(*get_parent)(struct ns_common *ns);
-};
+} __randomize_layout;
 
 extern const struct proc_ns_operations netns_operations;
 extern const struct proc_ns_operations utsns_operations;
index 2b69fc6..f833254 100644 (file)
@@ -408,7 +408,7 @@ struct sched_rt_entity {
        /* rq "owned" by this entity/group: */
        struct rt_rq                    *my_q;
 #endif
-};
+} __randomize_layout;
 
 struct sched_dl_entity {
        struct rb_node                  rb_node;
index c06d63b..2a0dd40 100644 (file)
@@ -222,7 +222,7 @@ struct signal_struct {
        struct mutex cred_guard_mutex;  /* guard against foreign influences on
                                         * credential calculations
                                         * (notably. ptrace) */
-};
+} __randomize_layout;
 
 /*
  * Bits in flags field of signal_struct.
index 9edec92..23bcbdf 100644 (file)
@@ -21,7 +21,7 @@ struct sem_array {
        int                     sem_nsems;      /* no. of semaphores in array */
        int                     complex_count;  /* pending complex operations */
        unsigned int            use_global_lock;/* >0: global lock required */
-};
+} __randomize_layout;
 
 #ifdef CONFIG_SYSVIPC
 
index 04e8818..0fb7061 100644 (file)
@@ -22,7 +22,7 @@ struct shmid_kernel /* private to the kernel */
        /* The task created the shm object.  NULL if the task is dead. */
        struct task_struct      *shm_creator;
        struct list_head        shm_clist;      /* list by creator */
-};
+} __randomize_layout;
 
 /* shm_mode upper byte flags */
 #define        SHM_DEST        01000   /* segment will be destroyed on last detach */
index 80d0781..9ddeef2 100644 (file)
@@ -117,7 +117,7 @@ struct ctl_table
        struct ctl_table_poll *poll;
        void *extra1;
        void *extra2;
-};
+} __randomize_layout;
 
 struct ctl_node {
        struct rb_node node;
index d07cd21..73f8d09 100644 (file)
@@ -333,7 +333,7 @@ struct tty_struct {
        /* If the tty has a pending do_SAK, queue it here - akpm */
        struct work_struct SAK_work;
        struct tty_port *port;
-};
+} __randomize_layout;
 
 /* Each of a tty's open files has private_data pointing to tty_file_private */
 struct tty_file_private {
index b742b5e..00b2213 100644 (file)
@@ -291,7 +291,7 @@ struct tty_operations {
        void (*poll_put_char)(struct tty_driver *driver, int line, char ch);
 #endif
        const struct file_operations *proc_fops;
-};
+} __randomize_layout;
 
 struct tty_driver {
        int     magic;          /* magic number for this structure */
@@ -325,7 +325,7 @@ struct tty_driver {
 
        const struct tty_operations *ops;
        struct list_head tty_drivers;
-};
+} __randomize_layout;
 
 extern struct list_head tty_drivers;
 
index 32354b4..b3575ce 100644 (file)
@@ -66,7 +66,7 @@ struct user_namespace {
 #endif
        struct ucounts          *ucounts;
        int ucount_max[UCOUNT_COUNTS];
-};
+} __randomize_layout;
 
 struct ucounts {
        struct hlist_node node;
index 60f0bb8..da826ed 100644 (file)
@@ -26,7 +26,7 @@ struct uts_namespace {
        struct user_namespace *user_ns;
        struct ucounts *ucounts;
        struct ns_common ns;
-};
+} __randomize_layout;
 extern struct uts_namespace init_uts_ns;
 
 #ifdef CONFIG_UTS_NS
index fd60ecc..64e2a1e 100644 (file)
@@ -36,7 +36,7 @@ struct unix_skb_parms {
        u32                     secid;          /* Security ID          */
 #endif
        u32                     consumed;
-};
+} __randomize_layout;
 
 #define UNIXCB(skb)    (*(struct unix_skb_parms *)&((skb)->cb))
 
index e4dd3a2..a62959d 100644 (file)
@@ -155,7 +155,7 @@ struct neighbour {
        struct rcu_head         rcu;
        struct net_device       *dev;
        u8                      primary_key[0];
-};
+} __randomize_layout;
 
 struct neigh_ops {
        int                     family;
index fe80bb4..a224196 100644 (file)
@@ -147,7 +147,7 @@ struct net {
 #endif
        struct sock             *diag_nlsk;
        atomic_t                fnhe_genid;
-};
+} __randomize_layout;
 
 #include <linux/seq_file_net.h>
 
index f33e3d1..d349297 100644 (file)
@@ -1113,7 +1113,7 @@ struct proto {
        atomic_t                socks;
 #endif
        int                     (*diag_destroy)(struct sock *sk, int err);
-};
+} __randomize_layout;
 
 int proto_register(struct proto *prot, int alloc_slab);
 void proto_unregister(struct proto *prot);
index 357348a..5616511 100644 (file)
@@ -212,7 +212,7 @@ struct futex_pi_state {
        atomic_t refcount;
 
        union futex_key key;
-};
+} __randomize_layout;
 
 /**
  * struct futex_q - The hashed futex queue entry, one per waiting task
@@ -246,7 +246,7 @@ struct futex_q {
        struct rt_mutex_waiter *rt_waiter;
        union futex_key *requeue_pi_key;
        u32 bitset;
-};
+} __randomize_layout;
 
 static const struct futex_q futex_q_init = {
        /* list gets initialized in queue_me()*/
index c0f8682..6494954 100644 (file)
@@ -197,7 +197,7 @@ struct request_key_auth {
        void                    *callout_info;
        size_t                  callout_len;
        pid_t                   pid;
-};
+} __randomize_layout;
 
 extern struct key_type key_type_request_key_auth;
 extern struct key *request_key_auth_new(struct key *target,