Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp7036474ybi; Thu, 13 Jun 2019 08:30:41 -0700 (PDT) X-Google-Smtp-Source: APXvYqwVjcyoGFucfve5pElsF1JaND88kidDb/vZ3UIqi2FycQubWtVFE8aXWAoMtOU6TpAOCa2L X-Received: by 2002:a17:90a:d814:: with SMTP id a20mr6294866pjv.48.1560439841202; Thu, 13 Jun 2019 08:30:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560439841; cv=none; d=google.com; s=arc-20160816; b=D6D1uLb5Q8P1cRIdn+uQkwcPig4RQS75PgjAVm9UuzIgGTkKt356KU84tr/kKo6Jld ninyS0b5XYYxTSB+qclWmpYLfp+vespGOaOVR0rd+Z3hMQx/v5xi92Dd8LwKBDsWigi1 cQ2PO/lXyCfginv55loHIl+of+Yvd1jnfvOe+k9tT8RMoFxEA9RSlWzqh0WGL5vyX42K 4KSNvvlDfVdovNGuiZ9U6zSBLSsuia1Q7QX3ASAramxzSh0wPnGYUeYegLGTfIhDZCVe 9UJCl8r09w4o/9+8PqVcEKbvcaLofXMNdwEfkV1zkBy90YpBXdvZnTGp+cES2rUzSfeN YCig== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:subject:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:cc:to:from; bh=31/4MkJduP3Zi5cBgu1p1Oc4etaXsk3xbK1NyFZtC5I=; b=TmFkHlE23SovowRwIaFZ2ODXM72tm+V5m/QQHkUzWIdplnz85M8Wx3ByFLaGyPtLEv W9n0AjwtSU+ZBE9CQehNX8MZzYGw/AjjyuE8Z8GojrRuV4TGAw8V57oWDjfMfREjYT2S vpqr5IeHh4LSbdakhAhdmdT/29X+ZOYGCoIazQxHWMB8aMnEGvdSH8cG78L0/wAINkO9 XXLs+o3hmdLf+2wscVh9n4GAk0+HWIfuXEfbenCZWV7LHMKkG7EdpOKBv0nJTp6nnxta 5DhnlpYwCDYY8odV46v9ajHI7pODe6EbsY69NUNTPTqGnjaoGLjUbsaZXTjv3PiD05gx qMEQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d4si3592601pfr.82.2019.06.13.08.30.25; Thu, 13 Jun 2019 08:30:41 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731081AbfFMP3D (ORCPT + 99 others); Thu, 13 Jun 2019 11:29:03 -0400 Received: from ou.quest-ce.net ([195.154.187.82]:36476 "EHLO ou.quest-ce.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728892AbfFML0W (ORCPT ); Thu, 13 Jun 2019 07:26:22 -0400 Received: from [2a01:e35:39f2:1220:9dd7:c176:119b:4c9d] (helo=test.quest-ce.net) by ou.quest-ce.net with esmtpsa (TLS1.1:RSA_AES_256_CBC_SHA1:256) (Exim 4.80) (envelope-from ) id 1hbNs2-00087D-OI; Thu, 13 Jun 2019 13:26:19 +0200 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 Content-Transfer-Encoding: 8bit X-SA-Exim-Connect-IP: 2a01:e35:39f2:1220:9dd7:c176:119b:4c9d X-SA-Exim-Mail-From: ydroneaud@opteya.com X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on ou.quest-ce.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00, URIBL_BLOCKED autolearn=ham version=3.3.2 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) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 */ -- 2.21.0