From patchwork Thu Jun 13 11:26:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yann Droneaud X-Patchwork-Id: 10991599 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 610A4924 for ; Thu, 13 Jun 2019 11:32:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4AFC928B79 for ; Thu, 13 Jun 2019 11:32:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3EA6D28B7F; Thu, 13 Jun 2019 11:32:15 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED 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 5594228B79 for ; Thu, 13 Jun 2019 11:32:14 +0000 (UTC) Received: (qmail 19657 invoked by uid 550); 13 Jun 2019 11:32:11 -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: Delivered-To: mailing list kernel-hardening@lists.openwall.com Delivered-To: moderator for kernel-hardening@lists.openwall.com Received: (qmail 9370 invoked from network); 13 Jun 2019 11:26:25 -0000 From: Yann Droneaud To: linux-kernel@vger.kernel.org, kernel-hardening@lists.openwall.com Cc: Andrew Morton , Kees Cook , Alexey Dobriyan , Yann Droneaud Date: Thu, 13 Jun 2019 13:26:04 +0200 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a01:e35:39f2:1220:9dd7:c176:119b:4c9d X-SA-Exim-Mail-From: ydroneaud@opteya.com Subject: [PATCH 1/3] binfmt/elf: use functions for stack manipulation X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on ou.quest-ce.net) X-Virus-Scanned: ClamAV using ClamSMTP As a preliminary step to AT_RANDOM alignment and randomization, replaces STACK_ macros by elf_stack_ inline functions to make them easier to reuse. STACK_ROUND() needed a pointer to elf_addr_t, while STACK_ADD() and STACK_ALLOC() don't. In the new functions, the current stack pointer is an obvious input/output parameter of unsigned long type. STACK_ADD() returned an unsigned long, while STACK_ROUND() returned a pointer to elf_addr_t. elf_stack_add_items() and elf_stack_align() return both void. STACK_ROUND() was used to reserve space on stack (like STACK_ADD()) and to align the resulting stack pointer on 16 bytes boundary. The macro is replaced by elf_stack_add_items() followed by elf_stack_align(). Link: https://lore.kernel.org/lkml/cover.1560423331.git.ydroneaud@opteya.com Signed-off-by: Yann Droneaud --- fs/binfmt_elf.c | 68 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 8264b468f283..87f0c8a21350 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -136,21 +136,52 @@ static int padzero(unsigned long elf_bss) return 0; } -/* Let's use some macros to make this stack manipulation a little clearer */ +/* Let's use some functions to make this stack manipulation clearer */ +static inline void elf_stack_add_items(unsigned long *pp, size_t items) +{ + elf_addr_t *sp = (elf_addr_t *)*pp; + +#ifdef CONFIG_STACK_GROWSUP + sp += items; +#else + sp -= items; +#endif + + *pp = (unsigned long)sp; +} + +static inline void elf_stack_align(unsigned long *pp) +{ + unsigned long p = *pp; + +#ifdef CONFIG_STACK_GROWSUP + p += 15; +#endif + + p &= ~15UL; + + *pp = p; +} + +static inline elf_addr_t __user *elf_stack_alloc(unsigned long *pp, + size_t len) +{ + unsigned long p = *pp; + elf_addr_t __user *sp; + #ifdef CONFIG_STACK_GROWSUP -#define STACK_ADD(sp, items) ((elf_addr_t __user *)(sp) + (items)) -#define STACK_ROUND(sp, items) \ - ((15 + (unsigned long) ((sp) + (items))) &~ 15UL) -#define STACK_ALLOC(sp, len) ({ \ - elf_addr_t __user *old_sp = (elf_addr_t __user *)sp; sp += len; \ - old_sp; }) + sp = (elf_addr_t __user *)p; + p += len; #else -#define STACK_ADD(sp, items) ((elf_addr_t __user *)(sp) - (items)) -#define STACK_ROUND(sp, items) \ - (((unsigned long) (sp - items)) &~ 15UL) -#define STACK_ALLOC(sp, len) ({ sp -= len ; sp; }) + p -= len; + sp = (elf_addr_t __user *)p; #endif + *pp = p; + + return sp; +} + #ifndef ELF_BASE_PLATFORM /* * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture. @@ -198,7 +229,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, if (k_platform) { size_t len = strlen(k_platform) + 1; - u_platform = (elf_addr_t __user *)STACK_ALLOC(p, len); + u_platform = elf_stack_alloc(&p, len); if (__copy_to_user(u_platform, k_platform, len)) return -EFAULT; } @@ -211,7 +242,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, if (k_base_platform) { size_t len = strlen(k_base_platform) + 1; - u_base_platform = (elf_addr_t __user *)STACK_ALLOC(p, len); + u_base_platform = elf_stack_alloc(&p, len); if (__copy_to_user(u_base_platform, k_base_platform, len)) return -EFAULT; } @@ -220,8 +251,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, * Generate 16 random bytes for userspace PRNG seeding. */ get_random_bytes(k_rand_bytes, sizeof(k_rand_bytes)); - u_rand_bytes = (elf_addr_t __user *) - STACK_ALLOC(p, sizeof(k_rand_bytes)); + u_rand_bytes = elf_stack_alloc(&p, sizeof(k_rand_bytes)); if (__copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes))) return -EFAULT; @@ -280,11 +310,13 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, /* And advance past the AT_NULL entry. */ ei_index += 2; - - sp = STACK_ADD(p, ei_index); + elf_stack_add_items(&p, ei_index); items = (argc + 1) + (envc + 1) + 1; - bprm->p = STACK_ROUND(sp, items); + elf_stack_add_items(&p, items); + elf_stack_align(&p); + + bprm->p = p; /* Point sp at the lowest address on the stack */ #ifdef CONFIG_STACK_GROWSUP From patchwork Thu Jun 13 11:26:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yann Droneaud X-Patchwork-Id: 10991601 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4275F924 for ; Thu, 13 Jun 2019 11:32:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3011928B79 for ; Thu, 13 Jun 2019 11:32:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2403F28B7F; Thu, 13 Jun 2019 11:32:23 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED 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 5EBCD28B7D for ; Thu, 13 Jun 2019 11:32:21 +0000 (UTC) Received: (qmail 19971 invoked by uid 550); 13 Jun 2019 11:32:13 -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: Delivered-To: mailing list kernel-hardening@lists.openwall.com Delivered-To: moderator for kernel-hardening@lists.openwall.com Received: (qmail 9453 invoked from network); 13 Jun 2019 11:26:28 -0000 From: Yann Droneaud To: linux-kernel@vger.kernel.org, kernel-hardening@lists.openwall.com Cc: Andrew Morton , Kees Cook , Alexey Dobriyan , Yann Droneaud Date: Thu, 13 Jun 2019 13:26:05 +0200 Message-Id: <42e5c3182c28b2e5c5d10fde340fd0cfcfac376f.1560423331.git.ydroneaud@opteya.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a01:e35:39f2:1220:9dd7:c176:119b:4c9d X-SA-Exim-Mail-From: ydroneaud@opteya.com Subject: [PATCH 2/3] binfmt/elf: align AT_RANDOM array X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on ou.quest-ce.net) X-Virus-Scanned: ClamAV using ClamSMTP Because AT_RANDOM array is put on stack after AT_PLATFORM and AT_BASE_PLATFORM strings, it's aligned on a 1 byte boundary: on x86: $ for i in 1 2 3 ; do LD_SHOW_AUXV=1 ./bin32 | grep AT_RANDOM ; done AT_RANDOM: 0xffb91ffb AT_RANDOM: 0xffcd60eb AT_RANDOM: 0xffd7d99b on x86_64: $ for i in 1 2 3 ; do LD_SHOW_AUXV=1 ./bin64 | grep AT_RANDOM ; done AT_RANDOM: 0x7ffe3ce7d559 AT_RANDOM: 0x7ffeb9ecd2b9 AT_RANDOM: 0x7ffd37cebd49 Unlike AT_ENTROPY1 and AT_ENTROPY2, AT_ENTROPY, or AT_RANDOM1 and AT_RANDOM2 proposals[1][2][3] which would be 32bits or 64bits integers, kernel never promise AT_RANDOM array to be aligned[4]. But having a 16bytes array not aligned might not be optimal. Userspace could benefit from an aligned array. As the AT_PLATFORM and AT_BASE_PLATFORM are asciiz C strings, they don't need to be aligned, thus they can be put after AT_RANDOM array. As AT_RANDOM array is first put on stack, it's alignment should match the one set by arch_align_stack(). [1] https://lore.kernel.org/lkml/4675C678.3080807@gentoo.org/ [2] https://lore.kernel.org/lkml/467948F5.3010709@gentoo.org/ [3] https://sourceware.org/ml/libc-alpha/2008-10/msg00013.html [1] https://lore.kernel.org/lkml/20081003001616.GN10632@outflux.net/ Link: https://lore.kernel.org/lkml/cover.1560423331.git.ydroneaud@opteya.com Signed-off-by: Yann Droneaud --- fs/binfmt_elf.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 87f0c8a21350..cfcc01fff4ae 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -219,6 +219,14 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, p = arch_align_stack(p); + /* + * Generate 16 random bytes for userspace PRNG seeding. + */ + get_random_bytes(k_rand_bytes, sizeof(k_rand_bytes)); + u_rand_bytes = elf_stack_alloc(&p, sizeof(k_rand_bytes)); + if (__copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes))) + return -EFAULT; + /* * If this architecture has a platform capability string, copy it * to userspace. In some cases (Sparc), this info is impossible @@ -247,14 +255,6 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, return -EFAULT; } - /* - * Generate 16 random bytes for userspace PRNG seeding. - */ - get_random_bytes(k_rand_bytes, sizeof(k_rand_bytes)); - u_rand_bytes = elf_stack_alloc(&p, sizeof(k_rand_bytes)); - if (__copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes))) - return -EFAULT; - /* Create the ELF interpreter info */ elf_info = (elf_addr_t *)current->mm->saved_auxv; /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */ From patchwork Thu Jun 13 11:26:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yann Droneaud X-Patchwork-Id: 10991603 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EF81D13AD for ; Thu, 13 Jun 2019 11:32:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DCE3228B79 for ; Thu, 13 Jun 2019 11:32:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D0FFE28B7F; Thu, 13 Jun 2019 11:32:30 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED 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 F0F4F28B79 for ; Thu, 13 Jun 2019 11:32:29 +0000 (UTC) Received: (qmail 21942 invoked by uid 550); 13 Jun 2019 11:32:22 -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: Delivered-To: mailing list kernel-hardening@lists.openwall.com Delivered-To: moderator for kernel-hardening@lists.openwall.com Received: (qmail 9536 invoked from network); 13 Jun 2019 11:26:30 -0000 From: Yann Droneaud To: linux-kernel@vger.kernel.org, kernel-hardening@lists.openwall.com Cc: Andrew Morton , Kees Cook , Alexey Dobriyan , Yann Droneaud , Elena Reshetova Date: Thu, 13 Jun 2019 13:26:06 +0200 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a01:e35:39f2:1220:9dd7:c176:119b:4c9d X-SA-Exim-Mail-From: ydroneaud@opteya.com Subject: [PATCH 3/3] binfmt/elf: randomize padding between ELF interp info X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on ou.quest-ce.net) X-Virus-Scanned: ClamAV using ClamSMTP As AT_RANDOM is on top of the stack, retrieving AT_RANDOM value through getauxval() could help, if needed, an attacker accesses interesting locations in program stack, if offset from top of the stack is fixed/known beforehand. As a pure cargo-cult feature, inspired by "x86/entry/64: randomize kernel stack offset upon syscall" [1], this patch adds small random offsets between the top of the stack, AT_RANDOM array, AT_PLAFORM strings, AT_BASE_PLATFORM strings, and the auxiliary vector (aka. ELF interpretor info) It introduces 16 possible different locations for AT_RANDOM array, 16 possible different locations for AT_PLATFORM, same for AT_BASE_PLATFORM, and 16 more for the auxiliary vector. Thus, at most 544 bytes (256 + 16 + 16 + 256) can be wasted in padding. This patch also enforces an 16bytes aligned AT_RANDOM array as elf_stack_align() is used, regardless of arch_align_stack(). It should be noted, per ABI, it's not possible to insert random padding between auxiliary vector and environment variables, nor between environment variables and program arguments, nor before programs arguments. (It should be possible to shuffle values within auxillay and environment variables, if someone want to scare userspace). [1] https://www.openwall.com/lists/kernel-hardening/2019/03/29/3 Link: https://lore.kernel.org/lkml/cover.1560423331.git.ydroneaud@opteya.com Cc: Elena Reshetova Signed-off-by: Yann Droneaud --- fs/binfmt_elf.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index cfcc01fff4ae..c84ef81f0639 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -182,6 +182,26 @@ static inline elf_addr_t __user *elf_stack_alloc(unsigned long *pp, return sp; } +static inline void elf_stack_randomize(unsigned long *pp, size_t range) +{ + u32 offset; + unsigned long p; + + if (!(current->flags & PF_RANDOMIZE)) + return; + + offset = prandom_u32() % range; + p = *pp; + +#ifdef CONFIG_STACK_GROWSUP + p += offset; +#else + p -= offset; +#endif + + *pp = p; +} + #ifndef ELF_BASE_PLATFORM /* * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture. @@ -219,6 +239,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, p = arch_align_stack(p); + elf_stack_randomize(&p, 256); + elf_stack_align(&p); + /* * Generate 16 random bytes for userspace PRNG seeding. */ @@ -237,6 +260,8 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, if (k_platform) { size_t len = strlen(k_platform) + 1; + elf_stack_randomize(&p, 16); + u_platform = elf_stack_alloc(&p, len); if (__copy_to_user(u_platform, k_platform, len)) return -EFAULT; @@ -250,11 +275,16 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, if (k_base_platform) { size_t len = strlen(k_base_platform) + 1; + elf_stack_randomize(&p, 16); + u_base_platform = elf_stack_alloc(&p, len); if (__copy_to_user(u_base_platform, k_base_platform, len)) return -EFAULT; } + elf_stack_randomize(&p, 256); + elf_stack_align(&p); + /* Create the ELF interpreter info */ elf_info = (elf_addr_t *)current->mm->saved_auxv; /* update AT_VECTOR_SIZE_BASE if the number of NEW_AUX_ENT() changes */ From patchwork Thu Jun 13 13:39:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yann Droneaud X-Patchwork-Id: 10991859 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3CEAB13AF for ; Thu, 13 Jun 2019 13:40:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 25F8528B56 for ; Thu, 13 Jun 2019 13:40:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 23ADA28C31; Thu, 13 Jun 2019 13:40:03 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED 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 4936128C20 for ; Thu, 13 Jun 2019 13:40:01 +0000 (UTC) Received: (qmail 30090 invoked by uid 550); 13 Jun 2019 13:40:00 -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: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 30055 invoked from network); 13 Jun 2019 13:40:00 -0000 From: Yann Droneaud To: linux-kernel@vger.kernel.org, kernel-hardening@lists.openwall.com Cc: Andrew Morton , Kees Cook , Alexey Dobriyan , Yann Droneaud Date: Thu, 13 Jun 2019 15:39:46 +0200 Message-Id: <20190613133946.20944-1-ydroneaud@opteya.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2a01:e35:39f2:1220:9dd7:c176:119b:4c9d X-SA-Exim-Mail-From: ydroneaud@opteya.com Subject: [PATCH 4/3] binfmt/elf: don't expose prandom_u32() state X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on ou.quest-ce.net) X-Virus-Scanned: ClamAV using ClamSMTP Using prandom_u32() to get random offsets might expose fraction of its internal state to userspace; To prevent leaking prandom_u32() state, get_random_u32() could be used instead, but with greater cost. But it would be a big waste to call get_random_u32() to retrieve only 4bits to 8bits at a time. Instead this patch makes use of get_random_u64() to seed once a local PRNG. The local PRNG can be used safely to produces the random offsets, exposing its internal state won't harm. Link: https://lore.kernel.org/lkml/cover.1560423331.git.ydroneaud@opteya.com Signed-off-by: Yann Droneaud --- fs/binfmt_elf.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index c84ef81f0639..9aaca1f671d1 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -182,7 +182,8 @@ static inline elf_addr_t __user *elf_stack_alloc(unsigned long *pp, return sp; } -static inline void elf_stack_randomize(unsigned long *pp, size_t range) +static inline void elf_stack_randomize(unsigned long *pp, + struct rnd_state *state, size_t range) { u32 offset; unsigned long p; @@ -190,7 +191,7 @@ static inline void elf_stack_randomize(unsigned long *pp, size_t range) if (!(current->flags & PF_RANDOMIZE)) return; - offset = prandom_u32() % range; + offset = prandom_u32_state(state) % range; p = *pp; #ifdef CONFIG_STACK_GROWSUP @@ -202,6 +203,15 @@ static inline void elf_stack_randomize(unsigned long *pp, size_t range) *pp = p; } +static inline void elf_stack_randomize_seed(struct rnd_state *state) +{ + if (!(current->flags & PF_RANDOMIZE)) + return; + + prandom_seed_state(state, + get_random_u64()); +} + #ifndef ELF_BASE_PLATFORM /* * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture. @@ -230,6 +240,9 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, int ei_index = 0; const struct cred *cred = current_cred(); struct vm_area_struct *vma; + struct rnd_state state; + + elf_stack_randomize_seed(&state); /* * In some cases (e.g. Hyper-Threading), we want to avoid L1 @@ -239,7 +252,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, p = arch_align_stack(p); - elf_stack_randomize(&p, 256); + elf_stack_randomize(&p, &state, 256); elf_stack_align(&p); /* @@ -260,7 +273,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, if (k_platform) { size_t len = strlen(k_platform) + 1; - elf_stack_randomize(&p, 16); + elf_stack_randomize(&p, &state, 16); u_platform = elf_stack_alloc(&p, len); if (__copy_to_user(u_platform, k_platform, len)) @@ -275,14 +288,14 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, if (k_base_platform) { size_t len = strlen(k_base_platform) + 1; - elf_stack_randomize(&p, 16); + elf_stack_randomize(&p, &state, 16); u_base_platform = elf_stack_alloc(&p, len); if (__copy_to_user(u_base_platform, k_base_platform, len)) return -EFAULT; } - elf_stack_randomize(&p, 256); + elf_stack_randomize(&p, &state, 256); elf_stack_align(&p); /* Create the ELF interpreter info */