Commit 3859a271 authored by Kees Cook's avatar Kees Cook

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: default avatarKees Cook <keescook@chromium.org>
parent ffa47aa6
......@@ -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;
......
......@@ -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 */
......
......@@ -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)
{
......
......@@ -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);
......
......@@ -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);
......
......@@ -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 *);
......
......@@ -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 *);
......
......@@ -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:
......
......@@ -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);
......
......@@ -12,7 +12,7 @@ struct fs_struct {
int umask;
int in_exec;
struct path root, pwd;
};
} __randomize_layout;
extern struct kmem_cache *fs_cachep;
......
......@@ -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 */
......@@ -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;
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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
......
......@@ -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;
......
......@@ -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
......
......@@ -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;
......
......@@ -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,
......
......@@ -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 *);
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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.
......
......@@ -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
......
......@@ -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 */
......
......@@ -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;
......
......@@ -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 {
......
......@@ -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;
......
......@@ -66,7 +66,7 @@ struct user_namespace {
#endif
struct ucounts *ucounts;
int ucount_max[UCOUNT_COUNTS];
};
} __randomize_layout;
struct ucounts {
struct hlist_node node;
......
......@@ -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
......
......@@ -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))
......
......@@ -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;
......
......@@ -147,7 +147,7 @@ struct net {
#endif
struct sock *diag_nlsk;
atomic_t fnhe_genid;
};
} __randomize_layout;
#include <linux/seq_file_net.h>
......
......@@ -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);
......
......@@ -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()*/
......
......@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment