Is the x86 Architecture Less Secure?
An anonymous reader asks: "Paul Murphy at CIO Today reports that a specific Windows buffer overflow vulnerability ' depends on the rigid stack-order execution and limited page protection inherent in the x86 architecture. If Windows ran on Risc, that vulnerability would still exist, but it would be a non-issue because the exploit opportunity would be more theoretical than practical.' And implies that other Windows vulnerabilities are actually facilitated by having an x86 chip." How does the x86 processor compare with other architectures when it comes to processor based vulnerabilities? How well have newer additions, like the Execute Disable Bit, helped in practical situations?
Paul Murphy, I'd like you to meet Paul Graham. What we have here is an Apple press release being printed up as a trade journal article.
Good for Apple's PR firm. I guess.
Not that I have anything against Macs or PowerPC hardware, I just don't like disengenuous authors (or their articles).
Regards,
Ross
x86 has been around how long? 15+ years? And they just begin discussing this now?
On x86, the stack grows backwards. Backwards! A stack overflow ought to overwrite unallocated space, not earlier stack frames and return addresses. It's totally insane.
But I guess when you live with insanity year after year, you get used it.
As copyright owner of this comment, I authorize everyone to defeat any technological measure which limits access to it.
while the NX bit can help prevent the execution of malicious code on the stack after a buffer overflow, it doesn't solve the security problem posed by overflows. return-into-libc attacks can easily be executed and will become much more prevelant as NX-enabled PCs filter into the mainstream. address space randomization can help make rilc attacks harder on 64-bit architectures but is pretty useless on 32-bit archs.
Exactly.
The security advantage of MacOS X is a lack of braindead design decisions, it has nothing to do with PowerPC.
I rarely criticize things I don't care about.
I just read this article recently in Embedded Systems Programming magazine. http://www.embedded.com//showArticle.jhtml?article ID=55301875
After a detailed explanation of the hardware protection features built into the x86 (since the 80386), the author makes the following statement towards the end of the article:
"Too bad Microsoft doesn't use this feature. Windows has been plagued by buffer-overflow bugs that could easily be prevented by the processor's segmentation features. Alas, even though these features have been built into every x86 chip for more than 15 years, Microsoft has never used them. Instead, Windows creates a "flat" memory system with no segmentation, no tasking, no bounds checking, and no privilege protection, and then struggles to duplicate all those features in software. The result has been famously ineffective."
I think his point was that driving the safest car may not be recognized as the most important criteria while buying a car...
and in reality it was just symbolic, because anyway volvos theese days are just as plastic as any car
Linux does support limited stack and library randomization. However, there are questions as to the effectiveness of these techniques.
Using a segmented address space, where the Stack and Code are kept in what are effectively different address spaces, would do much to mitigate the effect of buffer overruns. On the other hand, the NX bit on x86-64 accomplishes basically the same thing, without the overhead of having to use long pointers to access data on the stack.
Neither of them are really all that robust though, since any time you can overwrite the return address on the stack, you can cause execution to veer off to somewhere else. Maybe you won't be able to insert shellcode into the program's address space, but if you can cause a function to "return" to something in the C standard library, like remove(), you can still cause havoc.
A more secure solution would split the stack such that function arguments and return addresses are not stored in the same space. This would give you a somewhat Forth-like runtime model, where return addresses are stored on one stack, and data values on the other. In that case, a buffer overrun in one function would still allow you to overwrite the arguments to another function, which is sub-optimal.
If you combine a split stack with growing the stack in the non-obvious direction, then you're probably as secure as you're going to get without eliminating the use of a stack altogether.
-Mark
Yes, it is possible to use a buffer overflow to replace the return address even when the stack grows up. Here is an example:
void blah(char *s1, char *s2) {
strcpy(s1,s2);
}
void foo() {
char s[10];
blah(s,"abcdefghijklmnopqrstuvwxyz");
}
If the stack grows up, blah will wipe out it's own return address.
As for bugs, I agree with you but I also know how easy and how common it is. We need to use multiple tools, just saying hire better coders or something to that effect is a cop-out. We need to use programming technologies that are better suited for the problems and less prone to these kinds of defects, we needs platforms that take security seriously and provide different mechanisms for enforcing policy and then ultimately hardware that allows those platforms to be created and operate correctly. Sure, we can take plain old x86 and write bug free code and make it more "secure," unfortunately, that's just not practical or affordable.
I'd rather have my buggy code produce a segfault and cause a process to be restarted than expose sensitive data or allow an attacker to execute arbitrary code on my machines. I'd really like it to be completely bugfree but that's just not very realistic, in the mean time I'd rather deal with a DoS than a full root compromise..
You could use a language like Java ,Python or Ada.
Or some good programming practices.
CAN-2004-1134 is a buffer overflow issue. The Mac is susceptible to buffer overflows.
Take e.g. the iSync issue. Apple doesn't go into details, but if you do a Google search on "isync vulnerability" you will find:
"The vulnerability is caused due to a boundary error in the handling of the "-v" and "-a" command line options. This can be exploited to cause a buffer overflow by supplying an overly long argument (over 4096 bytes). Successful exploitation allows execution of arbitrary code with the privileges of the mRouter application."
A proof of concept exploit can be found at. It opens a root shell.
When the PowerPC jumps to a subroutine, the return address is stored in the lr register. The first thing the prolog code in the subroutine does, is to put the address on the stack (freeing up the register for further function calls). So, a would-be hacker can overwrite the return address. For a description of how to take advantage of buffer overflows on the Mac, see "Smashing The Mac For Fun & Profit".
"Administrate isn't a word"
From the OED:
administrate v.
[f. L. administrat- ppl. stem of administra-re: see administer (cf. demonstrate, etc.).]
1. A by-form of administer v. (a sacrament, oath, medicine).
1651 Calderwood Hist. Kirk (1843) II. 38 That no maner of person, in time coming, administrat anie of the sacraments secreetlie.
1733 G. Cheyne Eng. Malady (1735) Pref., When Lithotomy cannot be administrated.
1855 Milman Lat. Chr. iii. v. (1864) II. 70 The delinquent clerk might be deprived for a time of his power of administrating sacred things.
2. To manage or direct (affairs). Now usu. absol. or intr. Cf. administer v. 1.
a1639 J. Spottiswood Hist. Ch. Scot. (1655) v. 241 A Lieutenant should be appointed..with full authority to administrate all affairs.
1848 Tait's Mag. June 397/2 The people is sovereign, its representatives administrate.
1934 G. B. Shaw On Rocks Pref. 150 What was formerly called 'real property' is replaced by ordinary personal property and common property administrated by the State.
1965 New Statesman 17 Sept. 400/3 Bishops, prime ministers, official people loved it... One is simply administrating in a fantasy world.
1981 Times 29 Apr. 9/6 The machinery of such aid is still primed by administrators eager to go out and administrate.
3. To organize or manage the recording and application of information in (a list, register, etc.).
1977 Wandsworth Boro' News 16 Sept. 19/4 (Advt.), Part-time..ledger clerk required to administrate sales ledger (mechanised).
1982 Times 12 Oct. 12/6 A claims register, administrated by an International Sea Bed Authority, would have been a simple answer.
- The telnetd AYT heap overflow (2002) could be exploited on x86/*BSD systems specifically because of their memory layout and little-endianess, while MIPS and SPARC systems were saved by their big-endian, 64bit addresses. Yet, on x86/Linux it was not exploitable, because of a different memory layout within the heap.
- The Solaris login heap overflow (2001) could be exploited on both x86 and SPARC. The reason were that addresses are created by the vulnerable code itself.
- The SSH1 CRC32 overflow (2000), has been exploited on every known architecture, x86, SPARC, MIPS, etc. because the data used to overwrite memory with were created by the vulnerable code itself, hence endianess and order did not matter.
Now, there are cases where RISC architecture makes exploitation more difficult to impossible. But there are around an equal amount of cases where x86 is saved. But the reason is not to be found within the architecture alone, but within differences in the whole chain from CPU to process memory layout to ABI and runtime environment. The following are especially important to determine if a vulnerability could be exploited on a given system:- CPU, word width and endianess
- process address layout
- stack frame handling and layout, how registers are saved (register windows?) order of registers/parameters/locals/alloca
- heap handling (i.e. what malloc allocation system is used. For example, most *BSD systems use an out-of-chunk management to control the heap structure itself, while glibc uses an inband management, which is by nature more likely to allow exploitation)
- compiler optimizations, eg. if small functions are inlined omitting stack frames, etc.
- ...
Speaking with more than eight years of exploit development experience, there is much more to consider than just the CPU type.it's a known issue that the intel x86 platform is vulnerable to stack-based buffer overflow exploits. the amd64 architecture is addressing this by providing hardware page protection which prevents code from being illegally executed off the stack. netbsd has enabled this feature by default in netbsd 2.0. i look at the x86 platform like training wheels and amd64 like a nice racing bike... ;-)
But it's tough to run C on that kind of architecture. C wants pointers to be addresses. The "array is a pointer" convention is a bad fit to a true segmented architecture. You can run Pascal just fine, but running C is tough. It can be done, but basically requires allocating all the variables in one big "array" at the hardware level, so you lose the protection. When C came in, the Burroughs machines (by then the Unisys A series) died off.
So it's quite possible to fix this, but you have to dump C. This may happen as Java and C# get more traction.
C++ doesn't help. It's part of the problem.
This guy doesn't know what he's talking about.
Probably. Dunno since I stopped RTFAs a while ago.
However, the IBM PowerPC 970FX aka Apple G5 processors have had NX for a while. Partial Linux support already exists. Check it out.
http://lwn.net/Articles/126862/
I like the 970FX (apart from its tiny cache). Shame Apple has a monopoly on the desktop systems, and you have to buy their OS to run Linux on one.
The government does that over here.
To be fair, OpenBSD doesn't really care much about performance, and is willing to take a big speed hit for security. They have implemented workarounds for the architecture that have been deemed unacceptable elsewhere (Linux). All of this is pretty recent -- a few years ago, they had all the same fundemental problems as everyone else.
Whenever I hear the word 'Innovation', I reach for my pistol.
True, C# and Java would need a VM. However there are traditional (non VM) languages which have build in buffer protection. Fortran was mentioned by another poster - I would add Ada to the list.
Unlike common believe they are suitable for low level system programming. They are also not old and outdated - both Ada and Fortran have current (not older then 10 years) ISO standards and will get a new ISO standarts soon.
The only problem is that the names are not common buzz words.
Martin
I would have said that the most obvious hardware-specific feature, that would protect against stack overflows, is Harvard architecture (vs. Von Neumann, present in almostall CPUs today).
In Harvard architecture, data and program memory are separate and separately accessed. This has a speedup benefit, as you can access the data in the same cycle you access the program memory, but the other advantage is, a stack overflow will not corrupt your program. For an example, the Atmel AVR risc microcontroller family uses Harvard architecture.
Sigged!
Sometimes you have to do that, but I prefer instead to make sure that all uses of that buffer don't assume it is zero-terminated unless I can guarantee that it is.
Funny how exploits that are "just theoretical" don't stay that way forever...
I always liked this phrack article about how to exploit an appearently unexploitable bug. After reading this, I would be very cautious about clasifying a bug as unexploitable.
Do you care about the security of your wireless mouse?
The problem with that approach is that most compilers don't really create a stack frame off EBP anymore (think -fomit-frame-pointer in GCC). That makes EBP available for use as a general purpose register.
Thats not to say that your approach won't work at all. Simply that it will rob some x86 code of some of its performance. Its a question of trading security for performance/memory footprint. I guess I forgot to mention in my original post that having a disjoin stack area will still consume some memory in terms of page tables and virtual address space. But with paging enabled both stacks can grow on demand.
I would be happy to see this implemented but ABI's are hard to change.
In another article on Slashdot today it's mentioned that Eric Raymond recommends Microsoft "open document formats" and "adhere to standards". Document formats aren't really an issue with Apple, but Apple is doing a very nice job of adhering to open standards these days. BSD Unix, Java, OpenGL, PDF, TCP/IP, X11...Apple is much more programmer friendly than it has ever been. The G5 machines are also very competitive on performance.
If you need access to commercial applications, or would rather spend money instead of time to accomplish your computing tasks, Mac makes a lot of sense compared with Linux. Windows, for me, is a distant third due to the time lost dealing with security issues, and a general distaste for programming something that inelegant. Besides, I can target Windows using Java with very little pain.
Just my $.02.
Galileo: "The Earth revolves around the Sun!"
Score: -1 100% Flamebait