Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751946AbdGEQ7R (ORCPT ); Wed, 5 Jul 2017 12:59:17 -0400 Received: from shadbolt.e.decadent.org.uk ([88.96.1.126]:58201 "EHLO shadbolt.e.decadent.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751745AbdGEQ7Q (ORCPT ); Wed, 5 Jul 2017 12:59:16 -0400 Date: Wed, 5 Jul 2017 17:58:45 +0100 From: Ben Hutchings To: Michal Hocko Cc: Linus Torvalds , Willy Tarreau , Hugh Dickins , Oleg Nesterov , "Jason A. Donenfeld" , Rik van Riel , Larry Woodman , "Kirill A. Shutemov" , Tony Luck , "James E.J. Bottomley" , Helge Diller , James Hogan , Laura Abbott , Greg KH , "security@kernel.org" , Qualys Security Advisory , LKML , Ximin Luo Message-ID: <20170705165845.GB4732@decadent.org.uk> References: <20170704084122.GC14722@dhcp22.suse.cz> <20170704093538.GF14722@dhcp22.suse.cz> <20170704094728.GB22013@1wt.eu> <20170704104211.GG14722@dhcp22.suse.cz> <20170704113611.GA4732@decadent.org.uk> <1499209315.2707.29.camel@decadent.org.uk> <1499257180.2707.34.camel@decadent.org.uk> <20170705142354.GB21220@dhcp22.suse.cz> <1499268300.2707.41.camel@decadent.org.uk> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="jq0ap7NbKX2Kqbes" Content-Disposition: inline In-Reply-To: <1499268300.2707.41.camel@decadent.org.uk> User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: ben@decadent.org.uk Subject: Re: [PATCH] mm: larger stack guard gap, between vmas X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on shadbolt.decadent.org.uk) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4918 Lines: 155 --jq0ap7NbKX2Kqbes Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Jul 05, 2017 at 04:25:00PM +0100, Ben Hutchings wrote: [...] > Soemthing I noticed is that Java doesn't immediately use MAP_FIXED.=20 > Look at os::pd_attempt_reserve_memory_at(). If the first, hinted, > mmap() doesn't return the hinted address it then attempts to allocate > huge areas (I'm not sure how intentional this is) and unmaps the > unwanted parts. Then os::workaround_expand_exec_shield_cs_limit() re- > mmap()s the wanted part with MAP_FIXED. If this fails at any point it > is not a fatal error. >=20 > So if we change vm_start_gap() to take the stack limit into account > (when it's finite) that should neutralise > os::workaround_expand_exec_shield_cs_limit(). I'll try this. I ended up with the following two patches, which seem to deal with both the Java and Rust regressions. These don't touch the stack-grows-up paths at all because Rust doesn't run on those architectures and the Java weirdness is i386-specific. They definitely need longer commit messages and comments, but aside =66rom that do these look reasonable? Ben. Subject: [1/2] mmap: Skip a single VM_NONE mapping when checking the stack = gap Signed-off-by: Ben Hutchings --- mm/mmap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mm/mmap.c b/mm/mmap.c index a5e3dcd75e79..c7906ae1a7a1 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2323,11 +2323,16 @@ int expand_downwards(struct vm_area_struct *vma, if (error) return error; =20 - /* Enforce stack_guard_gap */ + /* + * Enforce stack_guard_gap. Some applications allocate a VM_NONE + * mapping just below the stack, which we can safely ignore. + */ gap_addr =3D address - stack_guard_gap; if (gap_addr > address) return -ENOMEM; prev =3D vma->vm_prev; + if (prev && !(prev->vm_flags & (VM_READ | VM_WRITE | VM_EXEC))) + prev =3D prev->vm_prev; if (prev && prev->vm_end > gap_addr) { if (!(prev->vm_flags & VM_GROWSDOWN)) return -ENOMEM; Subject: [2/2] mmap: Avoid mapping anywhere within the full stack extent if finite Signed-off-by: Ben Hutchings --- include/linux/mm.h | 9 ++++----- mm/mmap.c | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 6f543a47fc92..2240a0505072 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2223,15 +2223,14 @@ static inline struct vm_area_struct * find_vma_inte= rsection(struct mm_struct * m return vma; } =20 +unsigned long __vm_start_gap(struct vm_area_struct *vma); + static inline unsigned long vm_start_gap(struct vm_area_struct *vma) { unsigned long vm_start =3D vma->vm_start; =20 - if (vma->vm_flags & VM_GROWSDOWN) { - vm_start -=3D stack_guard_gap; - if (vm_start > vma->vm_start) - vm_start =3D 0; - } + if (vma->vm_flags & VM_GROWSDOWN) + vm_start =3D __vm_start_gap(vma); return vm_start; } =20 diff --git a/mm/mmap.c b/mm/mmap.c index c7906ae1a7a1..f8131a94e56e 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2307,6 +2307,25 @@ int expand_upwards(struct vm_area_struct *vma, unsig= ned long address) } #endif /* CONFIG_STACK_GROWSUP || CONFIG_IA64 */ =20 +unsigned long __vm_start_gap(struct vm_area_struct *vma) +{ + unsigned long stack_limit =3D + current->signal->rlim[RLIMIT_STACK].rlim_cur; + unsigned long vm_start; + + if (stack_limit !=3D RLIM_INFINITY && + vma->vm_end - vma->vm_start < stack_limit) + vm_start =3D vma->vm_end - PAGE_ALIGN(stack_limit); + else + vm_start =3D vma->vm_start; + + vm_start -=3D stack_guard_gap; + if (vm_start > vma->vm_start) + vm_start =3D 0; + + return vm_start; +} + /* * vma is the first one with address < vma->vm_start. Have to extend vma. */ --=20 Ben Hutchings For every complex problem there is a solution that is simple, neat, and wrong. --jq0ap7NbKX2Kqbes Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIVAwUBWV0axOe/yOyVhhEJAQoVqhAAqNbI6//NYH0Q7eN/68mF6Bcx5Cc8XgiU Mc1g2Ctjbht0UNLjWYS/cQP7wW+sqP9Qj8I0veYF4CKAbZwPWBbzTyD655aAdrPG 1V2QPWzP9jHURQdcUlxt/jQOIbC7BlNF3l6A3ZzJDnbB/pAsGPbQJ8MqxK0lO54B qHVbMYhTrQ81j51wUf+kofZJlT3fYl8nPb7DEzDmk5CEK1SKirc2FA7xyhMcTkVC auVu9f9yLwwwwl7MZPKg+x1LYTclMPvKqzarN+1DAg1/ahIYvc0p5ZRJb7UXaZQp jirr51Yr19+b6cZaOElIsNV0+Q6FzN2YNk1grT/Ucf/u6GpJY+xV+UNWI4NhikyT sWaFipawn4B3K0VzqvE3LbfbFSkF7YShxPjgTPKPlsfLf4ndLSyEARPypctOl6LS rrTNu+3Z9JMnSpgYTCIPMffjNyr2xYKF8KyUGYwWbFeQFRUQcqGrZn9tX5+o2sUb xEl5JnEtNHn9rkL7PEjArodhU3QAu1hbsEEnZqaEXU0AvDy0iqH0QACOb4/ZNmFg mPBHZxjCPOuYeBHtk7YMAgPWd59XTHrUIxxe+GhCfT/mW0RhAmcGEzD3/TOcPkEc YgfMhfnyb05pC11PodTFc7FgE86ZeFNG9SiNfOySgHOXAfNrTB7xe6HZN4O6z0ca bWfgBBIn8+U= =/2nf -----END PGP SIGNATURE----- --jq0ap7NbKX2Kqbes--