
How security flaws work: the buffer overflow - guardian5x
http://arstechnica.com/security/2015/08/how-security-flaws-work-the-buffer-overflow/
======
ghuntley
One of the best explanations ever written is the now classic "Cult of the Dead
Cow issue #351 - The Tao of Windows [NT|95|98] Buffer Overflow" @
[http://www.cultdeadcow.com/cDc_files/cDc-351/](http://www.cultdeadcow.com/cDc_files/cDc-351/)

~~~
drzaiusapelord
>but if you don't have automatic bounds checking like Java, I guarantee you
that those 'A's are going somewhere unfortunate.

20 years later and we're still using C++. I hope Rust takes off. The status
quo today is terrible.

~~~
dmix
Also of note is the lack of investment in exploit mitigation at the operating
system and compiler level. C++ and C are not going away from our systems any
time soon. Yet exploit mitigation technology still remains on the sidelines of
the security world while bug squashing, AV, and IDS are flush with cash.

~~~
drzaiusapelord
How realistic is a compiler-level change that is 100% transparent and reverse
compatible with existing codebases? I suspect this is a tough nut to crack
without making fundamental changes to the language and perhaps invalidating
past codebases. You might as well move to a different language then.

I suspect we'll have a Rust compiler that compiles fast applications with a
very minor performance hit before this happens to aging languages like C/C++.

~~~
dllthomas
The question is not just when we will have the tech, though. It is also when
the tech will have an impact. A perfect Rust compiler only improves the safety
of new (or rewritten) code.

~~~
pyre
I daresay that some codebases might _rely_ on overflowing behaviour even if
they don't know it. I've worked with a codebase where assumptions about unused
RAM were that it was always zeroed out. Moving to a different platform (Linux)
changed those assumptions, and there was lots of weird behaviour in the
codebase because of that.

I'll bet there are lots of legacy codebases that would actively resist using
such a compiler technology for C/C++ because of unknown behaviours happening
in their codebase (and because there is no test suite, or just poor test
coverage).

~~~
dllthomas
Certainly, though usually that winds up perceived as brittleness moving
between compiler versions in general. Ideally, the tech we are discussing
could help make it easier to understand those unknown behaviors.

But even if not, and even if this accounts for 60% of existing C/C++
codebases, improving the remaining 40% is a huge win that would take
tremendously more time to reimplement in Rust.

This is not to say that I am not also very excited about Rust.

------
kriro
Alternatively (just the concept, this should not work as outlined on modern
systems):
[http://phrack.org/issues/49/14.html](http://phrack.org/issues/49/14.html)

~~~
billyhoffman
I used to use Aleph One's article as a kind of shibboleth when interviewing
candidates for security researchers. I'd just casually say "Smashing the
stack..." and see if they would fill in the rest of the title.

Not the best data point, but showed pretty quickly who had a self-taught (and
usually practical) understanding of security vulnerabilities vs an academic
understanding.

~~~
roghummal
That's a class move and you are probably a cool person to work with.

~~~
roghummal
That was not sarcasm.

------
cm2187
The worse is that this error only happens because we are trying to save 4
bytes. If all arrays would also store their own size we could eradicate this
bug with a limited memory impact.

~~~
saurik
You have overlooked the CPU cost. Given that most memory objects already have
at least an over-approximate size _somewhere_ , and how we are more than happy
to annotate stacks with canaries, I really don't think anyone is as concerned
with the memory cost of adding a size to every array as the CPU cost of adding
a read and compare to every array access.

~~~
ctz
Intel is adding hardware array bounds checking called MPX in skylake, so this
could become a reality.

~~~
tedunangst
There already was a BOUND instruction. Nobody ever seems to remember this when
they propose adding such an instruction.

------
jakozaur
There were so many critical vulnerabilities attributed to that... and in spite
of putting tons of measures this is still potential danger. I knew projects
decided to use Java instead of C++ (which got array boundary checks) mostly to
limit security surface.

Maybe if we could start CPU architecture from scratch, array with sizes would
make more sense? Maybe even we could done it so memory segmentation would no
longer be needed:
[https://en.wikipedia.org/wiki/X86_memory_segmentation](https://en.wikipedia.org/wiki/X86_memory_segmentation)

Haven't figured out the details, but maybe we can even gain some performance
that way.

~~~
shanemhansen
Friendly reminder: it's not just a choice between C and Java. In order to get
bounds checking on arrays it's not necessary to give up the advantages of
native programming and use a virtual machine.

Rust is obviously a great example. So is Go. Bounds checked arrays in
languages that compile to native is not a new thing.

~~~
Alphasite_
Swift is another new language with it. Its getting to be the norm now.

------
bootload
_" The buffer overflow has long been a feature of the computer security
landscape. In fact the first self-propagating Internet worm—1988's Morris
Worm—used a buffer overflow in the Unix finger daemon to spread from machine
to machine."_

I thought the daemon exploited was sendmail? ... quick search later ... so the
fingerd was used. Good explanation here: ~ Eugene H. Spafford, _" The Internet
Worm Program: An Analysis"_ [http://spaf.cerias.purdue.edu/tech-
reps/823.pdf](http://spaf.cerias.purdue.edu/tech-reps/823.pdf)

------
rawdisk
Are "buffer overflows" possible in systems without without virtual memory?

I know how I would answer this question but I am curious how others would
answer it.

EDIT: s/possible/known to occur

~~~
pyre
As long as you have the ability to address memory directly, I would say that
it's possible. I'm not 100% sure about how memory is allocated though. Outside
of virtual memory, are the actual chunks of memory sequential, or would
overflowing an offset get you a chunk of another process? (I imagine the
answer might be implementation dependent)

~~~
shanemhansen
It's more important to have bounds checked access and to disallow pointer
arithmetic. If you do that, pointers (addresses) are fine.

------
segmondy
Seriously this is old news 20 years too late and not even good enough,
checkout Phrack article, "smashing the stack for fun and profit" written in
96. This is what unleashed the flood gates. With sample codes to boot.

------
nickpsecurity
The Burrough's architecture (1961) had a CPU that bounds-checked arrays &
pointer access. Also differentiated code and data to prevent... all kinds of
security issues. Total overhead in memory was 6% w/ almost zero overhead in
CPU in such a design if you run security-checks in parallel with rest of
pipeline while only committing a write if security check is OK. This is the
modern approach.

[http://www.smecc.org/The%20Architecture%20%20of%20the%20Burr...](http://www.smecc.org/The%20Architecture%20%20of%20the%20Burroughs%20B-5000.htm)

No matter what naysayers claim, the ability to inexpensively immunize a system
against buffer and stack attacks has existed for decades while being deployed
commercially on _1960 's-1980's era hardware_. The market went for what was
backward compatible with IBM, UNIX, and later DOS software plus highest raw
performance at lowest price. Systems designed for excellent security and
maintenance (esp written in HLL) had low market share with many getting
acquired, disappearing, or having security advantages removed in later
releases. It's a market thing, not a technical thing.

Here's a modern example, the SAFE architecture, that's being developed by BAE
& academia.

[http://www.crash-safe.org/assets/ieee-hst-2013-paper.pdf](http://www.crash-
safe.org/assets/ieee-hst-2013-paper.pdf)

It's actually more heavyweight as it tries to fix... computing in general
haha. It specifically mentions buffer overflows and stack risks with the ways
they try to immunize against them. The atomic groups with associated
processing are actually lightweight a la Burrough's model. They alone provide
quite the bit of protection seeing how many types of attack leverage pointer,
array, or stack flaws. The other tag will cause more of a hit but could do
type enforcement of calling functions. Is also very helpful given interface
errors underlie most attacks on systems. I've suggested porting Oberon System
and compiler to this architecture to get a fully-usable box with automated
protection. And see what attacks can still get through.

In any case, buffer overflows have been preventable since before they even had
a name past being an example of "insufficient argument validation" (MULTICS
security evaluation). They only exist because (a) market wants them to exist
via how it votes with its wallet and (b) legacy software refuses to take the
hit that automated protections created. The latter situation improved greatly
with tools such as Softbound + CETS which enforces full safety on C code with
average 50% hit, limited tools such as Control Pointer Integrity that protects
pointers with a tiny hit, and tools such as ASTREE/SPARK that prove C/Ada code
free of many types of errors that lead to crashes or hacks. Pretty much no
uptake.

There are counterexamples though. I've seen a reverse stack on x86, a DNS
server (IRONSIDES) written in SPARK, security kernels that extensively used
segmenting for OS-level POLA, a web application server reducing risk w/ FSM's
+ a separation kernel, and recently MirageOS building a whole stack in a
language that prevents so many issues at compile-time while designing for
isolation in partitions. So, we can do it better, some are doing it better,
and I encourage others to do the same. Look for work that knocks out issues,
use it, improve it, and get our baseline up to at least OK instead of FUBAR
(current status).

