From patchwork Mon May 23 22:16:29 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Emese Revfy X-Patchwork-Id: 9132459 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3A10A607D5 for ; Mon, 23 May 2016 22:09:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2EDF328164 for ; Mon, 23 May 2016 22:09:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 236722824D; Mon, 23 May 2016 22:09:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 7E0F728164 for ; Mon, 23 May 2016 22:09:40 +0000 (UTC) Received: (qmail 10003 invoked by uid 550); 23 May 2016 22:09:38 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: kernel-hardening@lists.openwall.com Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 9985 invoked from network); 23 May 2016 22:09:38 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rybpCaA/uXhSYglQaynT5LUCctq4ys0+Cf7W0HMJmQc=; b=gFOJsPJMxCa0gOjeMuU7oVJSrmzv01F6XMu89lyDY3EUcGxNTIDEx5etLrelBbHC5D PfGRMRpC6bDgSQTDQXJ0bDVhLgPyr3XATfy90YiUcQIfoEHdA9LOXdPsCRtgzKWw1+6g jxS1noeljjhv8Rsd+Q26YhN9bv3+AQnkaVj28B84lFm+rfxed1ADbbfPLksTR9hKR7Ks QYFvx6zmqP/N8YYFM1fCKtbj/3JTK/Z/TKLNs3rGNGrG3KtcyupnlV2Va/4iIDBxs/TO 2n4wDl94wvEFPKTeOynFsuFK7xm5G+xO8f/rMR9+fC526UDHpRUqyi5YRWspsvPqcNp1 x4MA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rybpCaA/uXhSYglQaynT5LUCctq4ys0+Cf7W0HMJmQc=; b=gdHPYs/DW1LT3DKCq4xpWTvMXkksqRWvLnudnROvumbTvSeYfQru+DI/91L2Yjlv9o kzxeRGM4g+hYa4tb8R9t+ZzRG5NC5MAhD0t1uLnAIIHTCrY0VCi4HnJRh2EtaWXfGlb0 DEmk6aU2SZulptML9kA6CnSJrYpd/m3iw4DqFKr1hJn9s6Wc+uo+9jNqeoYwj5pxVnDT N9EEdXaXrgq7l/GyKJ5f4obtUJetShMRWq3HSdU0dgCXlZThe7PCKx63erH7nkQ0Ppfs amn2bP+inP0lJEW80s2upKbeZ7CWeKhgvFsEGqf2/GoQIJDy4HGLUaT7LdDgk1UwKzTC 6VoQ== X-Gm-Message-State: ALyK8tIW2HRNgZdHLBbtS3Olcl/U9pg4Qpf6NY3G7H3e3dytIofi0jwCH+cwVoOsArGv0A== X-Received: by 10.194.32.199 with SMTP id l7mr855220wji.137.1464041367059; Mon, 23 May 2016 15:09:27 -0700 (PDT) Date: Tue, 24 May 2016 00:16:29 +0200 From: Emese Revfy To: kernel-hardening@lists.openwall.com Cc: pageexec@freemail.hu, spender@grsecurity.net, mmarek@suse.com, keescook@chromium.org, linux-kernel@vger.kernel.org, yamada.masahiro@socionext.com, linux-kbuild@vger.kernel.org, tytso@mit.edu, akpm@linux-foundation.org, linux-mm@kvack.org, axboe@kernel.dk, viro@zeniv.linux.org.uk, paulmck@linux.vnet.ibm.com, mingo@redhat.com, tglx@linutronix.de, bart.vanassche@sandisk.com, davem@davemloft.net Message-Id: <20160524001629.7a9f0c5ce8427d0ad5e951fd@gmail.com> In-Reply-To: <20160524001405.3e6abd1d5a63a871cc366cff@gmail.com> References: <20160524001405.3e6abd1d5a63a871cc366cff@gmail.com> X-Mailer: Sylpheed 3.5.0 (GTK+ 2.24.30; x86_64-pc-linux-gnu) Mime-Version: 1.0 Subject: [kernel-hardening] [PATCH v1 2/3] Mark functions with the latent_entropy attribute X-Virus-Scanned: ClamAV using ClamSMTP These functions have been selected because they are init functions or are called at random times or they have variable loops. Based on work created by the PaX Team. Signed-off-by: Emese Revfy --- block/blk-softirq.c | 2 +- drivers/char/random.c | 6 +++--- fs/namespace.c | 2 +- include/linux/compiler-gcc.h | 5 +++++ include/linux/compiler.h | 4 ++++ include/linux/fdtable.h | 2 +- include/linux/genhd.h | 2 +- include/linux/init.h | 10 ++++++++-- include/linux/random.h | 4 ++-- kernel/fork.c | 4 ++-- kernel/rcu/tiny.c | 2 +- kernel/rcu/tree.c | 2 +- kernel/sched/fair.c | 2 +- kernel/softirq.c | 4 ++-- kernel/time/timer.c | 2 +- lib/irq_poll.c | 2 +- lib/random32.c | 2 +- mm/page_alloc.c | 2 +- net/core/dev.c | 4 ++-- 19 files changed, 39 insertions(+), 24 deletions(-) diff --git a/block/blk-softirq.c b/block/blk-softirq.c index 53b1737..489eab8 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); * Softirq action handler - move entries to local list and loop over them * while passing them to the queue registered handler. */ -static void blk_done_softirq(struct softirq_action *h) +static __latent_entropy void blk_done_softirq(struct softirq_action *h) { struct list_head *cpu_list, local_list; diff --git a/drivers/char/random.c b/drivers/char/random.c index 0158d3b..6cca3ed 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -443,9 +443,9 @@ struct entropy_store { }; static void push_to_pool(struct work_struct *work); -static __u32 input_pool_data[INPUT_POOL_WORDS]; -static __u32 blocking_pool_data[OUTPUT_POOL_WORDS]; -static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS]; +static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy; +static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy; +static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy; static struct entropy_store input_pool = { .poolinfo = &poolinfo_table[0], diff --git a/fs/namespace.c b/fs/namespace.c index 4fb1691..eed930c 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2778,7 +2778,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) return new_ns; } -struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, +__latent_entropy struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, struct user_namespace *user_ns, struct fs_struct *new_fs) { struct mnt_namespace *new_ns; diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index e294939..8d85907 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -188,6 +188,11 @@ #endif /* GCC_VERSION >= 40300 */ #if GCC_VERSION >= 40500 + +#ifdef LATENT_ENTROPY_PLUGIN +#define __latent_entropy __attribute__((latent_entropy)) +#endif + /* * Mark a position in code as unreachable. This can be used to * suppress control flow warnings after asm blocks that transfer diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 793c082..c65327b 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -425,6 +425,10 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s # define __attribute_const__ /* unimplemented */ #endif +#ifndef __latent_entropy +# define __latent_entropy +#endif + /* * Tell gcc if a function is cold. The compiler will assume any path * directly leading to the call is unlikely. diff --git a/include/linux/fdtable.h b/include/linux/fdtable.h index 5295535..9852c7e 100644 --- a/include/linux/fdtable.h +++ b/include/linux/fdtable.h @@ -105,7 +105,7 @@ struct files_struct *get_files_struct(struct task_struct *); void put_files_struct(struct files_struct *fs); void reset_files_struct(struct files_struct *); int unshare_files(struct files_struct **); -struct files_struct *dup_fd(struct files_struct *, int *); +struct files_struct *dup_fd(struct files_struct *, int *) __latent_entropy; void do_close_on_exec(struct files_struct *); int iterate_fd(struct files_struct *, unsigned, int (*)(const void *, struct file *, unsigned), diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 359a8e4..8736c1f 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -433,7 +433,7 @@ extern void disk_flush_events(struct gendisk *disk, unsigned int mask); extern unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask); /* drivers/char/random.c */ -extern void add_disk_randomness(struct gendisk *disk); +extern void add_disk_randomness(struct gendisk *disk) __latent_entropy; extern void rand_initialize_disk(struct gendisk *disk); static inline sector_t get_start_sect(struct block_device *bdev) diff --git a/include/linux/init.h b/include/linux/init.h index aedb254..68df2c3 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -37,9 +37,15 @@ * section. */ +#ifdef CONFIG_MEMORY_HOTPLUG +#define add_meminit_latent_entropy +#else +#define add_meminit_latent_entropy __latent_entropy +#endif + /* These are for everybody (although not all archs will actually discard it in modules) */ -#define __init __section(.init.text) __cold notrace +#define __init __section(.init.text) __cold notrace __latent_entropy #define __initdata __section(.init.data) #define __initconst __constsection(.init.rodata) #define __exitdata __section(.exit.data) @@ -92,7 +98,7 @@ #define __exit __section(.exit.text) __exitused __cold notrace /* Used for MEMORY_HOTPLUG */ -#define __meminit __section(.meminit.text) __cold notrace +#define __meminit __section(.meminit.text) __cold notrace add_meminit_latent_entropy #define __meminitdata __section(.meminit.data) #define __meminitconst __constsection(.meminit.rodata) #define __memexit __section(.memexit.text) __exitused __cold notrace diff --git a/include/linux/random.h b/include/linux/random.h index 379f4bc..9fb07d1 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -27,8 +27,8 @@ static inline void add_latent_entropy(void) } extern void add_input_randomness(unsigned int type, unsigned int code, - unsigned int value); -extern void add_interrupt_randomness(int irq, int irq_flags); + unsigned int value) __latent_entropy; +extern void add_interrupt_randomness(int irq, int irq_flags) __latent_entropy; extern void get_random_bytes(void *buf, int nbytes); extern int add_random_ready_callback(struct random_ready_callback *rdy); diff --git a/kernel/fork.c b/kernel/fork.c index d07d5a6..9fba65c 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -406,7 +406,7 @@ free_tsk: } #ifdef CONFIG_MMU -static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) +static __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) { struct vm_area_struct *mpnt, *tmp, *prev, **pprev; struct rb_node **rb_link, *rb_parent; @@ -1281,7 +1281,7 @@ init_task_pid(struct task_struct *task, enum pid_type type, struct pid *pid) * parts of the process environment (as per the clone * flags). The actual kick-off is left to the caller. */ -static struct task_struct *copy_process(unsigned long clone_flags, +static __latent_entropy struct task_struct *copy_process(unsigned long clone_flags, unsigned long stack_start, unsigned long stack_size, int __user *child_tidptr, diff --git a/kernel/rcu/tiny.c b/kernel/rcu/tiny.c index 944b1b4..1898559 100644 --- a/kernel/rcu/tiny.c +++ b/kernel/rcu/tiny.c @@ -170,7 +170,7 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp) false)); } -static void rcu_process_callbacks(struct softirq_action *unused) +static __latent_entropy void rcu_process_callbacks(struct softirq_action *unused) { __rcu_process_callbacks(&rcu_sched_ctrlblk); __rcu_process_callbacks(&rcu_bh_ctrlblk); diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index c7f1bc4..8821fce 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -3004,7 +3004,7 @@ __rcu_process_callbacks(struct rcu_state *rsp) /* * Do RCU core processing for the current CPU. */ -static void rcu_process_callbacks(struct softirq_action *unused) +static __latent_entropy void rcu_process_callbacks(struct softirq_action *unused) { struct rcu_state *rsp; diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 218f8e8..cd745c2 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -8205,7 +8205,7 @@ static void nohz_idle_balance(struct rq *this_rq, enum cpu_idle_type idle) { } * run_rebalance_domains is triggered when needed from the scheduler tick. * Also triggered for nohz idle balancing (with nohz_balancing_kick set). */ -static void run_rebalance_domains(struct softirq_action *h) +static __latent_entropy void run_rebalance_domains(struct softirq_action *h) { struct rq *this_rq = this_rq(); enum cpu_idle_type idle = this_rq->idle_balance ? diff --git a/kernel/softirq.c b/kernel/softirq.c index 17caf4b..34033fd 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -482,7 +482,7 @@ void __tasklet_hi_schedule_first(struct tasklet_struct *t) } EXPORT_SYMBOL(__tasklet_hi_schedule_first); -static void tasklet_action(struct softirq_action *a) +static __latent_entropy void tasklet_action(struct softirq_action *a) { struct tasklet_struct *list; @@ -518,7 +518,7 @@ static void tasklet_action(struct softirq_action *a) } } -static void tasklet_hi_action(struct softirq_action *a) +static __latent_entropy void tasklet_hi_action(struct softirq_action *a) { struct tasklet_struct *list; diff --git a/kernel/time/timer.c b/kernel/time/timer.c index 3a95f97..6008e7ae 100644 --- a/kernel/time/timer.c +++ b/kernel/time/timer.c @@ -1414,7 +1414,7 @@ void update_process_times(int user_tick) /* * This function runs timers and the timer-tq in bottom half context. */ -static void run_timer_softirq(struct softirq_action *h) +static __latent_entropy void run_timer_softirq(struct softirq_action *h) { struct tvec_base *base = this_cpu_ptr(&tvec_bases); diff --git a/lib/irq_poll.c b/lib/irq_poll.c index 836f7db..63be749 100644 --- a/lib/irq_poll.c +++ b/lib/irq_poll.c @@ -74,7 +74,7 @@ void irq_poll_complete(struct irq_poll *iop) } EXPORT_SYMBOL(irq_poll_complete); -static void irq_poll_softirq(struct softirq_action *h) +static void __latent_entropy irq_poll_softirq(struct softirq_action *h) { struct list_head *list = this_cpu_ptr(&blk_cpu_iopoll); int rearm = 0, budget = irq_poll_budget; diff --git a/lib/random32.c b/lib/random32.c index 510d1ce..722d2b6 100644 --- a/lib/random32.c +++ b/lib/random32.c @@ -47,7 +47,7 @@ static inline void prandom_state_selftest(void) } #endif -static DEFINE_PER_CPU(struct rnd_state, net_rand_state); +static DEFINE_PER_CPU(struct rnd_state, net_rand_state) __latent_entropy; /** * prandom_u32_state - seeded pseudo-random number generator. diff --git a/mm/page_alloc.c b/mm/page_alloc.c index d10324e..ffc4f4a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1235,7 +1235,7 @@ static void __free_pages_ok(struct page *page, unsigned int order) } #ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY -volatile u64 latent_entropy; +volatile u64 latent_entropy __latent_entropy; EXPORT_SYMBOL(latent_entropy); #endif diff --git a/net/core/dev.c b/net/core/dev.c index 904ff43..723d3af 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3851,7 +3851,7 @@ int netif_rx_ni(struct sk_buff *skb) } EXPORT_SYMBOL(netif_rx_ni); -static void net_tx_action(struct softirq_action *h) +static __latent_entropy void net_tx_action(struct softirq_action *h) { struct softnet_data *sd = this_cpu_ptr(&softnet_data); @@ -5175,7 +5175,7 @@ out_unlock: return work; } -static void net_rx_action(struct softirq_action *h) +static __latent_entropy void net_rx_action(struct softirq_action *h) { struct softnet_data *sd = this_cpu_ptr(&softnet_data); unsigned long time_limit = jiffies + 2;