From: Pedro Falcato <pfalcato@suse.de>
To: Xiang Mei <xmei5@asu.edu>
Cc: Kees Cook <kees@kernel.org>,
Andrew Morton <akpm@linux-foundation.org>,
Thomas Gleixner <tglx@kernel.org>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
x86@kernel.org, linux-hardening@vger.kernel.org,
Uladzislau Rezki <urezki@gmail.com>,
"Gustavo A . R . Silva" <gustavoars@kernel.org>,
"H . Peter Anvin" <hpa@zytor.com>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
Jennifer Miller <jmill@asu.edu>, Tiffany Bao <tbao@asu.edu>,
Ruoyu Wang <fishw@asu.edu>, Adam Doupe <doupe@asu.edu>,
Kyle Zeng <zengyhkyle@asu.edu>,
Yan Shoshitaishvili <yans@asu.edu>
Subject: Re: [PATCH] mm/vmalloc: widen guard region to defeat ENTER-based stack pivot
Date: Fri, 26 Jun 2026 20:39:45 +0100 [thread overview]
Message-ID: <aj7UNceukU9zYeGH@pedro-suse.lan> (raw)
In-Reply-To: <20260626173444.2252041-1-xmei5@asu.edu>
On Fri, Jun 26, 2026 at 10:34:44AM -0700, Xiang Mei wrote:
> With CONFIG_VMAP_STACK, kernel stacks are allocated in the vmalloc area,
> which an unprivileged user can surround with attacker-controlled data by
> spraying vmap allocations adjacent to a target stack (for example via
> XDP_UMEM_REG, though other vmalloc spray paths work too). Today each
> guarded vmalloc allocation is followed by a single unmapped guard page.
>
> A single guard page is not enough to contain the x86_64 ENTER
> instruction used as a one-instruction stack pivot. ENTER imm16, imm8
> builds a stack frame and lowers RSP by:
>
> imm16 + 8 * (L + 1), L = imm8 & 0x1f
>
> imm16 is an unsigned 16-bit operand (ENTER never raises RSP), and L is
> in [0, 31], so the maximum displacement of a single ENTER is:
>
> 0xffff + 8 * 0x20 = 0x100ff bytes
>
> That is more than enough to step off the current stack, across the
> one-page guard, and into the adjacent sprayed pages. When those pages
> contain a return sled feeding a ROP chain, reaching any ENTER gadget
> (opcode 0xc8, abundant as both intended and unintended gadgets) turns a
> control-flow hijack into full ROP execution without any register control
> at the hijack site, making it a one-gadget-style primitive that
> significantly eases exploitation. The pivot happens after the control
> transfer, so it is not constrained by CFI (kCFI/FineIBT).
>
> Widen the guard region from one page to VMAP_GUARD_PAGES (0x11 pages,
> 0x11000 bytes), which is the smallest whole-page span exceeding the
> 0x100ff-byte maximum single-ENTER pivot. A pivot off the top of the
> stack now lands in the unmapped guard and faults, instead of in mapped,
> attacker-controlled memory. RANDOMIZE_KSTACK_OFFSET only perturbs RSP by
> a sub-page amount, so it does not change the required width.
What's so special about enter? Why do we need to design our guard pages
around it? FWIW, I can't find enter instructions in any of my kernel builds,
nor can I convince gcc (on godbolt) to generate an enter instruction.
If it's just "this is a single instruction that adjusts RSP", why is e.g.
sub imm32, %rsp ok?
FTR, I think it's fine that you're proposing more guard pages; virtual address
space is virtually free on 64-bit architectures (apart from lower page table
density, which may take a little toll on memory usage and/or page table
caching). I'm just wondering why enter is being used as the concrete target
for this.
--
Pedro
next prev parent reply other threads:[~2026-06-26 19:39 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-26 17:34 [PATCH] mm/vmalloc: widen guard region to defeat ENTER-based stack pivot Xiang Mei
2026-06-26 17:46 ` Xiang Mei
2026-06-26 17:48 ` Xiang Mei
2026-06-30 7:12 ` Peter Zijlstra
2026-06-30 8:09 ` Xiang Mei
2026-06-26 19:39 ` Pedro Falcato [this message]
2026-06-26 20:05 ` Xiang Mei
2026-06-29 2:09 ` H. Peter Anvin
2026-06-29 4:43 ` Matthew Wilcox
2026-06-29 12:50 ` H. Peter Anvin
2026-06-29 17:21 ` Xiang Mei
2026-06-29 21:50 ` Xiang Mei
2026-06-29 21:51 ` Xiang Mei
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aj7UNceukU9zYeGH@pedro-suse.lan \
--to=pfalcato@suse.de \
--cc=akpm@linux-foundation.org \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=doupe@asu.edu \
--cc=fishw@asu.edu \
--cc=gustavoars@kernel.org \
--cc=hpa@zytor.com \
--cc=jmill@asu.edu \
--cc=kees@kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mingo@redhat.com \
--cc=tbao@asu.edu \
--cc=tglx@kernel.org \
--cc=urezki@gmail.com \
--cc=x86@kernel.org \
--cc=xmei5@asu.edu \
--cc=yans@asu.edu \
--cc=zengyhkyle@asu.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.