All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nathan Lynch <Nathan_Lynch@mentor.com>
To: "H. Peter Anvin" <hpa@zytor.com>
Cc: <x86@kernel.org>, Kees Cook <keescook@google.com>,
	<luto@amacapital.net>, <linux-kernel@vger.kernel.org>
Subject: Re: randomized placement of x86_64 vdso
Date: Wed, 23 Apr 2014 12:06:24 -0500	[thread overview]
Message-ID: <5357F310.8090600@mentor.com> (raw)
In-Reply-To: <5357EABB.3070400@zytor.com>

On 04/23/2014 11:30 AM, H. Peter Anvin wrote:
> On 04/21/2014 09:52 AM, Nathan Lynch wrote:
>> Hi x86/vdso people,
>>
>> I've been working on adding a vDSO to 32-bit ARM, and Kees suggested I
>> look at x86_64's algorithm for placing the vDSO at a randomized offset
>> above the stack VMA.  I found that when the stack top occupies the
>> last slot in the PTE (is that the right term?), the vdso_addr routine
>> returns an address below mm->start_stack, equivalent to
>> (mm->start_stack & PAGE_MASK).  For instance if mm->start_stack is
>> 0x7fff3ffffc96, vdso_addr returns 0x7fff3ffff000.
>>
>> Since the address returned is always already occupied by the stack,
>> get_unmapped_area detects the collision and falls back to
>> vm_unmapped_area.  This results in the vdso being placed in the
>> address space next to libraries etc.  While this is generally
>> unnoticeable and doesn't break anything, it does mean that the vdso is
>> placed below the stack when there is actually room above the stack.
>> To me it also seems uncomfortably close to placing the vdso in the way
>> of downward expansion of the stack.
>>
>> I don't have a patch because I'm not sure what the algorithm should
>> be, but thought I would bring it up as vdso_addr doesn't seem to be
>> behaving as intended in all cases.
>>
> 
> If the stack occupies the last possible page, how can you say there is
> "space above the stack"?

Sorry for being unclear.  I probably am getting terminology wrong.  What
I'm trying to express is that if the stack top is in the last page of
its last-level page table (which may be the last possible page, but
that's not really the interesting case), vdso_addr returns an address
below mm->start_stack.

If you do a lot of execs with the following debug patch applied,
you should see occasional prints like:

got addr 0x7f9a2ba16000, asked 0x7fffa7bff000, start_stack=0x7fffa7bffc96
got addr 0x7f3877ff1000, asked 0x7fffd9bff000, start_stack=0x7fffd9bffc96
got addr 0x7f96e3637000, asked 0x7ffff39ff000, start_stack=0x7ffff39ffc96
got addr 0x7fb70588d000, asked 0x7fff271ff000, start_stack=0x7fff271ffc96
got addr 0x7f7957171000, asked 0x7fff71dff000, start_stack=0x7fff71dffc96

Hopefully this better illustrates.

diff --git a/arch/x86/vdso/vma.c b/arch/x86/vdso/vma.c
index 1ad102613127..06c51329d1b3 100644
--- a/arch/x86/vdso/vma.c
+++ b/arch/x86/vdso/vma.c
@@ -157,15 +157,17 @@ static int setup_additional_pages(struct linux_binprm *bprm,
 				  unsigned size)
 {
 	struct mm_struct *mm = current->mm;
-	unsigned long addr;
+	unsigned long addr, hint;
 	int ret;
 
 	if (!vdso_enabled)
 		return 0;
 
 	down_write(&mm->mmap_sem);
-	addr = vdso_addr(mm->start_stack, size);
-	addr = get_unmapped_area(NULL, addr, size, 0, 0);
+	hint = vdso_addr(mm->start_stack, size);
+	addr = get_unmapped_area(NULL, hint, size, 0, 0);
+	if (addr != hint)
+		pr_info("got addr 0x%lx, asked 0x%lx\n", addr, hint);
 	if (IS_ERR_VALUE(addr)) {
 		ret = addr;
 		goto up_fail;


  reply	other threads:[~2014-04-23 17:06 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-21 16:52 randomized placement of x86_64 vdso Nathan Lynch
2014-04-23 16:30 ` H. Peter Anvin
2014-04-23 17:06   ` Nathan Lynch [this message]
2014-04-30 17:47     ` Kees Cook
2014-04-30 17:52       ` Andy Lutomirski
2014-04-30 18:13         ` Kees Cook
2014-04-30 18:30           ` Andy Lutomirski
2014-04-30 20:05             ` Kees Cook
2014-04-30 20:14               ` Andy Lutomirski

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=5357F310.8090600@mentor.com \
    --to=nathan_lynch@mentor.com \
    --cc=hpa@zytor.com \
    --cc=keescook@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=x86@kernel.org \
    /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.