summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmese Revfy <re.emese@gmail.com>2016-06-20 14:42:34 -0400
committerKees Cook <keescook@chromium.org>2016-10-10 17:51:45 -0400
commit0766f788eb727e2e330d55d30545db65bcf2623f (patch)
tree0436ae3b005558a4fb827459fe5c602037fe764a
parent38addce8b600ca335dc86fa3d48c890f1c6fa1f4 (diff)
latent_entropy: Mark functions with __latent_entropy
The __latent_entropy gcc attribute can be used only on functions and variables. If it is on a function then the plugin will instrument it for gathering control-flow entropy. If the attribute is on a variable then the plugin will initialize it with random contents. The variable must be an integer, an integer array type or a structure with integer fields. These specific functions have been selected because they are init functions (to help gather boot-time entropy), are called at unpredictable times, or they have variable loops, each of which provide some level of latent entropy. Signed-off-by: Emese Revfy <re.emese@gmail.com> [kees: expanded commit message] Signed-off-by: Kees Cook <keescook@chromium.org>
-rw-r--r--block/blk-softirq.c2
-rw-r--r--drivers/char/random.c4
-rw-r--r--fs/namespace.c1
-rw-r--r--include/linux/compiler-gcc.h7
-rw-r--r--include/linux/compiler.h4
-rw-r--r--include/linux/fdtable.h2
-rw-r--r--include/linux/genhd.h2
-rw-r--r--include/linux/init.h5
-rw-r--r--include/linux/random.h4
-rw-r--r--kernel/fork.c6
-rw-r--r--kernel/rcu/tiny.c2
-rw-r--r--kernel/rcu/tree.c2
-rw-r--r--kernel/sched/fair.c2
-rw-r--r--kernel/softirq.c4
-rw-r--r--kernel/time/timer.c2
-rw-r--r--lib/irq_poll.c2
-rw-r--r--lib/random32.c2
-rw-r--r--mm/page_alloc.c2
-rw-r--r--net/core/dev.c4
19 files changed, 37 insertions, 22 deletions
diff --git a/block/blk-softirq.c b/block/blk-softirq.c
index 53b1737e978d..489eab825a8a 100644
--- a/block/blk-softirq.c
+++ b/block/blk-softirq.c
@@ -18,7 +18,7 @@ static DEFINE_PER_CPU(struct list_head, blk_cpu_done);
18 * Softirq action handler - move entries to local list and loop over them 18 * Softirq action handler - move entries to local list and loop over them
19 * while passing them to the queue registered handler. 19 * while passing them to the queue registered handler.
20 */ 20 */
21static void blk_done_softirq(struct softirq_action *h) 21static __latent_entropy void blk_done_softirq(struct softirq_action *h)
22{ 22{
23 struct list_head *cpu_list, local_list; 23 struct list_head *cpu_list, local_list;
24 24
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 3efb3bf0ab83..7274ae89ddb3 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -479,8 +479,8 @@ static ssize_t _extract_entropy(struct entropy_store *r, void *buf,
479 479
480static void crng_reseed(struct crng_state *crng, struct entropy_store *r); 480static void crng_reseed(struct crng_state *crng, struct entropy_store *r);
481static void push_to_pool(struct work_struct *work); 481static void push_to_pool(struct work_struct *work);
482static __u32 input_pool_data[INPUT_POOL_WORDS]; 482static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy;
483static __u32 blocking_pool_data[OUTPUT_POOL_WORDS]; 483static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy;
484 484
485static struct entropy_store input_pool = { 485static struct entropy_store input_pool = {
486 .poolinfo = &poolinfo_table[0], 486 .poolinfo = &poolinfo_table[0],
diff --git a/fs/namespace.c b/fs/namespace.c
index 7bb2cda3bfef..4a9568b81138 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2759,6 +2759,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns)
2759 return new_ns; 2759 return new_ns;
2760} 2760}
2761 2761
2762__latent_entropy
2762struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, 2763struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
2763 struct user_namespace *user_ns, struct fs_struct *new_fs) 2764 struct user_namespace *user_ns, struct fs_struct *new_fs)
2764{ 2765{
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 573c5a18908f..432f5c97e18f 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -188,6 +188,13 @@
188#endif /* GCC_VERSION >= 40300 */ 188#endif /* GCC_VERSION >= 40300 */
189 189
190#if GCC_VERSION >= 40500 190#if GCC_VERSION >= 40500
191
192#ifndef __CHECKER__
193#ifdef LATENT_ENTROPY_PLUGIN
194#define __latent_entropy __attribute__((latent_entropy))
195#endif
196#endif
197
191/* 198/*
192 * Mark a position in code as unreachable. This can be used to 199 * Mark a position in code as unreachable. This can be used to
193 * suppress control flow warnings after asm blocks that transfer 200 * suppress control flow warnings after asm blocks that transfer
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 668569844d37..ceaddaf76ff1 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -406,6 +406,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
406# define __attribute_const__ /* unimplemented */ 406# define __attribute_const__ /* unimplemented */
407#endif 407#endif
408 408
409#ifndef __latent_entropy
410# define __latent_entropy
411#endif
412
409/* 413/*
410 * Tell gcc if a function is cold. The compiler will assume any path 414 * Tell gcc if a function is cold. The compiler will assume any path
411 * directly leading to the call is unlikely. 415 * directly leading to the call is unlikely.
diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h
index 5295535b60c6..9852c7e33466 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -105,7 +105,7 @@ struct files_struct *get_files_struct(struct task_struct *);
105void put_files_struct(struct files_struct *fs); 105void put_files_struct(struct files_struct *fs);
106void reset_files_struct(struct files_struct *); 106void reset_files_struct(struct files_struct *);
107int unshare_files(struct files_struct **); 107int unshare_files(struct files_struct **);
108struct files_struct *dup_fd(struct files_struct *, int *); 108struct files_struct *dup_fd(struct files_struct *, int *) __latent_entropy;
109void do_close_on_exec(struct files_struct *); 109void do_close_on_exec(struct files_struct *);
110int iterate_fd(struct files_struct *, unsigned, 110int iterate_fd(struct files_struct *, unsigned,
111 int (*)(const void *, struct file *, unsigned), 111 int (*)(const void *, struct file *, unsigned),
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 1dbf52f9c24b..e0341af6950e 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -437,7 +437,7 @@ extern void disk_flush_events(struct gendisk *disk, unsigned int mask);
437extern unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask); 437extern unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask);
438 438
439/* drivers/char/random.c */ 439/* drivers/char/random.c */
440extern void add_disk_randomness(struct gendisk *disk); 440extern void add_disk_randomness(struct gendisk *disk) __latent_entropy;
441extern void rand_initialize_disk(struct gendisk *disk); 441extern void rand_initialize_disk(struct gendisk *disk);
442 442
443static inline sector_t get_start_sect(struct block_device *bdev) 443static inline sector_t get_start_sect(struct block_device *bdev)
diff --git a/include/linux/init.h b/include/linux/init.h
index 6935d02474aa..1e5c131d5c9a 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -39,7 +39,7 @@
39 39
40/* These are for everybody (although not all archs will actually 40/* These are for everybody (although not all archs will actually
41 discard it in modules) */ 41 discard it in modules) */
42#define __init __section(.init.text) __cold notrace 42#define __init __section(.init.text) __cold notrace __latent_entropy
43#define __initdata __section(.init.data) 43#define __initdata __section(.init.data)
44#define __initconst __constsection(.init.rodata) 44#define __initconst __constsection(.init.rodata)
45#define __exitdata __section(.exit.data) 45#define __exitdata __section(.exit.data)
@@ -86,7 +86,8 @@
86#define __exit __section(.exit.text) __exitused __cold notrace 86#define __exit __section(.exit.text) __exitused __cold notrace
87 87
88/* Used for MEMORY_HOTPLUG */ 88/* Used for MEMORY_HOTPLUG */
89#define __meminit __section(.meminit.text) __cold notrace 89#define __meminit __section(.meminit.text) __cold notrace \
90 __latent_entropy
90#define __meminitdata __section(.meminit.data) 91#define __meminitdata __section(.meminit.data)
91#define __meminitconst __constsection(.meminit.rodata) 92#define __meminitconst __constsection(.meminit.rodata)
92#define __memexit __section(.memexit.text) __exitused __cold notrace 93#define __memexit __section(.memexit.text) __exitused __cold notrace
diff --git a/include/linux/random.h b/include/linux/random.h
index a59c74cdb1eb..d80a4388a4fd 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -30,8 +30,8 @@ static inline void add_latent_entropy(void) {}
30#endif 30#endif
31 31
32extern void add_input_randomness(unsigned int type, unsigned int code, 32extern void add_input_randomness(unsigned int type, unsigned int code,
33 unsigned int value); 33 unsigned int value) __latent_entropy;
34extern void add_interrupt_randomness(int irq, int irq_flags); 34extern void add_interrupt_randomness(int irq, int irq_flags) __latent_entropy;
35 35
36extern void get_random_bytes(void *buf, int nbytes); 36extern void get_random_bytes(void *buf, int nbytes);
37extern int add_random_ready_callback(struct random_ready_callback *rdy); 37extern int add_random_ready_callback(struct random_ready_callback *rdy);
diff --git a/kernel/fork.c b/kernel/fork.c
index 001b18473a07..05393881ef39 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -404,7 +404,8 @@ free_tsk:
404} 404}
405 405
406#ifdef CONFIG_MMU 406#ifdef CONFIG_MMU
407static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) 407static __latent_entropy int dup_mmap(struct mm_struct *mm,
408 struct mm_struct *oldmm)
408{ 409{
409 struct vm_area_struct *mpnt, *tmp, *prev, **pprev; 410 struct vm_area_struct *mpnt, *tmp, *prev, **pprev;
410 struct rb_node **rb_link, *rb_parent; 411 struct rb_node **rb_link, *rb_parent;
@@ -1296,7 +1297,8 @@ init_task_pid(struct task_struct *task, enum pid_type type, struct pid *pid)
1296 * parts of the process environment (as per the clone 1297 * parts of the process environment (as per the clone
1297 * flags). The actual kick-off is left to the caller. 1298 * flags). The actual kick-off is left to the caller.
1298 */ 1299 */
1299static struct task_struct *copy_process(unsigned long clone_flags, 1300static __latent_entropy struct task_struct *copy_process(
1301 unsigned long clone_flags,
1300 unsigned long stack_start, 1302 unsigned long stack_start,
1301 unsigned long stack_size, 1303 unsigned long stack_size,
1302 int __user *child_tidptr, 1304 int __user *child_tidptr,
diff --git a/kernel/rcu/tiny.c b/kernel/rcu/tiny.c
index 944b1b491ed8..1898559e6b60 100644
--- a/kernel/rcu/tiny.c
+++ b/kernel/rcu/tiny.c
@@ -170,7 +170,7 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
170 false)); 170 false));
171} 171}
172 172
173static void rcu_process_callbacks(struct softirq_action *unused) 173static __latent_entropy void rcu_process_callbacks(struct softirq_action *unused)
174{ 174{
175 __rcu_process_callbacks(&rcu_sched_ctrlblk); 175 __rcu_process_callbacks(&rcu_sched_ctrlblk);
176 __rcu_process_callbacks(&rcu_bh_ctrlblk); 176 __rcu_process_callbacks(&rcu_bh_ctrlblk);
diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
index 5d80925e7fc8..e5164deb51e1 100644
--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -3013,7 +3013,7 @@ __rcu_process_callbacks(struct rcu_state *rsp)
3013/* 3013/*
3014 * Do RCU core processing for the current CPU. 3014 * Do RCU core processing for the current CPU.
3015 */ 3015 */
3016static void rcu_process_callbacks(struct softirq_action *unused) 3016static __latent_entropy void rcu_process_callbacks(struct softirq_action *unused)
3017{ 3017{
3018 struct rcu_state *rsp; 3018 struct rcu_state *rsp;
3019 3019
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 039de34f1521..004996df2f10 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -8283,7 +8283,7 @@ static void nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle) { }
8283 * run_rebalance_domains is triggered when needed from the scheduler tick. 8283 * run_rebalance_domains is triggered when needed from the scheduler tick.
8284 * Also triggered for nohz idle balancing (with nohz_balancing_kick set). 8284 * Also triggered for nohz idle balancing (with nohz_balancing_kick set).
8285 */ 8285 */
8286static void run_rebalance_domains(struct softirq_action *h) 8286static __latent_entropy void run_rebalance_domains(struct softirq_action *h)
8287{ 8287{
8288 struct rq *this_rq = this_rq(); 8288 struct rq *this_rq = this_rq();
8289 enum cpu_idle_type idle = this_rq->idle_balance ? 8289 enum cpu_idle_type idle = this_rq->idle_balance ?
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 17caf4b63342..34033fd09c8c 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -482,7 +482,7 @@ void __tasklet_hi_schedule_first(struct tasklet_struct *t)
482} 482}
483EXPORT_SYMBOL(__tasklet_hi_schedule_first); 483EXPORT_SYMBOL(__tasklet_hi_schedule_first);
484 484
485static void tasklet_action(struct softirq_action *a) 485static __latent_entropy void tasklet_action(struct softirq_action *a)
486{ 486{
487 struct tasklet_struct *list; 487 struct tasklet_struct *list;
488 488
@@ -518,7 +518,7 @@ static void tasklet_action(struct softirq_action *a)
518 } 518 }
519} 519}
520 520
521static void tasklet_hi_action(struct softirq_action *a) 521static __latent_entropy void tasklet_hi_action(struct softirq_action *a)
522{ 522{
523 struct tasklet_struct *list; 523 struct tasklet_struct *list;
524 524
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index 32bf6f75a8fe..2d47980a1bc4 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1633,7 +1633,7 @@ static inline void __run_timers(struct timer_base *base)
1633/* 1633/*
1634 * This function runs timers and the timer-tq in bottom half context. 1634 * This function runs timers and the timer-tq in bottom half context.
1635 */ 1635 */
1636static void run_timer_softirq(struct softirq_action *h) 1636static __latent_entropy void run_timer_softirq(struct softirq_action *h)
1637{ 1637{
1638 struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]); 1638 struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]);
1639 1639
diff --git a/lib/irq_poll.c b/lib/irq_poll.c
index 836f7db4e548..63be7495dbb2 100644
--- a/lib/irq_poll.c
+++ b/lib/irq_poll.c
@@ -74,7 +74,7 @@ void irq_poll_complete(struct irq_poll *iop)
74} 74}
75EXPORT_SYMBOL(irq_poll_complete); 75EXPORT_SYMBOL(irq_poll_complete);
76 76
77static void irq_poll_softirq(struct softirq_action *h) 77static void __latent_entropy irq_poll_softirq(struct softirq_action *h)
78{ 78{
79 struct list_head *list = this_cpu_ptr(&blk_cpu_iopoll); 79 struct list_head *list = this_cpu_ptr(&blk_cpu_iopoll);
80 int rearm = 0, budget = irq_poll_budget; 80 int rearm = 0, budget = irq_poll_budget;
diff --git a/lib/random32.c b/lib/random32.c
index 69ed593aab07..a30923573676 100644
--- a/lib/random32.c
+++ b/lib/random32.c
@@ -47,7 +47,7 @@ static inline void prandom_state_selftest(void)
47} 47}
48#endif 48#endif
49 49
50static DEFINE_PER_CPU(struct rnd_state, net_rand_state); 50static DEFINE_PER_CPU(struct rnd_state, net_rand_state) __latent_entropy;
51 51
52/** 52/**
53 * prandom_u32_state - seeded pseudo-random number generator. 53 * prandom_u32_state - seeded pseudo-random number generator.
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 248851d1fc86..901121af4e54 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -92,7 +92,7 @@ int _node_numa_mem_[MAX_NUMNODES];
92#endif 92#endif
93 93
94#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY 94#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
95volatile u64 latent_entropy; 95volatile u64 latent_entropy __latent_entropy;
96EXPORT_SYMBOL(latent_entropy); 96EXPORT_SYMBOL(latent_entropy);
97#endif 97#endif
98 98
diff --git a/net/core/dev.c b/net/core/dev.c
index ea6312057a71..ee076c2791f9 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3855,7 +3855,7 @@ int netif_rx_ni(struct sk_buff *skb)
3855} 3855}
3856EXPORT_SYMBOL(netif_rx_ni); 3856EXPORT_SYMBOL(netif_rx_ni);
3857 3857
3858static void net_tx_action(struct softirq_action *h) 3858static __latent_entropy void net_tx_action(struct softirq_action *h)
3859{ 3859{
3860 struct softnet_data *sd = this_cpu_ptr(&softnet_data); 3860 struct softnet_data *sd = this_cpu_ptr(&softnet_data);
3861 3861
@@ -5187,7 +5187,7 @@ out_unlock:
5187 return work; 5187 return work;
5188} 5188}
5189 5189
5190static void net_rx_action(struct softirq_action *h) 5190static __latent_entropy void net_rx_action(struct softirq_action *h)
5191{ 5191{
5192 struct softnet_data *sd = this_cpu_ptr(&softnet_data); 5192 struct softnet_data *sd = this_cpu_ptr(&softnet_data);
5193 unsigned long time_limit = jiffies + 2; 5193 unsigned long time_limit = jiffies + 2;