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.
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.
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.
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 :-)
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.
2) The same applies to any application, not just unikernels.
3) I completely agree.
2) Yes but Unikernels do not provide special protection against this either.
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.
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.
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.