[pro] Heartbleed?

William Lederer william.lederer at gmail.com
Sun Apr 27 15:48:41 UTC 2014


Dan:

I mostly agree with what you are saying.  However there is one point in
much of this discussion that may not be covered.

Further, assertions that compiler writers of language A tend to write
compilers (or, in this case, standard libraries) that aren't safe in some
way while writers of compilers for language B write systems that are is,
frankly, self-congratulatory naval gazing.

There is a fundamental practical difference between C and Lisp that is
relevant in the security world. That is of the vast number of explicitly
undefined behaviors that are in the specification of C. This is pretty much
unmatched in Lisp or C# or Java. John Reghur at http://blog.regehr.org/ has
done some fascinating work not only about undefined behaviors of C, but
also of the substantial number of bugs in compilers.

And while what you say is true about dependencies on other libraries (this
is always a major item we check for when doing assessments) is a risk for
all systems (except for qmail), a significant fraction of all breaches are
a result of logic errors or configuration errors. These errors compromise
all systems equally, regardless of the language underneath.

wglb


On Sun, Apr 27, 2014 at 10:20 AM, Dan Cross <crossd at gmail.com> wrote:

> On Sun, Apr 27, 2014 at 4:27 AM, Steve Haflich <shaflich at gmail.com> wrote:
>
>> I agree with essentially everything in wglb's message, but (once again)
>> I'll grumpily jump in to emphasize a point which I think many on this list
>> have missed.
>>
>> On Fri, Apr 25, 2014 at 1:20 PM, William Lederer <
>> william.lederer at gmail.com> wrote:
>>
>>>
>>> I agree with the general sentiment that Lisp is a much safer language to
>>> build anything in. While several in this thread are pointing to bounds
>>> checking as one of the advantages that Lisp has over C and other languages,
>>> there is something else I find that is also very strong: It is easier to
>>> write programs about which a reader can reason about correctness. In Lisp,
>>> the programs tend to be closer to provable and errors are more evident. As
>>> in "obviously no deficiencies" vs "no obvious deficiencies".
>>>
>>> But in my experience, vulnerabilities result from
>>>
>>>    - Buffer Overflows/lack of bounds checking (Heartbleed and friends)
>>>    - Configuration errors
>>>    - Logic Flaws
>>>    - Dangerous use of user input (leading to SQLi, XSS, XSRF)
>>>    - Improper use of cryptography
>>>    - Unclear protocol specification (leading to OpenSSL)
>>>
>>> This (IMO entirely worthy and correct) summary can easily be
>> misunderstood!  Lisp may be superior because it has bounds checking. (We've
>> previously agreed that isn't guaranteed since it isn't in the ANS, and in
>> any platform likely depends on optimization qualities, including the
>> optimization qualities under which internal called routines were compiled.)
>>  But bugs based on buffer overflow don't on normal operating systems in
>> general involve bounds checking.  At some point on any modern OS, reading
>> or writing to a socket stream will involve passing to the OS (generally via
>> a thin user-mode C API layer like *nix read() and write(), or some socket
>> analogue).  Neither Lisp nor C will provide any automatic bounds checking
>> on such a call.  The OS treats the application's address space as a
>> mostly-contiguous undifferentiated sea of bytes(*).  It doesn't matter that
>> at the app level C also has this model of a sea of bytes, while in Lisp the
>> ocean is run-time tagged into small plots.  That distinction disappears
>> once one calls write(fd,buf,len).
>>
>
> This is essentially the point I made in my email on April 13; an
> application program these days (even one written in Lisp) necessarily
> depends on a large set of libraries and support software that the
> application programmer has little to no control over.  Naive pronouncements
> that we should simply write all our code in Lisp (or another "safer"
> language) are almost guaranteed to have limited effect because many
> security problems are manifest in code we depend on that is simply out of
> our control.  Rebuilding the entire ecosystem that our applications sit on
> is economically infeasible and still leaves us open to the possibility of
> security problems in the underlying hardware (which have been shown to be
> real and to have been recently exploited).  This in no way implies that we
> should not STRIVE to do better, but illustrates that the issue is more
> complicated than language A vs language B.
>
> Further, assertions that compiler writers of language A tend to write
> compilers (or, in this case, standard libraries) that aren't safe in some
> way while writers of compilers for language B write systems that are is,
> frankly, self-congratulatory naval gazing.
>
> The Lisp Machine in its several manifestations might be the only
>> counterexample,
>>
>
> This, however, I disagree with.  There are operating systems that deal
> solely with managed-code objects.  If one considers, e.g., IL to be the
> "hardware" that sits on top of the underlying native instruction set acting
> as microcode, then Microsoft's Singularity system could be described as
> approximately equivalent to a Lisp machine in this regard.
>
> since there was no C boundary over which to cross, and because type and
>> bounds checking was performed for free in the microcode.  But Lisp machines
>> aren't around any more largely because of the economy of scale.  The number
>> of x86 and x64 processors on the planet must be nearly on the order of
>> 10^9, while the number of Lisp machine processors never got out of the 10^5
>> range, so Intel and AMD etc. could justify huge investments making those
>> processors 3 orders of magnitude faster in raw speed.  Lisp processors
>> could not have kept up at bearable per-item cost.  Alas!
>>
>> It is certainly true that the Heartbleed bug resulted from an
>> insufficiently-cautious implementation of an (overly?)complex
>> specification.  The author of the bug has essentially agreed with this
>> analysis.  But the "bounds checking" of most Lisp implementations would
>> provide no protection against this failure (about which the original
>> posting agrees) unless the succinctness and superior clarity of CL vs C
>> code might help it be seen.  That's a thin thread on which to hang an
>> entire language argument.
>>
>
> Actually, I'm not sure about that; in this case, the boundary violation
> was real and due to not taking into account the length of the input (e.g.,
> one memcpy'd more than had been provided, reading off the end of the source
> buffer).  But it was a rookie C programmer mistake, and I agree that this
> is indeed scant ammunition in a language beef.
>
> (*) I originally saw this beautiful metaphor, that C treats memory as an
>> undifferentiated sea of bytes, on some discussion list but can't remember
>> the originator.  Google shows current use scattered over many programming
>> subjects, but doesnt identify the original.  Anyway, it is the reason that
>> a small hyper-efficient C-struct-in-Lisp defining macro I wrote for a
>> certain huge CL software product is named "define-sea-struct" and (I used
>> to be a sailor) the operator for computing offsets possibly through
>> multiple levels of nested structs is called "following-sea".
>>  Paradoxically, http://www.ibiblio.org/hyperwar/NHC/fairwinds.htm says
>> "following seas" means "SAFE journey, good fortune" [emphasis added].
>>
>
> Semper Fi.
>
>         - Dan C.
>
>
> _______________________________________________
> pro mailing list
> pro at common-lisp.net
> http://common-lisp.net/cgi-bin/mailman/listinfo/pro
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/pro/attachments/20140427/74e7394a/attachment.html>


More information about the pro mailing list