[3942] in bugtraq

home help back first fref pref prev next nref lref last post

Re: Smashing the stack

daemon@ATHENA.MIT.EDU (Thomas Pornin)
Wed Jan 22 13:20:50 1997

Date: 	Wed, 22 Jan 1997 10:12:06 +0100
Reply-To: Thomas Pornin <Thomas.Pornin@ens.fr>
From: Thomas Pornin <Thomas.Pornin@ens.fr>
To: Multiple recipients of list BUGTRAQ <BUGTRAQ@netspace.org>
In-Reply-To:  <9701212043.AA15626@mtc.iitri.com>; from Terrell Thacker on Jan
              21, 1997 15:43:59 -0400

Terrell Thacker writes:
>> X86 memory protection is based on two segments types: Code and Data.
>> Code segments are executable with a read toggle.  Data segments
>> are not executable with a write toggle.  You cannot write to memory
>> using a code segment selector.  You cannot read memory using a code
>> segment selector that is not readable.  You cannot execute code using
>> a data segment selector.  The only selectors allowed in the stack
>> segment register are ones that are type Data/read/write.  The only
>> selectors allowed in the code segment register are type Code.  The
>> only selectors allowed in the general purpose data registers are
>> type Data or Code/read.
>>
>> The problem lies with implementations on the X86.  Different types
>> of selectors can be created to access the same memory in different
>> ways.  If you want a flat address space for each process, then there
>> will be the two types of selectors accessing the same memory space,
>> code and data. Now the code segment selector can be used to execute
>> the data modified in the stack or data segment.  Does anyone know of
>> implementations that use different areas of memory for the selectors
>> of each process?

Actually, you can declare a segment as a data one, with read and write
enable, and load it into the code segment register; this way, you may
have a writable and executable segment. This is not a widely used feature,
as it is much more elegant to use a data segment covering the same range
than the code segment considered.

Nevertheless, using these segments is a pain; that's why linux relies
on paging to perform memory protection and forgets the segments (all
segment registers are declared as 4 GB ones, beginning at adress 0).
I suspect all other 386-based Unixes act this way, as it simplifies much
the implementation. Pages (which are 4 KB wide) can be marked as
readable and writable; no executable flag.

Paging does not exist on 286; therefore, any Unix running on a 286
(but not on a 8086) is likely to use separate code segments and data
segments, and so being unable to execute code placed in data or stack
segments.

        --Thomas Pornin

home help back first fref pref prev next nref lref last post