mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@elte.hu>
To: Vegard Nossum <vegard.nossum@gmail.com>
Cc: Pekka Enberg <penberg@cs.helsinki.fi>,
	Eugene Teo <eugeneteo@kernel.sg>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [RFC] kmemcheck: TODO for stack tracking
Date: Fri, 28 Nov 2008 12:29:34 +0100	[thread overview]
Message-ID: <20081128112934.GA18333@elte.hu> (raw)
In-Reply-To: <19f34abd0811280316y13dd8dfcm3cf77b6b2171612b@mail.gmail.com>


* Vegard Nossum <vegard.nossum@gmail.com> wrote:

> Hi,
> 
> Here's a plan for how to do stack tracking with kmemcheck. It is not
> entirely trivial, but as far as I can see, it SHOULD be possible.
> Please let me know if you can spot any fallacies or other problems.
> I've probably missed something...
> 
> /*
>  * TODO for stack tracking in kmemcheck:
>  *
>  * 1. Make kernel run at CPL = 1
>  *
>  * This includes (I guess) changing the various privilege levels in most
>  * system descriptors and descriptor tables, and probably the IOPL. Are there
>  * any CPU features which always require CPL = 0 to work? Paging requires no
>  * change, as the U/S flag distinguishes between CPL = 0, 1, 2 and CPL = 3
>  * only.

hm, a ton of instructions need ring-0/supervisor privilege. OTOH, the 
32-bit Xen hypervisor runs the guest kernel on ring 1 so all these places 
are abstracted out to a fair degree already via paravirt_ops.

>  *
>  * 2. Modify TSS to use separate stacks for CPL = 0 and CPL = 1
>  * 3. Install a Call Gate for Page Faults in the GDT with DPL = 0
>  * 4. Change IDT entry for #PF to point to Call Gate in GDT
>  *
>  * Now when a #PF occurs in kernel mode, CPU will look up the IDT entry for
>  * #PF. It points to our Call Gate in the GDT, which has a different privilege
>  * level, so the CPU will look up the new stack to use in the TSS. In the new
>  * stack, SS, ESP, CS, and EIP are saved. Note: page_fault() will have to take
>  * care of handling the extra SS/ESP parameters. End of note. Observe that the
>  * old stack has not been touched by the CPU at all (this would lead to a #DF,
>  * Double Fault, which is irrecoverable). Observe also that none of the
>  * interrupted task's registers have been modified. Now the CPU transfers
>  * control to page_fault(), which must save all registers, etc. as usual.
>  *
>  * do_page_fault() must NOT be allowed to enable interrupts, otherwise we
>  * could take interrupts that would use the new stack. If the interrupt
>  * handler takes another page fault, the CPU will already be in CPL = 0 and no
>  * stack switch will occur!
>  *
>  * I think we need to make the kernel switch stacks on ALL interrupts. When
>  * the CPU is interrupted, it will attempt to push CS/EIP on the current
>  * stack. If the PTE of the current stack is non-present, a Page Fault will be
>  * generated (not a Double Fault!). However, we have no way to tell if the #PF
>  * was generated by an interrupt.
>  *
>  * 5. Implement support for PUSHA/POPA instruction handling in kmemcheck. No
>  *    extra support will be needed for IRET, as interrupts must not be allowed
>  *    to occur when the stack is located in a non-present page.
>  *
>  * Note that it is possible to track POPF/IRET instructions (even though they
>  * modify EFLAGS and the Trap Flag), because the CPU does the right thing and
>  * raises the Debug Exception based on the previous setting of TF.
>  *
>  * 6. The kernel stack tracer would need to be modified to understand stack
>  *    changes/boundaries.
>  */

Sounds like a lot of work.

I'm wondering, how about a non-fault-driven approach: for example the 
function tracer could be modified to poison stack frames as we return 
from a function, and it could also check the poison value when we enter a 
function call.

This is a high-overhead approach too - but ftrace could be modified to 
provide a stack frame size parameter so it would only involve the stack 
frame that is entered/exited.

This would not have the same quality as kmemcheck, but would cover the 
common cases to a fair degree. (and would also be fairly 
false-positive-safe)

Hm?

	Ingo

      reply	other threads:[~2008-11-28 11:29 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-28 11:16 Vegard Nossum
2008-11-28 11:29 ` Ingo Molnar [this message]

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=20081128112934.GA18333@elte.hu \
    --to=mingo@elte.hu \
    --cc=eugeneteo@kernel.sg \
    --cc=linux-kernel@vger.kernel.org \
    --cc=penberg@cs.helsinki.fi \
    --cc=vegard.nossum@gmail.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®