[3942] in bugtraq
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