
Unikernels are secure - ingve
http://unikernel.org/blog/2017/unikernels-are-secure
======
meson2k
> Good luck guessing that address. Our own unikernel, IncludeOS, randomizes
> addresses at each build, so even with access to source code you still don’t
> know the memory layout.

"There is one mortal sin in computer security (or by the way, in any kind of
security) that is feeling safe. It’s just a variation of pride to be true, but
it’s very deadly. Blindly trusting a protection technology is an extreme
error."

Read up on DEP. Randomizing function addresses at each build is useless when
it comes to attack mitigation. You need to randomize addresses at each
execution.

~~~
agumonkey
is linux randomizing is per exec ?

ps: BSD have started to randomize at boot time, fun times

~~~
geofft
> _is linux randomizing is per exec ?_

Not entirely sure what you're meaning to ask, but yes, Linux does KASLR and
tries very hard not to leak pointer addresses from the running kernel to
unprivileged userspace:

[https://lwn.net/Articles/569635/](https://lwn.net/Articles/569635/)

It's been enabled by default since the upstream 4.12 kernel, and usually well
before that in distros.

~~~
_joel
KALSR's not the same as ASLR (although ideologically related). ALSR has been
around for a good number of years in userspace via randomize_va_space sysctl

(edit I presume that's what the poster above mentioned re: per exec)

~~~
agumonkey
yes ALSR, sorry, acronym fail on my part. So ALSR does randomize bindings on
each execution ?

~~~
majewsky
Yes. If I run e.g. `ldd /bin/bash` multiple times, it shows different memory
addresses each time. That's ASLR.

~~~
strcat
cat /proc/self/maps is a better way to see that. If it's built with PIE, the
executable base is randomized. Some distributions use full ASLR across the
board (Alpine, Android, ChromeOS, Hardened Gentoo) while others don't yet
enable PIE globally or have only recently started and it isn't all pushed out
yet (OpenSUSE, Fedora, Debian).

------
wglb
I would hesitate to call something Secure unless some major pen test effort
were engaged to try to break it.

This is a corollary to "If it isn't tested it is broken". (Another corollary
is "Even if it is tested, it may still be broken.") This is more so with
security.

Just looking at some of the assumptions, e.g., that the lack of a shell
significantly increases the difficulty of an attack, leaves me with doubts
about the claims.

~~~
perbu
Hi author here. I agree wholeheartedly. I wasn't thinking in absolutes, but I
absolutely can understand how it could read that way. I could have titled the
post "Unikernels are resonably secure", but then nobody would have read it.

I was doubtful about mentioning the lack of shell. Technically it doesn't
really do much in terms of security, but it does make a compromise harder. And
currently, where we stand, a lot of the security comes from things being
really, really hard to compromise. Guessing adresses, not having a shell,
potentially no filesystem, etc.

~~~
wglb
With _" Unikernels are reasonably secure", but then nobody would have read
it._, you might also take into account whether the audience, having read it,
are happy that they did. The title sounded pretty absolute.

So you do have a noble goal. When I am asked to assess software, to gain a
first order approximation, I often look at the culture of the organization
that produced it. On the high end, that often translates to some sort of
formal process involving un-fun letters like 'ISO' and 'SOC'.

For smaller organizations, or OSS software, I try to get a feel for how the
developers seem to be thinking about security. Some of the cultural things I
see in your writeup are encouraging--Smaller Codebase, Removing hardware
emulation, Cutting off access to ring 0--all bode well for how you are
thinking about producing secure software.

But there are some things that are missing from your description. What is your
development process? In particular how and when do you attack your assumptions
about how the code actually works? What flaws have you found in your testing?
Zero findings could mean 1) it wasn't tested 2) it wasn't tested very hard 3)
the testers were not very good at security testing.

And as OpenBSD's history has illustrated, some things are totally secure until
they aren't.

------
kasey_junk
I'm interested that they didn't list the "old" reason people thought
unikernels _could_ be more secure. That is that they could be small enough to
be _completely_ written in higher languages. With something like
[https://github.com/GaloisInc/HaLVM](https://github.com/GaloisInc/HaLVM) you
could bring to bear formal methods in more straight forward ways.

This of course left the host still needing to be secured using traditional
approaches but that surface area was smaller.

I'd buy that you can't list that in an article about why _all_ unikernels are
_already_ secure, but that seemed to be the heart of the pitch to me when I
first started hearing it.

~~~
woodrowbarlow
well, you also have to keep in mind that this article is written by the CEO of
a company producing a particular unikernel implementation -- one that isn't
written in a higher language.

------
skywhopper
So to summarize, unikernels stop a couple of attack vectors (syscalls and
running other programs (notably shells) that are loadable from well-known
paths). Address randomization is not unique to unikernels, and the other
benefits are theoretical for the time being until hypervisors provide more
unikernel support (though the mention of paravirtualization makes me think
performance (particularly network) in this theroetical hyper-restricted mode
will be poor).

While I certainly sympathize with the idea that the typical kitchen-sink
deployment of a full suite of administrative/troubleshooting/build tools on an
application server is a security risk, it seems the actual improvements
enumerated here are relatively small potatoes.

Apologies for not knowing a lot about the state of the art here, but I'm
curious about how these unikernels address VM-internal security (eg, network,
filesystem, inter-process level stuff). Do you farm all of that out to the
hypervisor? Design around the lack of it? _Is_ there even "inter-process
stuff"?

------
nneonneo
So, basically, we're going to run all your code at ring0, so a single bug is
now either a total DoS (kernel shuts down) or an exploit vector straight to
ring0. Although they talk hypothetically about a defense for that involving
the MMU, this is not implemented in IncludeOS.

The build should not be relied on to be secure either; certain classes of
memory disclosure bugs could leak out enough memory to let you work out e.g. a
ROP payload, which wouldn't require injecting any machine code necessarily.
Plus, a long-lived machine, or a single instance deployed across many
machines, would present insufficient diversity to protect against a determined
attacker. The gist here appears to be the notion that their build diversity
gives them most of their security, while they've eliminated most of the
traditional defense layers (ASLR, DEP/NX, privilege separation, API isolation,
etc.)

If the attacker gets her machine code running in the unikernel environment,
it's game over no matter what. The machine code can just directly implement a
subset of needed functionality without having to call out to unikernel
functions.

In short - this post has a hell of a click bait title but really insufficient
evidence to suggest that these are truly "secure".

~~~
wmf
Keep in mind that it's ring 0 inside a VM that contains almost nothing. Really
a unikernel is just a process that uses hypercalls instead of system calls. So
exploiting a unikernel is no worse than exploiting a user process, and the
article explains a few reasons it could be more secure.

But they should definitely add ASLR.

~~~
language
Just like an operating-system executes processes, a VMM executes unikernels.
An operating system is responsible for randomizing the layout of processes in
memory. Shouldn't the actual question here be _" Does my hypervisor implement
some mechanism for randomizing the layout of my unikernel?"_

~~~
wmf
I don't think it matters whether it's implemented by the hypervisor or the
unikernel since it's all open source. But for compatibility with existing
hypervisors/clouds one could imagine a boot loader that loads the main
unikernel at a random address, sets up page tables with NX, and then makes a
one-way transition to ring 3 so that the page tables cannot be modified.

~~~
language
> one could imagine a boot loader that loads the main unikernel at a random
> address, sets up page tables with NX, and then makes a one-way transition to
> ring 3

True - I suppose I'm trying to hold onto the "kernel:hypervisor ::
process:unikernel" analogy here for no good reason. Following it suggested
that it might be the hypervisor's responsibility.

------
dmitrygr
The argument that something _IS_ secure is somehow supported by a whole lot of
hypotheticals of the form "we could do $X and that would be secure if someone
also did $Y".

So say it how it is: _unikernels COULD be secure if all this work that needs
to be done and we haven 't done was done...maybe_

~~~
wmf
That's par for the course. Unikernel people talk about VMs that use megabytes
of RAM while cloud providers only provide gigabytes. Unikernel people talk
about spawning VMs in tens of milliseconds while clouds take tens of seconds.

------
Cieplak
Hypothetically, if there were a buffer overflow in a unikernel process,
wouldn't it potentially give the exploit full-system access, whereas a normal
operating system would detect the out-of-bounds memory access and kill the
process? I'm sorry if this is an ignorant question.

~~~
leggomylibro
I could be wrong, but I think this is what Memory Management Units are for, on
processor chips. It's one major differentiator between application processors
and more embedded ones like Cortex-M or ATMega MCUs, which typically can't run
complex modern operating systems. A lot of those chips have a simpler Memory
Protection Unit that does basic enforcement of permissions like read+execute,
read+write, etc, but they lack the ability to partition memory virtually
between a large number of potential 'owners.'

I think - I'm still learning about this embedded stuff.

~~~
vertex-four
The point is that once you're doing that, and implementing communication
between all your separate owners (which map pretty precisely to a reasonable
definition of "processes")... you've just implemented another operating
system, not a unikernel.

------
PieSquared
In addition to the blog post, there's an interesting discussion on Github that
happened before the blog post was published: [https://github.com/Unikernel-
Systems/unikernel.org/pull/45](https://github.com/Unikernel-
Systems/unikernel.org/pull/45)

~~~
Danihan
Excellent discussion. I'm not knowledgeable enough in Linux internals to know
whether the ring0 versus ring3 criticism is warranted. Is it just a matter of
if/when an attacker achieves escalated privileges they will have far more
attack surface on ring0?

~~~
tscs37
There is quite a difference.

Ring 3 is userspace, you can't interact with hardware or the operating system
or anything not in Ring 3 directly.

Ring 0 is everything. There are no restrictions and nothing stops you from
writing "Ahahah You didn't say the magic word!" over your entire memory until
the CPU crashes.

Having root on a linux kernel is heavily restricted compared to this and still
runs in Ring 3 like all other userspace code.

As root, you still have to run the kernel. As Ring 0, you can replace the
kernel. Or run your own OS.

~~~
mato
Access to ring 0 on a traditional OS is indeed usually "game over".

In the case of a unikernel deployed on a hypervisor this is not the case,
since there is not much else in ring 0 that you wouldn't already have access
to from ring 3. Conceptually you can think of the hypervisor as "kernel space"
and anything inside the unikernel as "userspace".

There _are_ advantages to running the unikernel solely in ring 3 (eg.
immutable page tables) however this is not a requirement for security.

~~~
tscs37
I still see it as worse than a normal application being compromised.

When Ring 0 is compromised, there is no alert or anything to protect the app
from compromise. If there is an exploit, it's game over.

However, in Ring 3 and a normal kernel, you get various protections that allow
the kernel to recognize some attacks and shutdown the application immediately
or even shutdown the kernel.

This prevents a compromised app from running to some extend.

A unikernel cannot do this. If the app is compromised and I don't notice and
don't restart it...

Even worse, the attacker could use it as leverage to infect other unikernel
based instances of the app to gain some permanence against restarts by simply
reinfecting when an instance goes down.

The unikernel is not userspace, not even conceptually. The hpyervisor will not
shutdown the app unless it executes illegal instructions. The kernel will
shutdown misbehaving programs more easily.

~~~
mato
> A unikernel cannot do this. If the app is compromised and I don't notice and
> don't restart it...

I disagree. There's no reason such mitigations (not sure what exactly you're
referring to) can't be implemented by the monitor process (ukvm in the
Solo5/ukvm model).

I'd also argue that a _normal_ kernel does not do any integrity checks on the
code running in a user process, so the model is exactly the same.

> Even worse, the attacker could use it as leverage to infect other unikernel
> based instances of the app to gain some permanence against restarts by
> simply reinfecting when an instance goes down.

For that they'd need to break out of the virtual machine and into the
hypervisor / monitor. Which is by no means impossible, but with careful design
of unikernel-specific monitors can be much reduced. Of course, I'm by no means
suggesting you should back your unikernels with a monitor along the lines of
QEMU :-)

~~~
tscs37
1) You are in _Ring 0_. There is _no_ defense unless you reimplement a normal
Kernel to run a process in Ring 3 along with the monitoring process and
capabilities management... etc

2) No, the attacker is most likely there because of some bug in the app, once
in the network, it becomes harder to stop the attacker infecting other
instances.

3) Hypervisors are not perfect. There are known instances of people infecting
the host through the hypervisor.

~~~
mato
1) Virtualized Ring 0 != Ring 0. See section 24.6 "VM-execution control
fields" of the Intel SDM for details of the controls a hypervisor can use to
modify guest behaviour.

2) The same applies to any application, not just unikernels.

3) I completely agree.

~~~
tscs37
1) You are still on _a_ Ring 0. On a normal operating system, an exploited app
has a limited action range, depending on the system settings. A lot of
exploits simply do not work because the operating system kills the process. On
Ring 0, even virtualized, all these protections do not work. You have full
control within the VM and you can't have some process within the VM to check
this as it is equally vulnerable.

2) Yes but Unikernels do not provide special protection against this either.

~~~
mato
> On a normal operating system, an exploited app has a limited action range

Minor point, but this seems to be a bit lost in the discussion: Generally 1
unikernel == 1 VM (or, virtualization-backed sandbox, the use of "virtual
machine" brings too much baggage with it) == 1 application.

So, the attack scope for the class of attacks we're debating is equally
limited to a single application, just like on a normal operating system.

~~~
tscs37
Not quite.

When you write an exploit for a normal operating system application, you
can't, for example, just write your payload into data memory and start
executing it. You can't jump to the address of an array and have the CPU
execute it's contents.

On a unikernel this sort of thing becomes trivial since everything is Ring 0
and all protections can be trivially disabled.

You _can_ just write your payload into any arbitrary data field and your
exploit only needs to jump to it, even with address randomization this can be
exploited (ASLR and similar techniques do not prevent exploits, only make them
harder)

The exploiting just becomes a whole lot easier.

It's not even remotely more secure than Ring 3 code running on a kernel that
has strict capability enforcement.

~~~
mato
> On a unikernel this sort of thing becomes trivial since everything is Ring 0
> and all protections can be trivially disabled.

If the hypervisor sets the relevant VMCS control fields for the unikernel to
cause a VMEXIT on (for example) a load of CR3 and any EPT violations _and_
sets up the guest with a static set of read-only and executable (or in fact,
with EPT you could even do execute-only) pages then there is no way the
unikernel can disable these protections.

Having said that, I'm not arguing that running unikernels in Ring 0 is the
best approach for security, just that it's not impossibly insecure.

With ukvm we're also looking into running all of the unikernel in
(virtualized) Ring 3 with _nothing_ running in Ring 0. However, this needs
more experimentation since with x86 you can't (for example) easily handle
legitimate exceptions (e.g. divide by zero) from Ring 3.

------
msla
Unikernels are not that new. CMS running on VM has existed since the 1960s,
with CMS being the unikernel (actually, a unitasking OS about as complex as
MS-DOS) and VM being what's now called a hypervisor: Something which
multiplexes hardware, but provides no APIs, such that VM guests think they're
running alone on bare hardware.

(VM can even run VM as a guest, recursively, which is useful for developing
the newer version of VM on a machine other people are using for other work.)

Therefore, we can evaluate these claims by asking what we know about security
breaches on VM/CMS systems.

~~~
PhantomGremlin
_Something which multiplexes hardware, but provides no APIs, such that VM
guests think they 're running alone on bare hardware._

There is what amounts to an "API". The virtualized software thinks it's
talking directly to hardware, so the API is just an emulation of that
hardware. Since controlling hardware is almost invariably messier than doing
system calls, the API is actually more complex.

 _Therefore, we can evaluate these claims by asking what we know about
security breaches on VM /CMS systems._

Here's an HN post I wrote a few years ago, about VM exploits:
[https://news.ycombinator.com/item?id=9241807](https://news.ycombinator.com/item?id=9241807)

Plenty of exploits to be found, many of which were related to emulation of
"I/O channel programs", which are, essentially, System/370 I/O "hardware".

~~~
msla
> There is what amounts to an "API". The virtualized software thinks it's
> talking directly to hardware, so the API is just an emulation of that
> hardware. Since controlling hardware is almost invariably messier than doing
> system calls, the API is actually more complex.

Nobody said a hypervisor was completely trivial, but just to be clear, a pure
hypervisor wouldn't "emulate" any hardware except what was physically present
on the system. The line between "virtual machine" and "hypervisor" and
"emulator" are blurry enough as it is, and I'd like to be clear about what the
subject of _this_ little thread is.

> Here's an HN post I wrote a few years ago, about VM exploits:
> [https://news.ycombinator.com/item?id=9241807](https://news.ycombinator.com/item?id=9241807)

> Plenty of exploits to be found, many of which were related to emulation of
> "I/O channel programs", which are, essentially, System/370 I/O "hardware".

Very interesting. Thank you.

------
peterwwillis
_" Unikernels have no shells. Most attacks I’ve seen invoke /bin/sh to modify
the system they are attacking. Without a shell the attacker doesn’t have this
opportunity. This forces the attacker to use machine code to subvert the
system, decreasing the likelihood of succeeding with the attack."_

Timmy the software developer and his many years of forensic analysis have led
him to believe that you need a shell to root something. Literally the entire
page's takeaway about security is "It's hard to use, so it's secure!"

------
cyphar
One thing that I never understand when I read articles like this (
_especially_ this article) is that the "security improvements" that are
mentioned are entirely related to there being no userspace (you don't need a
shell or syscalls if you don't have a userspace).

But the whole point of userspace is to provide privilege separation between
the kernel and userspace. In unikernels everything is in the kernel, and you
can freely mutate in-kernel state without any segmentation violations. In
other words, of course there are no syscalls when there is no separation
between user code and the kernel ("no syscalls" is the description of a
unikernel). So, what is the tangible security benefit?

What I want to know is how do you protect against in-kernel ROP? Or hell, just
plain old-fashioned stack overflows? The ASLR mentioned is not really useful
because it's only on-recompile (Linux's ASLR is on-execution). The only
experience I've had with writing shell code was messing around with
[https://microcorruption.com/](https://microcorruption.com/) for a few
evenings, and even _I_ know that putting everything into the same address
space is just asking for trouble (of course you can mitigate it, but praising
the premise as a feat of security seems to be missing the point to me).

Maybe I'm just massively misinformed, but I simply don't see how someone can
proclaim that "unikernels are secure" by just re-stating the premise as the
justification for their security (and then following up with a bunch of
hypotheticals).

------
sethev
A unikernel is running a single process in a single address space. So yes, if
you compromise the app you compromise the whole system but the whole system is
the app.

~~~
im_down_w_otp
That's not entirely true in practice. I'm currently playing with rump kernels
deployed on top of seL4's hypervisor to give my platform the security posture
of a unikernel inside the security posture of seL4 VM isolation.

You could potentially compromise the rump kernel, but you still wouldn't be
able to break out of the VM's isolation context.

~~~
tscs37
The app is still compromised.

On top of that, you didn't get to reap the benefits of any of the protections
you get from a proper Kernel like Ring 3 execution, NX bits on pages, guard
pages on the stack, etc.

------
FungalRaincloud
I don't really like the argument that something is 'secure' because it is not
vulnerable in the same ways that an alternative is. I think this is why I like
talking about encryption so much. It's possible to mathematically prove the
security of encryption algorithms, and all that's really left to pick apart is
the implementation, politics and impact.

~~~
vertex-four
Ehh... you can often prove that X algorithm is not susceptible to A, B or C
attacks, but you cannot usually prove that the algorithm is "secure" in a
fundamental sense.

~~~
jacksnipe
[https://en.wikipedia.org/wiki/Provable_security](https://en.wikipedia.org/wiki/Provable_security)

You can prove that it's secure in that the _algorithm itself_ does not leak
information.

~~~
klodolph
With some exceptions, those proofs make assumptions about their primitives
like having block ciphers be "unpredictable permutations" or having hash
functions be "random oracles". These proofs also make assumptions that
information doesn't leak in other ways (like BEAST, heartbleed, timing
attacks, poor entropy sources, etc).

In other words, those proofs don't have as much real-world significance as
you'd like.

------
geofft
> _Unikernels have no shells. Most attacks I’ve seen invoke /bin/sh to modify
> the system they are attacking. Without a shell the attacker doesn’t have
> this opportunity. This forces the attacker to use machine code to subvert
> the system, decreasing the likelihood of succeeding with the attack._

This argument is completely incoherent.

~~~
tptacek
And, while this is a more minor rebuttal, it's still worth saying: _it 's
totally incorrect_. Modern exploits (for definitions of "modern" meaning
"written after 1999") do not care if you have a shell on your system.

The author has presumably confused the concept of a POC, which is an exploit
reduced and simplified for the consumption and understanding of laypeople,
with that of a real exploit.

~~~
mato
As one the early users[1] guilty of using the "there is no shell" argument for
unikernel security, I agree with what you say. I would rephrase the argument
as "there is no fork()/exec()", meaning that a unikernel cannot spawn a new
process.

A unikernel application which only executes native code[2], combined with a
hypervisor / hardware that enforces immutable page tables and NX, AFAICT
leaves ROP/JOP as the sole remaining attack vector for RCE. Further, each
deployment of the application should be done via a new build (or at least re-
link), which can employ the build-time ASLR Per mentions to mitigate ROP/JOP
attacks.

I'd be interested in your thoughts on what other relevant attack vectors I've
not thought of that would allow for a persistent compromise of a unikernel.
Feel free to discuss here or on the devel.unikernel.org forum thread[3].

[1] Page 4 in this whitepaper from 2015:
[https://wiki.xenproject.org/images/3/34/XenProject_Unikernel...](https://wiki.xenproject.org/images/3/34/XenProject_Unikernel_Whitepaper_2015_FINAL.pdf)

[2] Does not contain a JIT or interpreter able to "eval()" new code.

[3] [https://devel.unikernel.org/t/unikernels-are-secure-here-
is-...](https://devel.unikernel.org/t/unikernels-are-secure-here-is-why/258/2)

~~~
tptacek
What difference does it make if there's no fork/exec? Back in 1999 we had
MOSDEF and CORE IMPACT, both of which used staged loaders to boot up a
language runtime in a remote process after compromising it with a stack
overflow. In a broader sense this is stuff that viruses had been doing for
about 8 years prior to that.

Only executing native code is no defense at all. You're not even stopping
attackers from the '90s like that.

ROP is only a hardship until exploit code can find a way to allocate
executable memory or hook the program's own dynamic execution (note: this is
not necessarily a "JIT" or "eval") capabilities. ASLR only matters when
exploits can't find infoleaks.

Really, what you're describing here is the browser security model. When
staffed by the largest, best security teams in the world, the browser security
model almost works.

~~~
mato
> Back in 1999 we had MOSDEF and CORE IMPACT (...)

I'm not familiar with these. Googling "MOSDEF attack" suggests Massive Attack
songs and "CORE IMPACT" various products by Core Security, I presume you're
referring to neither? :-)

> Only executing native code is no defense at all. You're not even stopping
> attackers from the '90s like that.

> ROP is only a hardship until exploit code can find a way to allocate
> executable memory or hook the program's own dynamic execution (...)

Only executing native code _loaded at deployment time_ , i.e. presumably from
a trusted source. What I meant by "immutable page tables" is that after
loading the unikernel image the set of executable pages is fixed, and all of
those are read only. This is not something current unikernels do, but that's
more due to lack of development time rather than any inherent implementation
complexity.

If there is no way for the exploit code to ask the hypervisor for new
executable pages or overwrite existing ones then the amount of damage it can
do and its ability to persist in the running system is greatly reduced.

> Really, what you're describing here is the browser security model. When
> staffed by the largest, best security teams in the world, the browser
> security model almost works.

It's similar but not the same. The browser security model breaks down in a
large part due to exposing way too many APIs, most of which are too complex to
sensibly audit. Linux system calls have a similar problem, which is why you
have to hand-craft things like seccomp profiles to match your particular
application.

Unikernels (as used to implement network services) lend themselves extremely
well to running on top of a well defined API / sandbox boundary, designed with
security in mind. Again, we're not there yet, but the steps we need to explore
in this direction are fairly clear.

~~~
fulafel
MOSDEF: [https://www.blackhat.com/presentations/bh-federal-03/bh-
fed-...](https://www.blackhat.com/presentations/bh-federal-03/bh-
fed-03-aitel.pdf)

Core IMPACT: [http://seclists.org/pen-
test/2006/May/9](http://seclists.org/pen-test/2006/May/9)

------
notacoward
"No system calls"

Yeah, they're direct function calls now. How exactly is that more secure? The
author's right that many traditional exploit paths are gone, but only because
they've been replaced by _even easier_ ones.

~~~
robotresearcher
Because you don't know how to call the functions, as explained in the article.
To call a function, you need to know its address among other things. And you
don't, since the address was decided at random at build time (or even boot
time in some systems).

~~~
notacoward
There are other ways to find functions besides knowing their addresses a
priori.

~~~
robotresearcher
How is this done?

I think kernels try not to leak the address of system calls at run time, and
if they are scattered around in a 64bit address space they are tough to search
for. Educate me!

~~~
xorcist
I have no idea, but couldn't you use some part of the software you just
compromised that makes syscalls?

~~~
robotresearcher
There are no syscalls as the fine article explains.

~~~
robotresearcher
Ah, wait, I mis-read your comment and it's too late to edit mine. Yes, that
sounds plausible, and particularly if you have the source code, which you do
for many common servers.

------
floobyhoob
The real problem for unikernels is that they are effectively irrelevant until
the major clouds provide millisecond boot times along with appropriate pricing
models that charge for execution on a millisecond level basis.

Developers love to write code, but unless unikernel developers start speaking
up instead of writing code, the major clouds won't get on board and provide
the needed fast boot times plus pricing, which makes all this unikernel code
not a lot more than interesting personal / academic projects.

Questions of unikernel security are certainly academic if the cloud
infrastructure doesn't run them in the most effective manner.

~~~
weberc2
Why are millisecond bit times necessary? Linux doesn't boot in a
millisecond...

~~~
floobyhoob
Because you can then build single function unikernels that do one thing very
fast then disappear from RAM.

The point being that docker is actually a really clunky thing that is
reinventing the virtual server ecosystem within the OS which is pointless.

Serverless systems are better implemented as unikernels than docker images.

Unikernels make it possible to boot an entire OS in milliseconds, service an
inbound web request, then disappear.

~~~
corndoge
What's the use case for booting an entire OS to service a request?

~~~
hderms
when the OS is just some library functions statically compiled in and the
entire binary is a few megabytes that you can load directly into memory, why
not?

------
dreamdu5t
Hard to take claims of security seriously for untyped languages which are not
provably correct and lack a denotational semantics. Let's start by provably
not compiling buffer overflows and memory overreads considering those are the
vast majority of RCE and privilege escalation.

~~~
perbu
C++ is strongly typed. I believe there are frameworks that will give you
denotational semantics in C++.

It shouldn't surprise anyone that feature X is available in C++. But I
acknowledge there are tons of shotguns strewn around everywhere in C++ so you
can blow your feet off.

~~~
willtim
C++ is not "strongly typed" when compared to almost any other statically-typed
language, e.g. Ada, OCaml, Haskell or Rust. This is a big part of why it is so
insecure.

------
rdtsc
> There are two aspects of unikernel security. There are two aspects of
> unikernel security. One is the vector into the VM and the other is the
> vector from the VM into the hypervisor.

The "vector into the VM" might not be as obvious. For example, in a network
security contest in college I compromised the source repository of the server
to give my team an advantage and won. That was before git it was just a folder
on the server. Others argued it wasn't fair but the instructor sided with me
since that's a plausible scenario in real life.

There also tempest-like attacks for extracting private keys and such, so it's
there at also at least the 3rd vector - from VM to the hardware as well. And
forth from VM to the network (but I guess these can be subsumed in the "to the
hypervisor" case).

------
api
So now the hypervisor is ring0, the cloud provider is the OS, and the OS is
the app. IP is the IPC and the Internet is the IPC bus.

I suppose the hypervisor is more minimal and secure. Tenenbaum, thou art
avenged.

------
nkozyra
The intro video is somewhat confusing - it indicates that they're secure but
if that they're "harder to attack" and says if they are compromised they can
be restored. Also, he said "in the future, I believe unikernels will be more
or less unbreakable"

I think you could describe that as "more secure" or perhaps more generically
"safer" rather than "secure."

------
benmmurphy
don't unikernels run everything in ring0. if you run everything in ring0 you
can't claim not having system calls is a security feature :/

------
RRRA
And if you run a Linux kernel with a C app as one, for example, it's probably
possible to run a shellcode proxy in memory, even if you can't modify the app
code, you could ROP if a big enough buffer overflow is possible on the stack,
etc.?

------
munin
None of the claims in this have anything to do with the essence of security,
they all address the window-dressing of security.

What does it mean for something to be secure? As I see it, for something to be
secure, it means that every security invariant holds under all attacker
models.

Let's break this down. What's a security invariant, and what's an attacker
model?

A security invariant is a statement like "information may only be read by
principals authorized to do so" or something similar. The blog post talks
about "oh well every exploit I've seen pops a shell with /bin/sh and we don't
have /bin/sh so you can't hack it." This attacks the symptom and not the
disease. If the attacker is in a position to run /bin/sh you are already at a
disadvantage, the attacker was previously going to break your security
invariant by spawning a shell and then copying out your secrets. They could
instead just use their code execution to read the secrets directly, ala
heartbleed, if they are in the same address space.

An attacker model describes the attacker, their motivations/goals, and
capabilities. For example, what if the attacker wanted to take your unikernel
enabled app and repurpose it into an e-mail spam bot? Well, there isn't a
writeable FS and there isn't the ability to exec stuff, so the old model of
"copy some files up and run them" won't work. However, is there executable
memory in general? Can the application allocate existing executable memory? If
the application is, or involves, for example a modern JavaScript interpreter,
then it has to be able to do this in some capacity. So now the attacker
modifies their methods so that their goal can be achieved in the constraints
of this new system.

There is an argument you can make about sandboxing and principle of least
privilege, but that argument transcends unikernels really. Look at the
sandboxing and separation strategies used by programs like chrome, vsftpd, and
qmail. They (in conjunction with enforcement technologies like seccomp-bpf or
selinux) can make the same guarantees about the lack of system calls and least
privilege.

I'm pretty sure that the title of this post really should be "unikernels are
_obscure_ " because that's the layer of protection you're really getting here.

------
mtgx
> IncludeOS is a clean-slate unikernel written in C++ with performance and
> security in mind.

One of those things doesn't belong there. Guess which?

~~~
willtim
Yes it reads like satire. MirageOS, having been written in OCaml, would have a
better claim to being written with security in mind.

------
bogomipz
The article states:

>"Unikernels on the other hand don’t have system calls. They only have
function calls."

If my program is compiled against glibc functions which wrap actual system
calls how does my program work when there is no userland?

Is there a compiler that compiles my program to a unikernel target? Can
someone explain how this works?

------
kmicklas
"Secure" and yet they aren't even using a memory safe language such as Rust.

------
jeshwanth
Looks to be unikernel is just a RTOS, why the name unikernel then ? Whats the
difference with RTOS?

~~~
numbsafari
A unikernel could be designed as an RTOS, but not all RTOS are unikernels (in
fact, I'm not aware that _any_ are). Indeed, QNX, a RTOS, is not implemented
using a single address space, nor is your application linked against the
kernel and supporting libraries into a unikernel. While it's certainly
possible that you could implement an application/unikernel with real-time
guarantees, I'm not aware of a specific unikernel implementation that targets
that space specifically.

~~~
jeshwanth
Thanks or your kind reply, I use to find difficult to classify between RTOS
and unikernels technically.

------
eriknstr
> What we need is this:

> * packet interface for the network

> * a block interface for some storage

> * a serial port to output console data

Some applications need additional devices, such as for example hardware RNG,
atomic clocks and/or GPGPU.

------
kensai
Why am I reading this "Unicorns"? :D

------
rwmj
It's secure if and only if there's a formal proof.

~~~
adrianN
"Secure" sounds like a binary attribute but it's actually not. A formal proof
doesn't save you from errors in the specification. At some point you need
trust, the amount of trust needed is inversely proportional to the security.

~~~
dreamdu5t
Without a formal proof there is no measure of correctness at all.

~~~
adrianN
Lots of passing tests mean nothing to you?

~~~
monocasa
When an exploit only needs one edge case not handled right? No, lots of unit
tests means nothing. Maybe less than nothing due to the false sense of
security they seem to give you.

~~~
adrianN
So you trust a software that has had zero testing equally to a software like
sqlite that has extensive testing?

------
futurix
Generalisations are generalising.

------
m3kw9
Claiming something is secure is more like claiming an over unity perpetual
machine

