Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

randstruct: Mark various structs for randomization

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>

+57 -56
+1 -1
arch/x86/include/asm/processor.h
··· 129 129 /* Index into per_cpu list: */ 130 130 u16 cpu_index; 131 131 u32 microcode; 132 - }; 132 + } __randomize_layout; 133 133 134 134 struct cpuid_regs { 135 135 u32 eax, ebx, ecx, edx;
+2 -2
fs/mount.h
··· 16 16 u64 event; 17 17 unsigned int mounts; /* # of mounts in the namespace */ 18 18 unsigned int pending_mounts; 19 - }; 19 + } __randomize_layout; 20 20 21 21 struct mnt_pcp { 22 22 int mnt_count; ··· 68 68 struct hlist_head mnt_pins; 69 69 struct fs_pin mnt_umount; 70 70 struct dentry *mnt_ex_mountpoint; 71 - }; 71 + } __randomize_layout; 72 72 73 73 #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */ 74 74
+1 -1
fs/namei.c
··· 524 524 struct inode *link_inode; 525 525 unsigned root_seq; 526 526 int dfd; 527 - }; 527 + } __randomize_layout; 528 528 529 529 static void set_nameidata(struct nameidata *p, int dfd, struct filename *name) 530 530 {
+3 -3
fs/proc/internal.h
··· 51 51 spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */ 52 52 u8 namelen; 53 53 char name[]; 54 - }; 54 + } __randomize_layout; 55 55 56 56 union proc_op { 57 57 int (*proc_get_link)(struct dentry *, struct path *); ··· 70 70 struct list_head sysctl_inodes; 71 71 const struct proc_ns_operations *ns_ops; 72 72 struct inode vfs_inode; 73 - }; 73 + } __randomize_layout; 74 74 75 75 /* 76 76 * General functions ··· 279 279 #ifdef CONFIG_NUMA 280 280 struct mempolicy *task_mempolicy; 281 281 #endif 282 - }; 282 + } __randomize_layout; 283 283 284 284 struct mm_struct *proc_mem_open(struct inode *inode, unsigned int mode); 285 285
+2 -2
include/linux/binfmts.h
··· 46 46 unsigned interp_flags; 47 47 unsigned interp_data; 48 48 unsigned long loader, exec; 49 - }; 49 + } __randomize_layout; 50 50 51 51 #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0 52 52 #define BINPRM_FLAGS_ENFORCE_NONDUMP (1 << BINPRM_FLAGS_ENFORCE_NONDUMP_BIT) ··· 81 81 int (*load_shlib)(struct file *); 82 82 int (*core_dump)(struct coredump_params *cprm); 83 83 unsigned long min_coredump; /* minimal dump size */ 84 - }; 84 + } __randomize_layout; 85 85 86 86 extern void __register_binfmt(struct linux_binfmt *fmt, int insert); 87 87
+1 -1
include/linux/cdev.h
··· 17 17 struct list_head list; 18 18 dev_t dev; 19 19 unsigned int count; 20 - }; 20 + } __randomize_layout; 21 21 22 22 void cdev_init(struct cdev *, const struct file_operations *); 23 23
+2 -2
include/linux/cred.h
··· 31 31 atomic_t usage; 32 32 int ngroups; 33 33 kgid_t gid[0]; 34 - }; 34 + } __randomize_layout; 35 35 36 36 /** 37 37 * get_group_info - Get a reference to a group info structure ··· 145 145 struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */ 146 146 struct group_info *group_info; /* supplementary groups for euid/fsgid */ 147 147 struct rcu_head rcu; /* RCU deletion hook */ 148 - }; 148 + } __randomize_layout; 149 149 150 150 extern void __put_cred(struct cred *); 151 151 extern void exit_creds(struct task_struct *);
+1 -1
include/linux/dcache.h
··· 113 113 struct hlist_bl_node d_in_lookup_hash; /* only for in-lookup ones */ 114 114 struct rcu_head d_rcu; 115 115 } d_u; 116 - }; 116 + } __randomize_layout; 117 117 118 118 /* 119 119 * dentry->d_lock spinlock nesting subclasses:
+9 -8
include/linux/fs.h
··· 275 275 void (*ki_complete)(struct kiocb *iocb, long ret, long ret2); 276 276 void *private; 277 277 int ki_flags; 278 - }; 278 + } __randomize_layout; 279 279 280 280 static inline bool is_sync_kiocb(struct kiocb *kiocb) 281 281 { ··· 392 392 gfp_t gfp_mask; /* implicit gfp mask for allocations */ 393 393 struct list_head private_list; /* ditto */ 394 394 void *private_data; /* ditto */ 395 - } __attribute__((aligned(sizeof(long)))); 395 + } __attribute__((aligned(sizeof(long)))) __randomize_layout; 396 396 /* 397 397 * On most architectures that alignment is already the case; but 398 398 * must be enforced here for CRIS, to let the least significant bit ··· 435 435 int bd_fsfreeze_count; 436 436 /* Mutex for freeze */ 437 437 struct mutex bd_fsfreeze_mutex; 438 - }; 438 + } __randomize_layout; 439 439 440 440 /* 441 441 * Radix-tree tags, for tagging dirty and writeback pages within the pagecache ··· 653 653 #endif 654 654 655 655 void *i_private; /* fs or device private pointer */ 656 - }; 656 + } __randomize_layout; 657 657 658 658 static inline unsigned int i_blocksize(const struct inode *node) 659 659 { ··· 868 868 struct list_head f_tfile_llink; 869 869 #endif /* #ifdef CONFIG_EPOLL */ 870 870 struct address_space *f_mapping; 871 - } __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */ 871 + } __randomize_layout 872 + __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */ 872 873 873 874 struct file_handle { 874 875 __u32 handle_bytes; ··· 1006 1005 int state; /* state of grant or error if -ve */ 1007 1006 } afs; 1008 1007 } fl_u; 1009 - }; 1008 + } __randomize_layout; 1010 1009 1011 1010 struct file_lock_context { 1012 1011 spinlock_t flc_lock; ··· 1405 1404 1406 1405 spinlock_t s_inode_wblist_lock; 1407 1406 struct list_head s_inodes_wb; /* writeback inodes */ 1408 - }; 1407 + } __randomize_layout; 1409 1408 1410 1409 /* Helper functions so that in most cases filesystems will 1411 1410 * not need to deal directly with kuid_t and kgid_t and can ··· 1691 1690 u64); 1692 1691 ssize_t (*dedupe_file_range)(struct file *, u64, u64, struct file *, 1693 1692 u64); 1694 - }; 1693 + } __randomize_layout; 1695 1694 1696 1695 struct inode_operations { 1697 1696 struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
+1 -1
include/linux/fs_struct.h
··· 12 12 int umask; 13 13 int in_exec; 14 14 struct path root, pwd; 15 - }; 15 + } __randomize_layout; 16 16 17 17 extern struct kmem_cache *fs_cachep; 18 18
+1 -1
include/linux/ipc.h
··· 20 20 umode_t mode; 21 21 unsigned long seq; 22 22 void *security; 23 - } ____cacheline_aligned_in_smp; 23 + } ____cacheline_aligned_in_smp __randomize_layout; 24 24 25 25 #endif /* _LINUX_IPC_H */
+1 -1
include/linux/ipc_namespace.h
··· 61 61 struct ucounts *ucounts; 62 62 63 63 struct ns_common ns; 64 - }; 64 + } __randomize_layout; 65 65 66 66 extern struct ipc_namespace init_ipc_ns; 67 67 extern spinlock_t mq_lock;
+2 -2
include/linux/key-type.h
··· 45 45 size_t datalen; /* Raw datalen */ 46 46 size_t quotalen; /* Quota length for proposed payload */ 47 47 time_t expiry; /* Expiry time of key */ 48 - }; 48 + } __randomize_layout; 49 49 50 50 typedef int (*request_key_actor_t)(struct key_construction *key, 51 51 const char *op, void *aux); ··· 158 158 /* internal fields */ 159 159 struct list_head link; /* link in types list */ 160 160 struct lock_class_key lock_class; /* key->sem lock class */ 161 - }; 161 + } __randomize_layout; 162 162 163 163 extern struct key_type key_type_keyring; 164 164
+1 -1
include/linux/kmod.h
··· 64 64 int (*init)(struct subprocess_info *info, struct cred *new); 65 65 void (*cleanup)(struct subprocess_info *info); 66 66 void *data; 67 - }; 67 + } __randomize_layout; 68 68 69 69 extern int 70 70 call_usermodehelper(const char *path, char **argv, char **envp, int wait);
+1 -1
include/linux/kobject.h
··· 172 172 spinlock_t list_lock; 173 173 struct kobject kobj; 174 174 const struct kset_uevent_ops *uevent_ops; 175 - }; 175 + } __randomize_layout; 176 176 177 177 extern void kset_init(struct kset *kset); 178 178 extern int __must_check kset_register(struct kset *kset);
+2 -2
include/linux/lsm_hooks.h
··· 1876 1876 struct list_head audit_rule_match; 1877 1877 struct list_head audit_rule_free; 1878 1878 #endif /* CONFIG_AUDIT */ 1879 - }; 1879 + } __randomize_layout; 1880 1880 1881 1881 /* 1882 1882 * Security module hook list structure. ··· 1887 1887 struct list_head *head; 1888 1888 union security_list_options hook; 1889 1889 char *lsm; 1890 - }; 1890 + } __randomize_layout; 1891 1891 1892 1892 /* 1893 1893 * Initializing a security_hook_list structure takes
+2 -2
include/linux/mm_types.h
··· 342 342 struct mempolicy *vm_policy; /* NUMA policy for the VMA */ 343 343 #endif 344 344 struct vm_userfaultfd_ctx vm_userfaultfd_ctx; 345 - }; 345 + } __randomize_layout; 346 346 347 347 struct core_thread { 348 348 struct task_struct *task; ··· 500 500 atomic_long_t hugetlb_usage; 501 501 #endif 502 502 struct work_struct async_put_work; 503 - }; 503 + } __randomize_layout; 504 504 505 505 extern struct mm_struct init_mm; 506 506
+2 -2
include/linux/module.h
··· 45 45 struct kobject *drivers_dir; 46 46 struct module_param_attrs *mp; 47 47 struct completion *kobj_completion; 48 - }; 48 + } __randomize_layout; 49 49 50 50 struct module_attribute { 51 51 struct attribute attr; ··· 475 475 ctor_fn_t *ctors; 476 476 unsigned int num_ctors; 477 477 #endif 478 - } ____cacheline_aligned; 478 + } ____cacheline_aligned __randomize_layout; 479 479 #ifndef MODULE_ARCH_INIT 480 480 #define MODULE_ARCH_INIT {} 481 481 #endif
+1 -1
include/linux/mount.h
··· 67 67 struct dentry *mnt_root; /* root of the mounted tree */ 68 68 struct super_block *mnt_sb; /* pointer to superblock */ 69 69 int mnt_flags; 70 - }; 70 + } __randomize_layout; 71 71 72 72 struct file; /* forward dec */ 73 73 struct path;
+1 -1
include/linux/msg.h
··· 29 29 struct list_head q_messages; 30 30 struct list_head q_receivers; 31 31 struct list_head q_senders; 32 - }; 32 + } __randomize_layout; 33 33 34 34 /* Helper routines for sys_msgsnd and sys_msgrcv */ 35 35 extern long do_msgsnd(int msqid, long mtype, void __user *mtext,
+1 -1
include/linux/path.h
··· 7 7 struct path { 8 8 struct vfsmount *mnt; 9 9 struct dentry *dentry; 10 - }; 10 + } __randomize_layout; 11 11 12 12 extern void path_get(const struct path *); 13 13 extern void path_put(const struct path *);
+1 -1
include/linux/pid_namespace.h
··· 52 52 int hide_pid; 53 53 int reboot; /* group exit code if this pidns was rebooted */ 54 54 struct ns_common ns; 55 - }; 55 + } __randomize_layout; 56 56 57 57 extern struct pid_namespace init_pid_ns; 58 58
+1 -1
include/linux/proc_ns.h
··· 21 21 int (*install)(struct nsproxy *nsproxy, struct ns_common *ns); 22 22 struct user_namespace *(*owner)(struct ns_common *ns); 23 23 struct ns_common *(*get_parent)(struct ns_common *ns); 24 - }; 24 + } __randomize_layout; 25 25 26 26 extern const struct proc_ns_operations netns_operations; 27 27 extern const struct proc_ns_operations utsns_operations;
+1 -1
include/linux/sched.h
··· 408 408 /* rq "owned" by this entity/group: */ 409 409 struct rt_rq *my_q; 410 410 #endif 411 - }; 411 + } __randomize_layout; 412 412 413 413 struct sched_dl_entity { 414 414 struct rb_node rb_node;
+1 -1
include/linux/sched/signal.h
··· 222 222 struct mutex cred_guard_mutex; /* guard against foreign influences on 223 223 * credential calculations 224 224 * (notably. ptrace) */ 225 - }; 225 + } __randomize_layout; 226 226 227 227 /* 228 228 * Bits in flags field of signal_struct.
+1 -1
include/linux/sem.h
··· 21 21 int sem_nsems; /* no. of semaphores in array */ 22 22 int complex_count; /* pending complex operations */ 23 23 unsigned int use_global_lock;/* >0: global lock required */ 24 - }; 24 + } __randomize_layout; 25 25 26 26 #ifdef CONFIG_SYSVIPC 27 27
+1 -1
include/linux/shm.h
··· 22 22 /* The task created the shm object. NULL if the task is dead. */ 23 23 struct task_struct *shm_creator; 24 24 struct list_head shm_clist; /* list by creator */ 25 - }; 25 + } __randomize_layout; 26 26 27 27 /* shm_mode upper byte flags */ 28 28 #define SHM_DEST 01000 /* segment will be destroyed on last detach */
+1 -1
include/linux/sysctl.h
··· 117 117 struct ctl_table_poll *poll; 118 118 void *extra1; 119 119 void *extra2; 120 - }; 120 + } __randomize_layout; 121 121 122 122 struct ctl_node { 123 123 struct rb_node node;
+1 -1
include/linux/tty.h
··· 333 333 /* If the tty has a pending do_SAK, queue it here - akpm */ 334 334 struct work_struct SAK_work; 335 335 struct tty_port *port; 336 - }; 336 + } __randomize_layout; 337 337 338 338 /* Each of a tty's open files has private_data pointing to tty_file_private */ 339 339 struct tty_file_private {
+2 -2
include/linux/tty_driver.h
··· 291 291 void (*poll_put_char)(struct tty_driver *driver, int line, char ch); 292 292 #endif 293 293 const struct file_operations *proc_fops; 294 - }; 294 + } __randomize_layout; 295 295 296 296 struct tty_driver { 297 297 int magic; /* magic number for this structure */ ··· 325 325 326 326 const struct tty_operations *ops; 327 327 struct list_head tty_drivers; 328 - }; 328 + } __randomize_layout; 329 329 330 330 extern struct list_head tty_drivers; 331 331
+1 -1
include/linux/user_namespace.h
··· 66 66 #endif 67 67 struct ucounts *ucounts; 68 68 int ucount_max[UCOUNT_COUNTS]; 69 - }; 69 + } __randomize_layout; 70 70 71 71 struct ucounts { 72 72 struct hlist_node node;
+1 -1
include/linux/utsname.h
··· 26 26 struct user_namespace *user_ns; 27 27 struct ucounts *ucounts; 28 28 struct ns_common ns; 29 - }; 29 + } __randomize_layout; 30 30 extern struct uts_namespace init_uts_ns; 31 31 32 32 #ifdef CONFIG_UTS_NS
+1 -1
include/net/af_unix.h
··· 36 36 u32 secid; /* Security ID */ 37 37 #endif 38 38 u32 consumed; 39 - }; 39 + } __randomize_layout; 40 40 41 41 #define UNIXCB(skb) (*(struct unix_skb_parms *)&((skb)->cb)) 42 42
+1 -1
include/net/neighbour.h
··· 155 155 struct rcu_head rcu; 156 156 struct net_device *dev; 157 157 u8 primary_key[0]; 158 - }; 158 + } __randomize_layout; 159 159 160 160 struct neigh_ops { 161 161 int family;
+1 -1
include/net/net_namespace.h
··· 147 147 #endif 148 148 struct sock *diag_nlsk; 149 149 atomic_t fnhe_genid; 150 - }; 150 + } __randomize_layout; 151 151 152 152 #include <linux/seq_file_net.h> 153 153
+1 -1
include/net/sock.h
··· 1113 1113 atomic_t socks; 1114 1114 #endif 1115 1115 int (*diag_destroy)(struct sock *sk, int err); 1116 - }; 1116 + } __randomize_layout; 1117 1117 1118 1118 int proto_register(struct proto *prot, int alloc_slab); 1119 1119 void proto_unregister(struct proto *prot);
+2 -2
kernel/futex.c
··· 212 212 atomic_t refcount; 213 213 214 214 union futex_key key; 215 - }; 215 + } __randomize_layout; 216 216 217 217 /** 218 218 * struct futex_q - The hashed futex queue entry, one per waiting task ··· 246 246 struct rt_mutex_waiter *rt_waiter; 247 247 union futex_key *requeue_pi_key; 248 248 u32 bitset; 249 - }; 249 + } __randomize_layout; 250 250 251 251 static const struct futex_q futex_q_init = { 252 252 /* list gets initialized in queue_me()*/
+1 -1
security/keys/internal.h
··· 197 197 void *callout_info; 198 198 size_t callout_len; 199 199 pid_t pid; 200 - }; 200 + } __randomize_layout; 201 201 202 202 extern struct key_type key_type_request_key_auth; 203 203 extern struct key *request_key_auth_new(struct key *target,