
Spectre and the end of langsec - robin_reala
http://wingolog.org/archives/2018/01/11/spectre-and-the-end-of-langsec
======
forapurpose
I'm starting to consider whether this reflects a larger failure in the
industry/community: Traditionally, many of us (I'd say almost all) have been
focused on security at the OS level and above. We've assumed that the
processor and related hardware are safe and reliable.

However, below the OS level much new technology has been introduced that has
greatly increased the attack surface, from processor performance enhancements
such as branch prediction to subsystems such as Intel ME. I almost feel like
Intel broke a social compact that their products would be predictable, safe
commodities on which I can build my systems. But did those good old days ever
really exist?. And of course, Intel naturally doesn't want their products to
be commodities, which likely is why they introduced these new features.

Focusing on OS and application security may be living in a fantasy world, one
I hesitate to give up because the reality is much more complex. What good are
OpenBSD's or Chrome's security efforts, for example, if the processor on which
they run is insecure and if there are insecure out-of-band management
subsystems? Why does an attacker need to worry about the OS?

(Part of the answer is that securing the application and OS makes attacks more
expensive; at least we can reduce drive-by JavaScript exploits. But now the OS
and application are a smaller part of the security puzzle, and not at all
sufficient.)

~~~
gibson99
The issue of hardware security really has been ignored too long in favor of
the quest for performance enhancement. Perhaps there is a chance now for
markets to encourage production of simplified processors and instruction sets
that are designed with the same philosophy as OpenBSD. I would imagine
companies and governments around the globe should have developed a new
interest in secure IT systems with news about major exploits turning up every
few months now it seems.

------
lclarkmichalek
Really not the end. The existence of issues that cannot be addressed via
'langsec' does not imply that we should give up on 'langsec'. There will be
more security issues due to buffer overflows than there will be CPU bugs this
year. More importantly, there will be orders of magnitudes more users with
data compromised via buffer overflows, compared to CPU bugs.

~~~
alxlaz
The author does not seem to mean "the end of langsec" as in "everyone will
give up on it", but rather the end of a period characterized, and not
incorrectly, by the opinion that a safe programming language guarantees the
absence of unintentional unsafe behaviour. In short, that things which, within
this "langsec framework", one could prove to be impossible, turn out to be
possible in practice; in the author's own words:

"The basis of language security is starting from a programming language with a
well-defined, easy-to-understand semantics. From there you can prove (formally
or informally) interesting security properties about particular programs. [..]
But the Spectre and Meltdown attacks have seriously set back this endeavor.
One manifestation of the Spectre vulnerability is that code running in a
process can now read the entirety of its address space, bypassing invariants
of the language in which it is written, even if it is written in a "safe"
language. [...] Mathematically, in terms of the semantics of e.g. JavaScript,
these attacks should not be possible. But practically, they work. "

This is not really news. The limits of formal methods were, in my opinion,
well-understood, if often exaggerated by naysayers, brogrammers or simply
programmers without much familiarity with them. Intuitively, it is not too
difficult to grasp the idea that formal proofs are exactly as solid as the
hardware which will run the program about which one is reasoning, and my
impression is that it was well-grasped, if begrudgingly, by the community.

(This is akin to the well-known mantra that no end-to-end encryption scheme is
invulnerable to someone looking over your shoulder and noting what keys you
type; similarly, no software-only process isolation scheme is impervious to
the hardware looking over its shoulder and "writing down" bytes someplace
where everyone can access them)

~~~
allenz
> the end of a period characterized, and not incorrectly, by the opinion that
> a safe programming language guarantees...

I don't think that there was ever such a period. Provable correctness always
had the caveat of highly idealized assumptions, and we've known from the start
that hardware vulnerabilities such as timing attacks, rowhammer, gamma rays,
and power loss can undermine those assumptions.

------
nordsieck
> Rich Hickey has this thing where he talks about "simple versus easy". Both
> of them sound good but for him, only "simple" is good whereas "easy" is bad.

I don't think I've ever heard anyone mischaracterize his talk [1] this badly.

The claim is actually that simplicity is a fundamental property of software,
whereas ease of use is often dominated by the familiarity a user has with a
particular set of tools.

[1] [https://www.infoq.com/presentations/Simple-Made-
Easy](https://www.infoq.com/presentations/Simple-Made-Easy)

~~~
spiralganglion
Agreed, but I have see a lot of people come away from the talk with an
unfortunate disdain for ease. Ironically, in disentangling "simple" and
"easy", Rich created a lot of confusion about the value of ease.

------
scott_s
My personal take is that perhaps chipmakers will start to see different market
pressures. Performance is the big one, and it's been around since the first
microprocessor. Power became increasingly more important, particularly in the
past decade, from both ends of the market. (Both mobile devices and
supercomputers are very power conscious.)

Security may become a new market pressure. You will likely sacrifice
performance to get it, as it will mean simpler cores, maybe in-order, and
probably without speculative execution. But, with simpler cores, we can
probably further increase hardware parallelism, which will only partially
mitigate the loss in single-threaded performance. Some chips may even be more
radically security conscious, and guarantee no shared caches between
processes. Such chipmakers would be able to say: we can't say for certain that
these chips are fully secure, but because they are simpler with less attack
vectors, we are far more confident they are. Security conscious chips may tend
to be the ones that are internet facing (your mobile device, cloud data
centers), and faster, less security conscious chips may only exist behind
strict firewalls.

I bring this up in response to the submitted article because I find it
unlikely that we will start to model processor insecurity at the language
level. It ruptures too many levels of abstraction. I find it more likely that
we will find ways to maintain those abstractions.

~~~
tzs
> Security may become a new market pressure. You will likely sacrifice
> performance to get it, as it will mean simpler cores, maybe in-order, and
> probably without speculative execution.

Maybe we go from having CPU + GPU to having CPU + GPU + FPU, where FPU = "Fast
Processing Unit".

The CPU in the CPU/GPU/FPU model becomes simpler. Any time we have to choose
between performance and security we choose security.

The FPU goes the other way. It is for things where speed is critical and you
either don't care if others on the machine can see your data, or you are
willing to jump through a few hoops in your code to protect your secrets.

For most of what most people do on their computers most of the time,
performance is fine without speculative execution or branch prediction and
probably even with caches that are completely flushed on every context switch.
(It will probably be fine to leave branch prediction in but just reset the
history on every context switch).

The FPU memory system could be designed so that there is a way to designate
part of FPU memory as containing secrets. Data from that memory is
automatically flushed from cache whenever there is a context switch.

~~~
sliverstorm
I believe you can make a process noncacheable today, and maybe even disable
branch prediction. This would totally shut down Spectre and Meltdown. You can
disable SMT, and there's a whole host of other things you can do to isolate
your "secure" process on an existing chip. Nobody has done these things
because they like performance.

 _For most of what most people do on their computers most of the time,
performance is fine without speculative execution or branch prediction_

I think you underestimate the importance of branch prediction.

------
tdullien
I think this is too dark a post, but it shows a useful shock: Computer Science
likes to live in proximity to pure mathematics, but it lives between EE and
mathematics. And neglecting the EE side is dangerous - which not only Spectre
showed, but which should have been obvious at the latest when Rowhammer hit.

There's actual physics happening, and we need to be aware of it.

If you want to prove something about code, you probably have to prove microop
semantics upward from verilog, otherwise you're proving on a possibly broken
model of reality.

Second-order effects are complicated.

~~~
ddellacosta
Rowhammer I can understand, but how do you come to that
conclusion--"neglecting the EE side is dangerous"\--from analyzing Spectre?
Does speculative execution rely somehow on physical effects? I can't find
anything ( for example here:
[https://en.wikipedia.org/wiki/Spectre_(security_vulnerabilit...](https://en.wikipedia.org/wiki/Spectre_\(security_vulnerability\))
) that suggests there is a physical component to this vulnerability.

~~~
mst
I'd argue that using timing differences due to physical limitations of the
hardware that to exfiltrate data based on whether or not it's cached is very
definitely 'relying on physical effects'

~~~
ddellacosta
> timing differences due to physical limitations of the hardware

I see; so you're talking about step two as described here, do I have that
right?

[https://en.wikipedia.org/wiki/Spectre_(security_vulnerabilit...](https://en.wikipedia.org/wiki/Spectre_\(security_vulnerability\)#Detailed_explanation)

This seems like a failure of algorithm design to me, in the sense of not
starting with a better model that more accurately encodes the possibility of
timing attacks. That being the case it appears to me to be a problem still
firmly residing in the domain of computer science.

But, I'm a programmer, not a chip designer, and I have very little knowledge
of this field, so I'm probably biased and not thinking about this correctly or
with enough nuance.

~~~
mst
Quoting the thread root:

> Computer Science likes to live in proximity to pure mathematics, but it
> lives between EE and mathematics

which doesn't disagree with "firmly residing in the domain of computer
science" \- it's merely a question of nobody having factored the right bit of
EE into the right bit of math to get the right model.

------
perlgeek
I don't see how this is fundamentally different than timing attacks and other
side channel attacks that have been well known before, and to the best of my
knowledge, simply hasn't been the focus of the "prove it correct" approach.

Whenever you want to prove something correct, you need to make assumptions
about the execution model, and about what correctness means. Now "we" as an
industry found a bug that makes the actual model differ from the assumed
model, so we need to fix it.

The same is true when you can measure the power used by a microchip during
some cryptographic operation, and infer the secret key from that -- even if
the cryptographic operation has been proven correct, the definition of
correctness likely didn't include this factor.

------
KirinDave
While langsec can't easily mitigate spectre because the processor is trying to
hide where the performance comes from, it's worth noting that several new
languages are working on ways to write code where you can actually assert and
have the compiler check that the timing of the code you write is bounded and
uniform.

It's very easy, I think, to throw up our hands and say, "Well gosh all this
language stuff is useless because timing attacks are so scary!" But in
reality, they're pretty well studied and many of them are actually pretty
simple to understand even if they can be hard to recognize.

Both hardware AND software sides of our industry need to start taking
correctness, both at compile and runtime, seriously. The days where we can
shrug and say, "But that's too slow, don't run code you don't trust" are dead.
We killed them by ceding the idea of hardware ownership to big CSPs. The days
where we can say, "This is too complicated to do!" or "This doesn't deliver
customer value!" are also going away; the threat of combination attacks easily
overshadows any individual attack, and small vulnerabilities tend to multiply
the total surface area into truly cataclysmic proportions.

But also gone is the day when we can say things like, "Just use Haskell or
OCaml!" We've seen now what these environments offer. It's a great start and
it's paved the way for a lot of important understanding, but even that is
insufficient. Our next generation of programming environments needs to require
less abstract category theory, needs to deliver more performant code, and
needs to PROVE properties of code to the limit of runtime resolution. The
hardware and OS sides of the equation need to do the same thing. And we as
engineers need to learn these tools and their techniques inside and out; and
we shouldn't be allowed to sell our work to the general public if we don't.

~~~
zbentley
> several new languages are working on ways to write code where you can
> actually assert and have the compiler check that the timing of the code you
> write is bounded and uniform.

I'm interested in how that would avoid the halting problem. Let's say I write
code, compile it, and run some "timing verifier" on it. That verifier either
runs my code and verifies that it's timing is correct _on that run_ , or
inspects the machine code against a known specification of the hardware I'm
running it on _right then_ and ensures all of the instructions obey my timing
constraints. How would you check that the code's timing is bounded and uniform
on subsequent executions? Or on other hardware? Or in the face of
specifications that are incorrect regarding the timing characteristics of
machine code instructions (CPU/assembly language specs are notoriously
incomplete and errata-filled).

I suspect something fundamental would have to be changed about computer design
(e.g. a "CPU, report thine own circuit design in a guaranteed-accurate way")
to make something like this possible, but am not sure what that would be, or
if it's feasible.

~~~
UncleMeat
It avoids the halting problem the same way literally all sound static analysis
does. With false positives. The java type checker will reject programs that
will not have type errors at runtime. And a system that verifies timing
assertions with SMT or whatever will reject some programs that will not fail
the assertion.

The halting problem has never actually stopped static analysis tools. Static
analysis tools that check timing assertions have been around for a very long
time.

~~~
zbentley
Sure, but this isn't a static analysis tool in the same way a type system is.
This is an analysis tool which checks for mostly platform-unrelated, entirely
runtime behavior which can vary based on a lot of external factors.

When you say "Static analysis tools that check timing assertions have been
around for a very long time.", what are you referring to? I've used analyzers
that check for potentially-inescapable loops, do assembly/machine code
operation counts, and look for the presence of interruptions that are _known_
to take a potentially infinite/nondeterministic amount of time (waiting for
I/O), or ones whose _lower_ bound in time is known (scheduler interactions
like sleep). How would you analyze for instructions which have theoretically-
constant times, but which in practice are vulnerable to "constant plus or
minus"-type timing attacks like Spectre? How would that analysis yield results
we don't already know, a la "in this section of code, you should
obfuscate/prevent the gathering of timing data, and/or try to defeat
speculative execution"?

~~~
KirinDave
There is no one here saying that there is a runtime that can protect against
Spectre. Spectre is just one of extreme example of timing attacks which have
been troubling our industry for the better part of a decade.

It's entirely possible to prove that some types of code do not significantly
very they're running time based on the character of their input. A classic
example of this is hashing algorithm whose execution time is only dependent on
the length of the input.

I'm not sure if people recall password oracles but they're still valid attacks
today. We can only eliminate these by starting at the bottom and working our
way up.

If your response to Spectre is to give up on your computer security, I don't
think I want you writing software for me. These are the challenges our
industry has to face. Failure is not really an option.

------
hacknat
Everyone is assuming the author is giving up on Langsec. Read carefully, he
called Spectre/Meltdown a setback. I think he’s making a subtler point that
the fundamentals of programming have become more of a pragmatic activity than
a mathematical one, if you’re being practical about your goals that is. I’m
currently on the kubernetes multi-tenancy working group (which isn’t really a
working group yet) and its really funny to see how much effort is going into
securing containers, but core bits like the CNI receive little attention. A
wise security professional, ex hacker said that he actually liked over
engineered security systems as a hacker, because it told him what not to focus
on. Container security pretty good? Okay then figure out how to do what you
want without breaking out of the container (definitely possible in the case of
Spectre/Meltdown).

There is a fundamental cognitive bias in our field to solve the technically
challenging problems without realizing that there are practical
vulnerabilities that are far more dangerous, but a lot more boring to solve
(the most common way orgs are exploited is through a combination of social
attacks and something really trivial).

I think the author is frustrated because he feels the interesting work is
unimportant in comparison to the practical.

That isn’t to say that this work isn’t helpful. I’m very glad to be working
daily in a typesafe, memory safe language, but I have bigger fish to fry now
as a security professional on the frontline.

------
saulrh
On the one hand, langsec specifically handles these problems. A program for
searching through a file will produce the same results whether it runs in a
tenth of a second or ten seconds, and as such doesn't need to - in langsec,
shouldn't be _able_ to - access the time. That's what langsec is. It can even
identify hazards like the SharedArrayBuffer high-res timers that compare the
execution speed of different programs by communicating between processes; most
programs shouldn't care which thread finished first, so that information
shouldn't be available! And so we build formalisms for computing that don't
make that information available to the program.

On the other hand, that's probably infeasible for the real world. Humans care
about time too much for it to be declared off-limits to many programs.
Similarly with things like communicating processes. These attacks are so
fundamental that it'd be effectively impossible to build a program that didn't
throw up an impenetrable wall of critical langsec violations.

So I'm not sure. The langsec framework _does_ offer a solution. It might just
be that, in the same way that things like haskell offer their solutions, it's
too difficult for the real world to apply it.

------
willvarfar
There are CPUs that are immune to these attacks, including spectre.

The CERT recommendation was to throw away affected CPUs and use alternatives.

Now this isn't very realistic today when the in-order alternatives are slow
and not comparable performance. But it does say that CERT is not giving up on
langsec.

(Team Mill - we're immune too and will put out a light paper on how these
attacks apply to in-order processors that support speculation and what we're
doing to prevent them)

~~~
gbrown_
> Team Mill - we're immune too and will put out a light paper on how these
> attacks apply to in-order processors that support speculation and what we're
> doing to prevent them

Will this be sent to the mailing list when released?

~~~
willvarfar
Yes probably.

I've already written the paper and it's just got to survive a lot of peer
review. It turns out that it would be real easy to envisage an in-order
processor that has some mechanism for speculation that was actually vulnerable
to spectre and variations of meltdown and the paper explores that - so
hopefully it's an interesting paper even if the tl;dr is we claim to be
immune.

~~~
cwzwarich
I'm curious, because I think the Mill as described in the talks is vulnerable
to a variant of Spectre. If you have a sequence of code like this:

    
    
        if (index < bounds) {
            index2 = array1[index];
            ... array2[index2];
        }
    

If the compiler speculates both array accesses above the bounds check, then
the first one can still succeed (i.e. not produce a NaR) while accessing
attacker-controlled memory for the value of index2.

You could obviously fix this by never generating code that does double
speculation, but you could also do that by modifying a conventional OoO
microarchitecture.

~~~
willvarfar
Spot on!

This variant of Spectre would be software bug not a hardware bug on the mill.

Our specialiser had to be fixed to _not_ produce code with this flaw.

And so we wrote a light paper on it, and perhaps a talk etc ;)

~~~
cwzwarich
It seems that Mill's combination of a single address space and speculation-
before-permissions-checks is still quite vulnerable to an ASLR leak. Have you
made any changes to mitigate this, or do you just consider address space
layout leaks acceptable behavior?

~~~
hduty
seriously? Mill is/will do speculation before perms? And here I thought turfs
were the elegant answer to this nightmare.

~~~
cwzwarich
See slide 72 of the metadata talk[1] and slide 51 of the IPC talk[2], which
indicate that it does speculation before permissions checking.

Since turf permissions operate on the granularity of an arbitrary address
range (rather than a page like traditional MMUs), the permissions cache (what
the Mill calls a PLB) has a worse latency/power tradeoff than a traditional
TLB. The Mill takes advantage of its single address space and reduces some of
this hit by doing permissions checks in parallel with the access.

[1]
[https://millcomputing.com/docs/metadata/](https://millcomputing.com/docs/metadata/)
[2] [https://millcomputing.com/docs/inter-process-
communication/](https://millcomputing.com/docs/inter-process-communication/)

~~~
willvarfar
Thank you for watching the talks! :D

Luckily its not quite as you interpreted:

The L1$D is accessed in parallel with the PLB. Both at top-level caches - one
for data, one for protection.

If there is a PLB miss we have no cache-visible side-effects until the
protection has been resolved.

The paper we're preparing will cover this in detail, because as you can see,
the talks are a bit light on exactly what happens in what order when here.

------
barbegal
One of the big problems with Spectre and Meltdown is that they are due to
behaviours and components of a processor that are not well documented. Caches,
branch predictors, out of order execution and superscalar execution are all
things that processor vendors refuse to disclose any information about because
it is so commercially sensitive. Indeed CPUs are now primarily differentiated
by these features. We are no longer getting processors with faster clocks or
even smaller transistors so a lot of research has gone into making individual
instructions run faster (or at least run faster most of the time).

Neither Intel, ARM or AMD have disclosed why their CPU design are, or are not
vulnerable to Spectre and Meltdown. If the developers of compilers or even
operating systems don't know exactly how the hardware works then it is pretty
hard for them to know that they haven't written vulnerable code. By the same
token, it is also hard for them to know if they have written performant code.

And we know even less about other types of processors that exist in almost
every chip such as GPUs, digital signal processors, video processor units
(VPUs) and other hardware accelerators. Those processors can almost certainly
also leak data from other parts of the system, they have their own caches and
sometimes branch predictors. Although it is hard to specify the code that runs
on these devices it is almost certainly still possible to exploit bugs and
timing attacks in them.

We are essentially getting security through the obscurity of the devices and
security through obscurity is no good.

So should we have processor architectures which are completely open? In some
ways that would destroy most vendor's business models. But having more
openness could lead to more divergent processor architectures as vendors try
to differentiate themselves and it should improve the security of our systems.

------
xg15
Welcome to the cyberwar.

I think the basic problem with brakdown of static analysis tools like this one
or optimisations like speculative execution is that they were built in a
different time for significantly different requirements.

When the theories were developed, the main concern was to prove correctness
and protect against accidents. Yes, the OS isolated processes from each other
and protected memory boundaries - but this was added to keep a crashing
process from corrupting other processes and bringing down the whole OS. It was
_not_ developed to contain an actively malicious process.

At some point the paradigm changed and the idea spread that an OS shouldn't
just protect against misbehaving _code_ but also against misbehaving
_programmers_. That lead to the current practice of compartmentalizing a
machine in different areas of trust and tightly restricting what a program
_can_ do - and at the same time permitting increasing amounts of "untrusted"
code to run because we trust the boundaries so much.

I think the general paradigm shift has some worrying sides, but more
importantly, it was never explicitely discussed and it was never discussed if
the current tools of software and hardware development can even support that
new paradigm.

So yeah, in short, I think we are currently discovering that our houses are in
fact not built to withstand a 20kton TNT blast set off at the front door. So
far this hadn't been a problem as random violent explosions used to be a rare
occurence. Somehow we got ourselves in a situation where they aren't rare
anymore.

------
qubex
Am I wrong in recalling that Itanium (IA-64) was an in-order architecture that
relied on the compiler to explicate the potential for parallelism? Again, if I
recall correctly, the struggle to construct compilers that could do this
versus the apparent success (and lack of trade-offs) in letting in-processor
circuitry to reshuffle instructions at run-time was one of the main reasons
why _x_ 86’s 64-bit extensions prevailed (the other being poor performance
when running legacy _x_ 86 32-bit code).

Now it turns out that we really were benefitting from an advantage that had a
hidden cost, not in terms of performance (though power might be a concern) but
in terms of breaking the implicit model we have of how software executes, and
that this disconnect in turn opens us to a host of “architectural” risks and
metaphor breakages.

Maybe at this point we should consider reverting to the original plan and
insist on compilers doing the legwork, so that approaches such as langsec have
a hope of succeeding. Systems must be comprehensible (at least in principle)
and reliably deterministic from the top all the way to the bottom.

~~~
gpderetta
Itianium relies on advance loads which is a form of speculation introduced by
the compiler to perform competitively. It is not unlikely that this is as
exploitable as spectre.

~~~
qubex
I respectfully disagree for two main reasons. Firstly, because the compiler is
not transversal to all processes currently executing on the system at runtime,
so it isn’t a ”unifying step” that conjoins otherwise independent processes
and can allow them to interact. Secondly, if the compiler were found to be
leaking state between processes, simply changing the compiler’s logic would
allow rectification of these issues (albeit at the expense of recompiling all
software with the new compiler), with circuits etched onto a processor die one
has no such opportunity. What could be (at least potentially) an open-source
fix becomes the umpteenth binary blob from an opaque entity that tell us to
”trust them because [they] know best”.

~~~
gpderetta
Spectre is not (at least not directly), a cross address space vulnerability
(although it can be exploited in some cases from other address spaces).

A JS JIT running on itanium that generates advanced loads before bounds checks
will be vulnerable.

It is true that it can be fixed purely by software changes, by simply avoiding
issuing advanced loads [1], but then again software changes can also plug the
spectre v1 vulnerability on OoO architectures by adding artificial
dependencies on load-load sequences (see the WebKit mitigation article that
was discussed here a few days ago). Both software fixes have potentially
significant performance issues (more so on in-order architectures).

So yeah, in-order CPUs are less microarchitecturally vulnerable [2] to spectre
by default, but the compiler tricks required to make them competitive with OoO
CPUs might reintroduce the issue.

[1] In principle compiler issued prefetches and load hoisting can be an issue
on OoO CPUs as well, but as these are less important for performance compilers
can be more conservative. On the other hand some VLIW architectures have
special instructions and architectural support (like Itanium ALAT) to make
this load hoisting easier.

[2] There are in-order ARM CPUs that have been reported to be affected though.

~~~
gpderetta
Thinking more about this, the vulnerability would be in any load issued
speculatively which whose address depends on the result of a previous load.
This can be detected at compile time and avoiding just this scenario it will
not have such a performance effect as avoiding any speculative load.

------
urbit
Here's a more optimistic take which is unavoidably a plug.

Urbit is maybe a sort of "extreme langsec." "Immune" is a dangerous word.
Urbit is "premitigated" against Spectre for the following reasons, some cool
and others stupid:

(1) The Nock VM has no O(n) data structures, ie, arrays. This was not anything
to brag about till now.

(2) Urbit events are interpreted in their own process, which is one trust
domain (one process, one "personal server").

(3) A personal server isn't a browser and doesn't habitually run code its
owner doesn't trust.

(4) Urbit is purely functional, so you only know the time if someone passes
you the time.

(5) Top-level event handlers are passed the time of the event. This is easy to
fuzz.

(6) If you are running untrusted foreign code, it is probably just a function.
Giving this function a measured time interval from top-level event times would
be strange. And it would need another channel to exfiltrate the stolen data.

Never say never, but this combination of premitigations makes me worry about
Spectre very little. Although, when we do have a less-trusted tier of
applications (walk before run), ain't nobody is going to be telling them the
time.

Besides the plug, the lesson there is that one of the reasons Spectre is a
problem is that langsec is an imperfect bandaid.

Urbit is premitigated because it was designed as a functional system from the
ground up. The JS environment is functional lite -- it allows typeless
functional programming, but it also retains many mutable/imperative systems
design tropes.

It's these tropes that have become clever attack vectors. If you don't want to
get Spectred, build systems that are formal and functional all the way down.

~~~
drbawb
>(5) Top-level event handlers are passed the time of the event. This is easy
to fuzz.

Therein lies the rub -- if your program does not have access to precise timing
information, it is by definition not operating at the full capability of the
hardware which runs it. That's a hard sell to many domains.

Consider gaming. At 144Hz w/ 4K resolution you have 6ms to render a frame:
that's about 1.3ns per pixel. If for a moment we imagine that it takes
approximately 1 machine cycle per pixel to render a scene: that means you need
to be operating at 1.3GHz just to meet the deadline for drawing to the frame
buffer. -- That's before you consider memory & cache latency, or the fact that
your multitasking OS is stealing resources for itself & other competing
processes.

So no, one cannot just fuzz performance counters in the name of security. Any
soft-realtime or hard-realtime domain is going to expect the machine to
actually perform as advertised.

~~~
tartis
You are right: by definition real-time tasks will always be vulnerable.

With regard to Urbit, it is a non-issue because there are no use cases which
would warrant access to soft or hard-realtime for a networked OS.

Such tasks will always happen on client-side, by virtue of network latency.

------
zbentley
> Spectre shows us that the building blocks provided to us by Intel, ARM, and
> all the rest are no longer "small parts understood entirely"; that instead
> now we have to do "basic science" on our CPUs and memory hierarchies to know
> what they do.

I object to the term "no longer" in that sentence. There exist old CPUs that
are not vulnerable to these attacks, but their existence doesn't mean that
when those CPUs were in widespread use they were "understood entirely". I
imagine that most programmers affected by the F00F vulnerability in Pentiums
didn't fully understood what it was about the chip/microcode that caused the
lockup, either.

The parts being assembled change over time, but I think you can always say
"bah, {kids|engineers|scientists|etc} nowadays don't know how the things
they're plugging together work" and be trivially "correct" without making any
constructive point about how to go back to some nonexistent past in which
things were understood. Even when computers ran on vacuum tubes and physical
insects in machines as "bugs"
([apocryphal]([https://www.computerworld.com/article/2515435/app-
developmen...](https://www.computerworld.com/article/2515435/app-
development/moth-in-the-machine--debugging-the-origins-of--bug-.html)), I
know), people didn't know the composition of the hardware. Would one of those
programmers, on average, be more likely to fully understand, say the heat
range required for successfully making circuits in a tube or the effects of
anode corrosion on the lifespan of a tube, than a modern-day program would
understand how CPU microcode works?

The amount of complexity per part might go up over time. But there's always a
specialized threshold for "low level" understanding below which a) most people
don't operate and b) dragons lurk.

------
jokoon
I find weird and worrying that you cannot analyze the safety of a program
easily with some form of static analysis, or that there is no solution to do
an automated security audit.

I have been bragging for a long time that there are no organized effort
(state, government, scholars or otherwise) to teach basic software security in
programming. There are no ISO standard for computer security, or at least
there is nothing really relevant being taught. Security certifications don't
really mean anything, or it seems nobody cares enough.

I guess governments will have to get preoccupied with those things, because
you can clearly see that for now, it's an arms race kind of strategy, as long
as the NSA has the upper hand, things are okay, but if it becomes a bigger
national security concern, things might change. I guess you can smell that the
russians are getting good enough and that it's time to make internet security
a more prevalent matter for developers.

~~~
qubex
How can you hope to statically analyse something that executes non-
deterministically and whose state depends on the goings-on of all the
processes simultaneously hosted on that system? The whole point the author is
making is that there is a step at the bottom of all formal reasoning
hierarchies that doesn’t behave deterministically and thus undermines formal
reasoning about everything built above it. It’s just that we had never
recognised it as existing because we conveniently abstracted away this
reordering of instructions and thus had a model of the runtime environment
that doesn’t match with reality.

------
coldtea
> _Mathematically, in terms of the semantics of e.g. JavaScript, these attacks
> should not be possible. But practically, they work._

Obviously this is badly stated.

It's not correct to say "mathematically they should be possible given the
semantics of Javascript" and then say that "practically they work" as if
implying that the mathematics somehow broke down.

It's not the mathematics that failed you, but the assumptions (axioms) you've
used. Mathematically they are absolutely possible -- when you correctly
account for the real processor behavior. And if you had mathematically modeled
the whole "JS semantics + CPU behavior" accounting for Meltdown, mathematics
would have shown that it's not safe.

------
nine_k
Spectre has nothing to do with program correctness or safety. It has
everything to do with _hardware 's_ correctness and safety.

That is, the basic premise of hardware process isolation is that a process
cannot have any knowledge of what another process is doing, or whether it even
exists, unless it is explicitly permitted (e.g. the OS offers an API to look
at processes).

This basic premise is now broken: enough information leaks via timing as to
allow to read arbitrary memory regions. It's like you built a house laying
bricks in a formally correct way, but the walls proved to be permeable because
the bricks themselves have a flaw.

Since this flaw is not fundamental, that is, not even every currently existing
processor exhibits it, it appears to be reasonable to replace the flawed
design of the bricks, and not to re-engineer house construction.

There is a nice quote in the article, about doing basic science to find out
how software (and hardware) _actually_ works, since specs are badly
incomplete. It can be matched with another, earlier famous quote: "Beware of
this code; I only proved it correct, I did not test it." Black-box testing of
information systems is not going anywhere, formal methods or not; at the very
least, we need evidence that formal methods were not visibly mis-applied, and
also evidence that other basic premises, like those of hardware, still hold.
Because sometimes they don't.

~~~
ajross
> Spectre has nothing to do with program correctness or safety. It has
> everything to do with hardware's correctness and safety.

Yes, but safety is safety. The point of the article is that the assumption on
the part of language nerds for the past few decades -- that correct choice of
processes and implementation patterns as expressed by whatever favorite
runtime the author wants can protect us from security bugs -- turns out to be
_FALSE_.

Rust and Haskell programs are subject to Spectre attacks just as badly as K&R
C ones from 1983. All that pontification didn't actually work!

The point is that it puts a limit on pedantry about "correctness". That's all
based on an idea about a "computer" being an abstracted device, when it turns
out the real-world machines are in fact leaky abstractions. The lesson to my
ears isn't that you shouldn't use Rust or whatever, but that some humility
about the boundaries of "correctness" would probably be a good idea for many
of the pontificators.

~~~
kibwen
_> All that pontification didn't actually work!_

This is a bit silly. Security is a chain that is only as strong as its weakest
link. For decades we believed that C was the weakest link, and now, with
Spectre, we have discovered (drumroll, please!): nah, C is still the weakest
link. For all the amazingly scary things that Spectre brings to the table,
it's still less scary than Heartbleed and Cloudbleed were.

Don't get me wrong, hardware still sucks (and with Intel and AMD's growing
body of management engine incompetence they may yet overtake C as the weakest
link in the chain) but we will learn from this and get better. In the
meantime, we need to be pushing forward on all fronts: hardware security,
language security, kernel security, application security, network security...
nobody gets to stand still.

~~~
wahern
Long before Heartbleed or Cloudbleed researchers (and presumably attackers)
were using remote timing attacks to extract secret keys:

    
    
      https://crypto.stanford.edu/~dabo/papers/ssl-timing.pdf
    

And most big data breaches where information assets are actually stolen
involve services written using "safe" languages, like Java or SQL.

And even if C is the weakest link, all that means is that you're totally
screwed. No amount of Rust will save you when the Linux kernel, your
relational database, and every router between you and the attacker are written
using C or assembly.

At the end of the day, if you want strong security assurances you need to
prove the correctness of all the semantics (of which memory bounds
constraining is but one small aspect) of every piece of software in your
stack, or at the very least all the most critical pieces. And the best tooling
for that is for Ada and C.

------
rwj
The opening line that "The work of engineers used to be about taking small
parts that they understood entirely and using simple techniques to compose
them into larger things that do what they want" is not correct. Emergent
behaviour has always been an issue for complex system. Just look at the story
behind the Tacoma Narrows Bridge.

Computing is extremely complex, so the issue is probably more acute, but it is
not unique.

~~~
calebm
I agree with you. Engineers of physical things don't fully understand what
steel is made of (since we don't fully understand the lowest underpinnings of
matter or all of its properties).

------
musha68k
OK so do we finally get proper lisp machines now?

~~~
SomeHacker44
Lisp machines (at least, Symbolics Lisp Machines which I know well) didn't
suffer from these flaws. They were largely designed to be single-user machines
and there was literally almost no isolation between anything!

~~~
AnimalMuppet
But weren't Symbolics Lisp Machines from an era where _nothing_ suffered from
these flaws, because nothing did speculative execution?

~~~
SomeHacker44
As far as I know, this is true for the Symbolics Ivory CPUs, yes. That said,
these flaws would be irrelevant, if so, because the system built upon the
hardware did not enforce modern process isolation paradigms.

------
agentultra
Security by proof, model checking, semantics is still a good, effective tool!

Leveraging the type system is a good communication channel for programmers
maintaining the system.

Proofs and models of the protocols are still important.

But yes... we still need to fix CPUs. And the class of errors (those of
omission) are still worth removing from our code regardless of spectre or
meltdown.

------
realandreskytt
Security is an emergent property of a system consisting of users, software and
hardware. Thus, a programmer cannot prove security of a system but merely
assert its certain behaviour. Langsec does just that. No, it can never be used
to build secure systems. Yes, it can be used to solve practical problems
making things more secure.

------
chubot
The author of this post isn't properly characterizing langsec:

 _The basis of language security is starting from a programming language with
a well-defined, easy-to-understand semantics. ... This approach is taken, for
example, by Google 's Caja compiler to isolate components from each other,
even when they run in the context of the same web page._

From what I can tell, he's talking about the broader area of "programming
languages and security". That is not the same thing as
[http://langsec.org/](http://langsec.org/), which is essentially about using
grammars to recognize network PROTOCOL formats.

As far as I remember, one motivating vulnerability is that there were two
different parsers for SSL certificates, which allowed attackers to trick
browsers into accepting invalid certificates. That doesn't have anything to do
with programming languages per se; you can write this vulnerability in any
language. It's analogous to the fact that using a safe language doesn't
prevent you from SQL injection.

Some examples of what they are trying to address:

[http://langsec.org/papers/langsec-cwes-
secdev2016.pdf](http://langsec.org/papers/langsec-cwes-secdev2016.pdf)

I wrote a critique of langsec a few months ago here:

[https://lobste.rs/s/uyjzjc/science_insecurity_meredith_l_pat...](https://lobste.rs/s/uyjzjc/science_insecurity_meredith_l_patterson#c_pzjzxh)

tl;dr I think they are using the wrong formalisms.

I found it odd that the author was assuming that langsec is a widely used
thing when I think it is nascent research.

Even Google Caja, a totally different project outside of langsec, is not
widely deployed, although I very much like its ideas.

~~~
maradydd
Just FTR, your critique is answered by Stefan Lucks, Norina Grosch, and Joshua
Koenig's paper[0] from last year's langsec workshop at IEEE Security and
Privacy. They define a formalism, calc-regular languages, to handle length-
prefixed strings.

[0] [http://spw17.langsec.org/papers.html#calc-
regular](http://spw17.langsec.org/papers.html#calc-regular)

~~~
chubot
Thanks, this looks promising! I'll take a look.

------
titzer
Hi Andy, thanks for writing this.

I don't think we are fundamentally hopeless for "langsec", although history
will definitely be divided into two Epochs: a time before Spectre and a time
after.

Language runtimes and operating systems just got some really great new
research problems, and a lots of interesting ideas are afoot (many in V8
land).

~~~
UncleMeat
There is no way that this is true. The program analysis community has known
for decades that systems were only ever sound w.r.t. some assumptions. See
Andrew Appel's paper on breaking java safety with mcdonalds heat lamps from
like a decade ago for a fun example.

Basically every static analysis person I've talked to about this agrees that
it is a really really cool attack but that it doesn't represent fundamental
new information for the field.

------
stmw
I think there is a deeper truth here - understanding of what the hardware is
doing has always been essential for writing correct, secure, performant
programs - and it is the (IMHO, mistaken) ideology that this is not the case
that took the biggest hit from Spectre/Meltdown/et al.

------
kibwen
_> One manifestation of the Spectre vulnerability is that code running in a
process can now read the entirety of its address space, bypassing invariants
of the language in which it is written, even if it is written in a "safe"
language. This is currently being used by JavaScript programs to exfiltrate
passwords from a browser's password manager, or bitcoin wallets._

Isn't this incorrect? I thought it was Meltdown, not Spectre, that was being
used to read the browser's password manager from JavaScript, and that Spectre-
via-Javascript was limited to reading data within the same JS VM process (so
e.g. you could prevent Spectre from reading cookies by making them http-only).
This matters because meltdown is much easier to patch than Spectre.

------
workthrowaway27
This is like saying a compiler bug in a safe language ends langsec. Which is
obviously absurd. It means the implementation had a flaw, but that doesn't
make the whole thing worthless. And when the flaw is fixed the same guarantees
are restored.

~~~
madez
The problem is that what you call guarantees weren't guarantees to begin with,
and we can't be sure they are now.

~~~
workthrowaway27
That's true about any engineering artifact though. If your steel rebar isn't
built to whatever standard you require your concrete skyscraper isn't going to
be structurally sound. To build on top of the layers below you, you have to
trust that they work, and when problems occur you fix the problems as they
come up (or ideally prevent them ahead of time).

------
ngneer
I am not seeing the connection to LANGSEC. The Spectre and Meltdown attacks
turn the processor into a confused deputy, that is all. If anything, this is
predicted by LANGSEC. The beef is not even with hardware verification, as some
have suggested, because the specification never calls for such security
guarantees. The specification is architectural because we want different
processors to implement the same architecture, such that they are compatible.
The only reason transient instruction sequences have security violating side
effects is microarchitectural leaks.

------
tannhaeuser
I think concluding the "end of langsec" goes too far. We'll continue to need
both langsec, plus much more thorough hardware verification to re-establish
basic isolation assumptions lost with Spectre/Meltdown (or push for detailed
HW specs to begin with, to be able to assert these assumptions on our own).

OTOH, as if it wasn't obvious enough already, I'm seeing a serious issue with
the concept of executing arbitrary code from untrusted network locations, such
as with JavaScript on the Web.

------
juancn
The failure lies in forgetting that computers are not deterministic machines,
they are probabilistically deterministic machines instead.

They are physical constructs, not mathematical ones, and as such, verification
is inescapable if you want some level of assurance. You need tolerances and
experimentation after construction, even if you proved your thing correct.

In the words of Knuth: "Beware of bugs in the above code; I have only proved
it correct, not tried it."

------
crb002
The major chip manufacturers need to have two kinds of cores/caches. One that
has full security guarantees, the other that is optimized for energy
efficiency/performance and has zero interprocess security. This isn't a one
size fits all problem.

~~~
zzzcpan
I see some people assume that a possibility of a single chip that can do both
is not option. It is. It's only x86 that has to do everything in hardware and
hide everything from the user for backwards compatibility.

Imagine instructing a compiler for an architecture that does everything in
software, like Mill, to make every operation constant time or to speculate
aggressively and unsafely depending on what the program needs.

------
KaiserPro
Even on the Arduino I don't think I could claim that I knew 100% what was
going on, let alone go/python/JS -> kernel -> docker/VM -> -> kernel ->
processor

------
fnord77
meh.

reasoning always loses out to empirical techniques anyway.

------
jezfromfuture
Buy a new cpu that is fixed and problem gone maybe we shouldn’t change the
world maybe intel should fix there own problem? If a car has a serious fault
that makes it dangerous it’s recalled it’s time for intel to do the same.

