public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* Segfault on the i386 enter instruction
@ 2006-05-12 13:16 Tomasz Malesinski
  2006-05-12 13:47 ` Denis Vlasenko
                   ` (2 more replies)
  0 siblings, 3 replies; 25+ messages in thread
From: Tomasz Malesinski @ 2006-05-12 13:16 UTC (permalink / raw)
  To: linux-kernel

The code attached below segfaults on the enter instruction. It works
when a stack frame is created by the three commented out
instructions and also when the first operand of the enter instruction
is small (less than about 6500 on my system).

AFAIK, the only difference between creating a stack frame with the
enter instruction or push/mov/sub is that enter checks if the new
value of esp is inside the stack segment limit.

I tested it on a vanilla kernel 2.4.26 on Intel Celeron and also on
probably non-vanilla 2.6.16.13 running on 3 dual core AMD Opteron,
quite busy, server. It is working in 32-bit mode. Interestingly, on
the second machine sometimes the program worked correctly.

I am not subscribed to the list. Please cc replies to me.


	.file	"a.c"
	.version	"01.01"
gcc2_compiled.:
.section	.rodata
.LC0:
	.string	"asdf\n"
.text
	.align 4
.globl main
	.type	 main,@function
main:
	enter $10008, $0
#	pushl %ebp
#	movl %esp,%ebp
#	subl $10008,%esp
	addl $-12,%esp
	pushl $.LC0
	call printf
	addl $16,%esp
.L2:
	leave
	ret
.Lfe1:
	.size	 main,.Lfe1-main
	.ident	"GCC: (GNU) 2.95.4 20011002 (Debian prerelease)"

-- 
Tomek Malesinski

^ permalink raw reply	[flat|nested] 25+ messages in thread
* Re: Segfault on the i386 enter instruction
@ 2006-05-14 17:56 Stas Sergeev
  2006-05-15  7:40 ` Andi Kleen
  0 siblings, 1 reply; 25+ messages in thread
From: Stas Sergeev @ 2006-05-14 17:56 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Linux kernel

Hi.

Andi Kleen wrote:
> Handling it like you expect would require to disassemble 
> the function in the page fault handler and it's probably not 
> worth doing that for this weird case.
Just wondering, is this case really that weird?
In fact, the check against %esp that the kernel
does, looks strange. I realize that it can catch a
(very rare) user-space bug of accessing below %esp, but
other than that it looks redundant (IMHO) and as soon as
it triggers the false-positives, what is it really good for?
Aren't the rlimit and the other checks of acct_stack_growth()
not enough, or am I missing something obvious?


^ permalink raw reply	[flat|nested] 25+ messages in thread
* Re: Segfault on the i386 enter instruction
@ 2006-05-16  2:29 Chuck Ebbert
  2006-05-16  9:32 ` Andi Kleen
  0 siblings, 1 reply; 25+ messages in thread
From: Chuck Ebbert @ 2006-05-16  2:29 UTC (permalink / raw)
  To: Stas Sergeev; +Cc: Andi Kleen, linux-kernel

In-Reply-To: <44676F42.7080907@aknet.ru>

On Sun, 14 May 2006 21:56:18 +0400, Stas Sergeev wrote:

> Andi Kleen wrote:
> > Handling it like you expect would require to disassemble 
> > the function in the page fault handler and it's probably not 
> > worth doing that for this weird case.
> Just wondering, is this case really that weird?
> In fact, the check against %esp that the kernel
> does, looks strange. I realize that it can catch a
> (very rare) user-space bug of accessing below %esp, but
> other than that it looks redundant (IMHO) and as soon as
> it triggers the false-positives, what is it really good for?

I can't get a SIGSEGV on any native i386 kernel, not even when
running on AMD64.  It only happens on native x86_64 kernels.

Looking at the AMD instruction manual, the pseudo-code for 'enter'
ends with:

RSP.s = RSP - temp_ALLOC_SPACE // Leave "temp_ALLOC_SPACE" free bytes on
                               // the stack
WRITE_MEM.v [SS:RSP.s] = temp_unused // ENTER finishes with a memory write
                                     // check on the final stack pointer,
                                     // but no write actually occurs.
RBP.v = temp_RBP
EXIT


And the Intel manual says:

IF 64-Bit Mode (StackSize = 64)
THEN
        RBP = FrameTemp;
        RSP = RSP - Size;
ELSE IF StackSize = 32
THEN
        EBP = FrameTemp;
        ESP = ESP - Size;
ELSE (* StackSize = 16 *)
        BP = FrameTemp;
        SP = SP - Size;
FI;
END;


Intel says nothing about a write check.  Is that a mistake in the manual
or is that something only AMD64 does, and then only in long mode?


-- 
Chuck

"The x86 isn't all that complex -- it just doesn't make a lot of sense."
                                                        -- Mike Johnson

^ permalink raw reply	[flat|nested] 25+ messages in thread
* Re: Segfault on the i386 enter instruction
@ 2006-05-17  8:20 Chuck Ebbert
  0 siblings, 0 replies; 25+ messages in thread
From: Chuck Ebbert @ 2006-05-17  8:20 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Tomasz Malesinski, linux-kernel, Stas Sergeev, Denis Vlasenko

In-Reply-To: <200605161132.18610.ak@suse.de>

On Tue, 16 May 2006 11:32:18 +0200, Andi Kleen wrote:

> On Tuesday 16 May 2006 04:29, Chuck Ebbert wrote:
> > In-Reply-To: <44676F42.7080907@aknet.ru>
> > 
> > On Sun, 14 May 2006 21:56:18 +0400, Stas Sergeev wrote:
> > 
> > > Andi Kleen wrote:
> > > > Handling it like you expect would require to disassemble 
> > > > the function in the page fault handler and it's probably not 
> > > > worth doing that for this weird case.
> > > Just wondering, is this case really that weird?
> > > In fact, the check against %esp that the kernel
> > > does, looks strange. I realize that it can catch a
> > > (very rare) user-space bug of accessing below %esp, but
> > > other than that it looks redundant (IMHO) and as soon as
> > > it triggers the false-positives, what is it really good for?
> > 
> > I can't get a SIGSEGV on any native i386 kernel, not even when
> > running on AMD64.  It only happens on native x86_64 kernels.
> 
> I reproduced the original SIGSEGV on several i386 kernels.

OK, I got SIGSEGV on a 2.6.9 i386 kernel in addition to ia32 mode on x86_64.
But it doesn't happen on any recent 2.6, even with "enter $65535,$0".
Digging, I found the stack vma is 22 pages (88k) on recent i386
kernels while it's only 8k on 2.6.9 and 12k in x86_64 ia32 emulation.
So you have to go deeper into the stack before you will hit this on
recent i386 kernels.
 
> > Intel says nothing about a write check.  Is that a mistake in the manual
> > or is that something only AMD64 does, and then only in long mode?
> 
> In 98+% of all cases when Intel and AMD documentation differ
> in subtle detail it's a documentation bug.

Yeah, that's why it's good to have both on hand.  But sometimes it can be
hard to tell which one is wrong. :)


BTW one easy way to fix this bug would be to enlarge the window for
access below the stack pointer to allow for the largest possible enter
instruction, i.e. "enter $65535,$31".  On x86_64 that would be 65536+256
instead of the current 128 bytes.

-- 
Chuck
"The x86 isn't all that complex -- it just doesn't make a lot of sense."
                                                        -- Mike Johnson

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2006-05-17  8:25 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-05-12 13:16 Segfault on the i386 enter instruction Tomasz Malesinski
2006-05-12 13:47 ` Denis Vlasenko
2006-05-12 13:50 ` Andi Kleen
2006-05-12 14:03   ` Denis Vlasenko
2006-05-12 15:31   ` Tomasz Malesinski
2006-05-15 11:36     ` Bart Hartgers
2006-05-15 11:46       ` Andi Kleen
2006-05-15 13:36       ` linux-os (Dick Johnson)
2006-05-15 14:19         ` Bart Hartgers
2006-05-12 14:07 ` linux-os (Dick Johnson)
2006-05-12 14:20   ` Denis Vlasenko
2006-05-12 14:42     ` linux-os (Dick Johnson)
2006-05-12 14:53       ` Denis Vlasenko
2006-05-15 20:53   ` Bill Davidsen
  -- strict thread matches above, loose matches on Subject: below --
2006-05-14 17:56 Stas Sergeev
2006-05-15  7:40 ` Andi Kleen
2006-05-15 17:15   ` Stas Sergeev
2006-05-15 18:44     ` Andi Kleen
2006-05-15 19:38       ` Stas Sergeev
2006-05-15 19:56         ` Lee Revell
2006-05-15 22:49           ` Ingo Oeser
2006-05-15 22:56             ` Lee Revell
2006-05-16  2:29 Chuck Ebbert
2006-05-16  9:32 ` Andi Kleen
2006-05-17  8:20 Chuck Ebbert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox