Why was Intel a no-show on No Execute?

  • Thread starter Thread starter Yousuf Khan
  • Start date Start date
In comp.sys.ibm.pc.hardware.chips Stefan Monnier said:
Any language with exceptions: C++, Java, C (with setjmp/longjmp), ...

Why should exceptions change anything? AFAIK, all exceptions are
kernel events / interrupts wherein the previous context is fully
saved and restored. Userspace exception handlers are supposed
to be isolated code with their own returns.

-- Robert
 
Why should exceptions change anything? AFAIK, all exceptions are
kernel events / interrupts wherein the previous context is fully
saved and restored. Userspace exception handlers are supposed
to be isolated code with their own returns.

Boggle.

It ain't what you don't know that causes the trouble; it's what you
know that ain't so.


Regards,
Nick Maclaren.
 
Robert Redelmeier said:
...

But `c` compilers have this habit of allocating local variable
space on the stack. So when `char input[80];` is coded in a
routine, ESP gets decreased by 80 and that array is sitting
just below the return address!

I don't think it's _required_ by any standard that local vars are
allocated on the stack, but it sure makes memory managment easy.

It also facilitates recursion and re-entrancy. But it needn't be the
same stack as the return linkage pointer.
AFAIK, only global vars and large malloc()s are put on the heap.

Only malloc()s.

Toby
 
Sander Vesik said:
only superficialy true. as you have control of the stack, you can
cause any number of function calls to happen with the parameters of
your choice. This is essentialy the same as running code.

I see, so how long has C been passing command-line parameters through the
stack? How many other languages do this?

Yousuf Khan
 
No, for not opting to use both. There was no mutual exclusivity between
paging and segmentation. Both could be used and complement each other.

Google for ingo molnar, execshield, ascii armou?r.

-Peter
 
Robert Redelmeier said:
But `c` compilers have this habit of allocating local variable
space on the stack. So when `char input[80];` is coded in a
routine, ESP gets decreased by 80 and that array is sitting
just below the return address!

I don't think it's _required_ by any standard that local vars are
allocated on the stack, but it sure makes memory managment easy.

It also facilitates recursion and re-entrancy. But it needn't be the
same stack as the return linkage pointer.

That is true.
Only malloc()s.

That isn't. It depends on the implementation where variably sized
arrays are put, for example.


Regards,
Nick Maclaren.
 
I see, so how long has C been passing command-line parameters through the
stack? How many other languages do this?

Sinve the beginning. In pretty well all stack-based languages,
you can emulate such a call with no hassle. In some, it is more
difficult.


Regards,
Nick Maclaren.
 
Peter "Firefly" Lund said:
Google for ingo molnar, execshield, ascii armou?r.

Looks like he was using the segment limits to protect against stack
overflows.

Yousuf Khan
 
+---------------
| > I don't think it's _required_ by any standard that local vars are
| > allocated on the stack, but it sure makes memory managment easy.
|
| It also facilitates recursion and re-entrancy. But it needn't be the
| same stack as the return linkage pointer.
+---------------

But if you *don't* do it, then you have trouble with stack fragmentation
and/or collisions with your "argument stack" expanding at a different rate
than your "linkage stack", resulting in one or the other bumping into
arbitrary limits at inconvenient times. As a result, one or the other
of the stacks gets pushed off into the heap (usually the argument stack)
as a linked list of stack-allocated "malloc()" blocks [optimized by
allocating a bunch at a time], which puts a lot of stress on "malloc()",
or gets pushed into a separately-managed segment of address space, which
puts pressure on memory allocation in general and the dynamic loader in
particular.

We had some of these issues with the Am29000 Subroutine Calling Standard
(circa 1987), which had both a "register cache" stack for linkage
information and "small" arguments (which were passed in registers)
and a "memory" stack for "large" arguments (as well as *any* argument,
regardless of size, that the called subroutine referenced by address).[1]
Had the 29k CPU family ever made it into the 32-bit Unix[2] workstation
market, where as we know address space layout has become an issue
(especially with an ever-larger number of DLLs or DSOs competing for space),
the two-stack calling sequence could have become quite problematic.
[As it was, in the embedded-processor space it was pretty much a non-issue.]


-Rob

[1] Actually, the rule was that the first 16 *words* of arguments got
passed in registers and any further words of arguments got passed
on the memory stack, except that if the called routine referenced
any of the first 16 words by address (e.g., "&foo") then that word
and all subsequence words of the register args would get copied into
the memory stack at subroutine entry. Yes, this meant that whenever
the memory stack got used at all there was a 64-byte area at the
front reserved in case the first 16 words needed to be manifested
in memory. (*Ugh*)

[2] Both BSD and System-V ports were done to the Am29000 -- both were
quite straightforward since the 29k was a friendly target enviroment --
but shortly after both were up & running AMD chose not to promote
the 29k as a Unix engine, and they were abandoned.
 
I see, so how long has C been passing command-line parameters through the
stack? How many other languages do this?

Hmm, not "command line" parameters but "actual argument" passing to
functions is done using the stack in C and most Fortrans I've come
across... if the hardware has a stack. But it's not the arguments, which
are pushed on the stack by the programmer written caller routine, which are
important - AIUI it's the return address which gets pushed on the stack
automatically by the "call" instruction. That's what can be fudged by the
exploit - all you need is a bugged, err vulnerable, system call address to
plonk in there which, when entered, will also take *its* argument values
off the stack.

Rgds, George Macdonald

"Just because they're paranoid doesn't mean you're not psychotic" - Who, me??
 
In comp.arch Robert Redelmeier said:
Why should exceptions change anything? AFAIK, all exceptions are
kernel events / interrupts wherein the previous context is fully
saved and restored. Userspace exception handlers are supposed
to be isolated code with their own returns.

So you have no idea at all what a exception is in C++ / Java ? If so
why are you arguing on this topic? You are only going to be completely
wrong and embarass yourself.
 
In comp.arch Robert Redelmeier said:
Well, I'm not entirely sure how these constructs are
implemented by the compilers, but I would expect a
simple `jmp` instruction. This does NOT disturb the
hw call/ret stack, nor pose any buffer-overflow danger.

Completely, *utterly* wrong. Even if the essence of teh longjmp
is a 'jmp' instruction, teh whole point of it is that it happens
back over a number of intermediate call frames that thus never
return. The case of get/setcontext is even more drastic - these
actively change the userland context, so that after the setcontext
call the stack is pointing to a completely new place, including a
new call/return history that has no relation to previous thread's
call/return history.

Quit arguing about things you don't know anything about.
 
In comp.arch Yousuf Khan said:
I see, so how long has C been passing command-line parameters through the
stack? How many other languages do this?

This has always been so, except possibly on some obscure architectures
(obscure from the POV of C language).
 
Sander Vesik said:
This has always been so, except possibly on some obscure architectures
(obscure from the POV of C language).

C programs have always gotten their command-line parameters through
the first two parameters of main(); where these parameters are passed
depends on the calling convention; often it is registers.

Where the strings pointed to by argv[] are located depends on the OS
and has little to do with C.

Followups to comp.arch.

- anton
 
In comp.sys.ibm.pc.hardware.chips Sander Vesik said:
So you have no idea at all what a exception is in C++ / Java ? If so

And just _how_ does an exception occur? At the hw layer, because
this is a hw group. Either some code signals it, which is a library
and potentially kernel event, or some hw event (always kernel).
The kernel can always have fixup code, even to the point of allowing
faults in libspace.

Hmm ... gives me another idea: Maybe the libs can be fixed?!?
Something like:
gets():
mov edx, [esp] ; save return addr in edx
; blah blah gets() code
cmp edx, [esp] ; check that stack not trampled
jnz trampled ; (could be more sophisticated stack sig)
ret
trampled:
printk("Stack trampled by gets() input")
call exit

why are you arguing on this topic? You are only going to be completely
wrong and embarass yourself.

My, my, aren't you hot under the collar. Obviously upset.
Something I've learned is often related to a lack of confidence.

-- Robert
 
Robert Redelmeier said:
And just _how_ does an exception occur? At the hw layer, because
this is a hw group. Either some code signals it, which is a library
and potentially kernel event, or some hw event (always kernel).
The kernel can always have fixup code, even to the point of allowing
faults in libspace.

This is getting embarassing. Could it really be true that you have no
idea what "exception" means in the context of C++ or Java?
 
Looks like he was using the segment limits to protect against stack
overflows.

Not quite. To compensate for the lack of write-but-not-execute and
execute-but-not-write modes for the pages.

-Peter
 
In comp.sys.ibm.pc.hardware.chips Christian Bau said:
This is getting embarassing. Could it really be true that you have
no idea what "exception" means in the context of C++ or Java?

Could it be really true that you're not embarrased by stooping
to "ad hominem"? Or content-free posts? I have an idea, and am
hardly embarrassed by not knowing more of Java or C++. Cruftspace,
IMHO. You will note by my quote line that I read in csiphc.

What I know of exceptions is they appear to have been created
for error checking. Java and C++ seem to have vastly different
mechanisms (runtime vs compile time) that doubtless has resulted in
juvenile flame-fests. Clever programmer probably have been able
to [ab]use these mechanisms for other purposes [multithreading?].
Overloaded, if you will :)

Actually, comparing hw & memory return addr's won't work for
a totally different reason -- gets() and it's evil siblings
are almost certainly blocking syscalls. A task switch to a
different process is likely and the hw stack will be flooded.

Better to save/fingerprint the stack on entry and abort
if trampled as I explain elsewhere.

-- Robert
 
This is getting embarassing. Could it really be true that you have no
idea what "exception" means in the context of C++ or Java?

Rather than being a little argumentative prig, why don't you
educate us?
 
In comp.arch Robert Redelmeier said:
And just _how_ does an exception occur? At the hw layer, because
this is a hw group. Either some code signals it, which is a library
and potentially kernel event, or some hw event (always kernel).

There are no specific hw event involved at all. Again, simply go
and read up on what exceptions are.
The kernel can always have fixup code, even to the point of allowing
faults in libspace.

The kernel would not know anything about the exception.

[snip]
My, my, aren't you hot under the collar. Obviously upset.
Something I've learned is often related to a lack of confidence.

No I simply have short temper with those who continue rambling on
even when they have obviously no clue.
 
Back
Top