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 3cada998a402a7893ffd2fc709916f4fcbc3f970..e2335edb9fc560ec363f818f04d183375dd28552 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 bf1fda6eed8f36beae7e678a0be8e78cd9317201..e406b286fba11b24ac4d86a288276e6c46a4764d 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 6571a5f5112ed82894fdbec1c9b6dfaf557d93b1..1764620ac383e5ce66d442325dfac4d90aab43de 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 c5ae09b6c726ab8d8d01043a2d896f752727d0a4..07b16318223fc2be0e951a3bbf1292433947aa02 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 05488da3aee9db28e3a233564421efe6971a2a32..3ae9013eeaaa4367bb160aef88b36ab549b0446d 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 408bc09ce497bb14fdd058b11debbdda7c22fa78..cb28eb21e3ca52054fbb65d72e22c93127aaf472 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 b03e7d049a64f4ca0081d78e93c49fda898a9733..82c8a9e1aabbf7278db29012ffbffa446cdb0aa6 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 d2e38dc6172c0670472e654103f2f0bfa0d1b2ba..7eb262e13d3c47454a719e114d8a20c5ef746fcc 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 803e5a9b265422d2c2034678331b6d4dd353d1de..8f28143486c402c49db9c1cfd2e8425f124dd5a9 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 0efc3e62843ae74592128dc7e34bd11fbaca4a3c..7a026240cbb1bc0b45f65ac9b14a1f1823501c06 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 71fd92d81b266edf1781c542de550159bc33949a..ea0eb0b5f98cd5f91d49cf73e47227782b4acd77 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 848e5796400e797a57fb0ab253c6accc215ed9d4..65327ee0936b314fe38fffee3ffb5f882d8883ac 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 8496cf64575c679b49a0eeedf0c0d3c4d1e2dd1c..9520fc3c3b9ab376ae571cb9895d0dc838212ffc 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 c4e441e00db57c85103e93ffedd16674762df5af..655082c88fd93b5057fc641d196aae66d805850b 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 ca85cb80e99a60e33df79e2ed0d8815953d1d21d..0845133503178c5ac722d395f476c6ed375793d8 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 080f34e66017a8299d10bc4276b1acfe8a1f94cc..565163fc9ad43387ded2be94309a1b82a3099c1d 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 45cdb27791a33ff8d494549ce92f080a93434889..ff151814a02d98b613237d1602839fd18358e115 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 21f56393602f2000b901238cd9a7911e23e04448..d93111d7def6cd6a64f3ffea956808b8d19d82fc 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 8e0352af06b786fb0cccde2022af945772f5091e..1ce85e6fd95f798a2e0f2afbb470515d8b0e40dd 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 f3f302f9c1975a67ea1c01a828403950fac8a061..a001305f5a79959a5e4f816320f3c4276e308e12 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 d1372186f4315c3de45b3949017026dca2d7f109..cde895cc4af4cd5053f1a0f477f15c6a1240eedc 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 c2a989dee876360d85f305965e34c1dddc0a9c12..b09136f88cf45c3bd84064a88f441c41da6730b3 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 58ab28d81fc2ecd4f78f37a81ac07a56d984f2e5..06844b54dfc17a222dc42ce17d4cde5e0d848a8e 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 2b69fc65020131bed57e41d4b228ed0c59692a5c..f833254fce00926bc52d8ffab3c34701a414faa9 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 c06d63b3a58389b92483bb6a0f24f427324ac000..2a0dd40b15dbae8c49c6196ee9d13b6146f2df8d 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 9edec926e9d968a3900ec0f683b039a6cf6f6ef7..23bcbdfad4a6aff208540f03014e0d629184bc99 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 04e88182962511da30753010075c42f8ab30f086..0fb7061ec54c13d29e36ba5b6f09628f4f2ba676 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 80d07816def05bf0f7662c46d56387830dec3d57..9ddeef2c03e227555c1ee29b8c44f6612878f240 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 d07cd2105a6c6a3bdcac20c918622c7ad4ea0840..73f8d0977bb0bc8312105ee7b70d0be86e6d834c 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 b742b5e47cc209ac60e441cc42fcf8f431239fab..00b2213f6a35564974d5be7ac7ba909c464d3e01 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 32354b4b4b2ba5ae72034d00c3b1d43fa8c2a15c..b3575ce291483284847ccc7eef5fea679fade38b 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 60f0bb83b313af0e5429264bb83296735c8cdf01..da826ed059cfd7de52135a40caafe5589b52d2d6 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 fd60eccb59a67969eba53416a376a3c912d62d81..64e2a1e24a2cfec66542bb5c7524559ac76a79a7 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 e4dd3a2140341049fabfbff1ec55406fbe11d5b2..a62959d2b3f7b1748d9674ed9ff3508c8a8fd7b1 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 fe80bb48ab1f0c7b1665a10a9bf2388b32eb5013..a224196d16ac9d2d337f76929ac1231520ea9e59 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 f33e3d134e0b7f66329f2122d7acc8b396c1787b..d349297db9e9e2be03124eb150c17fd50543c65c 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 357348a6cf6b4d71dbc24c9ad89ad2d0e63b20d2..5616511abf39d09fcd7faeb4d4a86cf17e608772 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 c0f8682eba69a5d89af203f4979df65102b95909..6494954e9980ac7bc9e70b75f512557322cd9597 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,