mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-20 13:06:33 +00:00
Rename jinux to asterinas in documentation and code
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
2b248dc326
commit
99f6765ced
@ -14,7 +14,7 @@
|
||||
|
||||
# Introduction
|
||||
|
||||
This document describes Jinux, a secure, fast, and modern OS written in Rust.
|
||||
This document describes Asterinas, a secure, fast, and modern OS written in Rust.
|
||||
|
||||
As the project is a work in progress, this document is by no means complete.
|
||||
Despite the incompleteness, this evolving document serves several important purposes:
|
||||
@ -50,7 +50,7 @@ OSes, e.g., [Kerla](https://github.com/nuta/kerla),
|
||||
and [zCore](https://github.com/rcore-os/zCore). Despite their varying degrees of
|
||||
success, none of them are general-purpose, industrial-strength OSes that are or
|
||||
will ever be competitive with Linux. Eventually, a winner will emerge out of this
|
||||
market of Rust OSes, and Jinux is our bet for this competition.
|
||||
market of Rust OSes, and Asterinas is our bet for this competition.
|
||||
|
||||
Second, Rust OSes are a perfect fit for
|
||||
[Trusted Execution Environments (TEEs)](https://en.wikipedia.org/wiki/Trusted_execution_environment).
|
||||
@ -79,24 +79,24 @@ relational databases:
|
||||
[Oracle and IBM are losing ground as Chinese vendors catch up with their US counterparts](https://www.theregister.com/2022/07/06/international_database_vendors_are_losing/).
|
||||
Can such success stories be repeated in the field of OSes? I think so.
|
||||
There are some China's home-grown OSes like [openKylin](https://www.openkylin.top/index.php?lang=en), but all of them are based on Linux and lack a self-developed
|
||||
OS _kernel_. The long-term goal of Jinux is to fill this key missing core of the home-grown OSes.
|
||||
OS _kernel_. The long-term goal of Asterinas is to fill this key missing core of the home-grown OSes.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
Here is an overview of the architecture of Jinux.
|
||||
Here is an overview of the architecture of Asterinas.
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
**1. Security by design.** Security is our top priority in the design of Jinux. As such, we adopt the widely acknowledged security best practice of [least privilege principle](https://en.wikipedia.org/wiki/Principle_of_least_privilege) and enforce it in a fashion that leverages the full strengths of Rust. To do so, we partition Jinux into two halves: a _privileged_ OS core and _unprivileged_ OS components. All OS components are written entirely in _safe_ Rust and only the privileged OS core
|
||||
**1. Security by design.** Security is our top priority in the design of Asterinas. As such, we adopt the widely acknowledged security best practice of [least privilege principle](https://en.wikipedia.org/wiki/Principle_of_least_privilege) and enforce it in a fashion that leverages the full strengths of Rust. To do so, we partition Asterinas into two halves: a _privileged_ OS core and _unprivileged_ OS components. All OS components are written entirely in _safe_ Rust and only the privileged OS core
|
||||
is allowed to have _unsafe_ Rust code. Furthermore, we propose the idea of _everything-is-a-capability_, which elevates the status of [capabilities](https://en.wikipedia.org/wiki/Capability-based_security) to the level of a ubiquitous security primitive used throughout the OS. We make novel use of Rust's advanced features (e.g., [type-level programming](https://willcrichton.net/notes/type-level-programming/)) to make capabilities more accessible and efficient. The net result is improved security and uncompromised performance.
|
||||
|
||||
**2. Trustworthy OS-level virtualization.** OS-level virtualization mechanisms (like Linux's cgroups and namespaces) enable containers, a more lightweight and arguably more popular alternative to virtual machines (VMs). But there is one problem with containers: they are not as secure as VMs (see [StackExchange](https://security.stackexchange.com/questions/169642/what-makes-docker-more-secure-than-vms-or-bare-metal), [LWN](https://lwn.net/Articles/796700/), and [AWS](https://docs.aws.amazon.com/AmazonECS/latest/bestpracticesguide/security-tasks-containers.html)). There is a real risk that malicious containers may exploit privilege escalation bugs in the OS kernel to attack the host. [A study](https://dl.acm.org/doi/10.1145/3274694.3274720) found that 11 out of 88 kernel exploits are effective in breaking the container sandbox. The seemingly inherent insecurity of OS kernels leads to a new breed of container implementations (e.g., [Kata](https://katacontainers.io/) and [gVisor](https://gvisor.dev/)) that are based on VMs, instead of kernels, for isolation and sandboxing. We argue that this unfortunate retreat from OS-level virtualization to VM-based one is unwarranted---if the OS kernels are secure enough. And this is exactly what we plan to achieve with Jinux. We aim to provide a trustworthy OS-level virtualization mechanism on Jinux.
|
||||
**2. Trustworthy OS-level virtualization.** OS-level virtualization mechanisms (like Linux's cgroups and namespaces) enable containers, a more lightweight and arguably more popular alternative to virtual machines (VMs). But there is one problem with containers: they are not as secure as VMs (see [StackExchange](https://security.stackexchange.com/questions/169642/what-makes-docker-more-secure-than-vms-or-bare-metal), [LWN](https://lwn.net/Articles/796700/), and [AWS](https://docs.aws.amazon.com/AmazonECS/latest/bestpracticesguide/security-tasks-containers.html)). There is a real risk that malicious containers may exploit privilege escalation bugs in the OS kernel to attack the host. [A study](https://dl.acm.org/doi/10.1145/3274694.3274720) found that 11 out of 88 kernel exploits are effective in breaking the container sandbox. The seemingly inherent insecurity of OS kernels leads to a new breed of container implementations (e.g., [Kata](https://katacontainers.io/) and [gVisor](https://gvisor.dev/)) that are based on VMs, instead of kernels, for isolation and sandboxing. We argue that this unfortunate retreat from OS-level virtualization to VM-based one is unwarranted---if the OS kernels are secure enough. And this is exactly what we plan to achieve with Asterinas. We aim to provide a trustworthy OS-level virtualization mechanism on Asterinas.
|
||||
|
||||
**3. Fast user-mode development.** Traditional OS kernels like Linux are hard to develop, test, and debug. Kernel development involves countless rounds of programming, failing, and rebooting on bare-metal or virtual machines. This way of life is unproductive and painful. Such a pain point is also recognized and partially addressed by [research work](https://www.usenix.org/conference/fast21/presentation/miller), but we think we can do more. In this spirit, we design the OS core to provide high-level APIs that are largely independent of the underlying hardware and implement it with two targets: one target is as part of a regular OS in kernel space and the other is as a library OS in user space. This way, all the OS components of Jinux, which are stacked above the OS core, can be developed, tested, and debugged in user space, which is more friendly to developers than kernel space.
|
||||
**3. Fast user-mode development.** Traditional OS kernels like Linux are hard to develop, test, and debug. Kernel development involves countless rounds of programming, failing, and rebooting on bare-metal or virtual machines. This way of life is unproductive and painful. Such a pain point is also recognized and partially addressed by [research work](https://www.usenix.org/conference/fast21/presentation/miller), but we think we can do more. In this spirit, we design the OS core to provide high-level APIs that are largely independent of the underlying hardware and implement it with two targets: one target is as part of a regular OS in kernel space and the other is as a library OS in user space. This way, all the OS components of Asterinas, which are stacked above the OS core, can be developed, tested, and debugged in user space, which is more friendly to developers than kernel space.
|
||||
|
||||
**4. High-fidelity Linux ABI.** An OS without usable applications is useless. So we believe it is important for Jinux to fit in an established and thriving ecosystem of software, such as the one around Linux. This is why we conclude that Jinux should aim at implementing high-fidelity Linux ABI, including the system calls, the proc file system, etc.
|
||||
**4. High-fidelity Linux ABI.** An OS without usable applications is useless. So we believe it is important for Asterinas to fit in an established and thriving ecosystem of software, such as the one around Linux. This is why we conclude that Asterinas should aim at implementing high-fidelity Linux ABI, including the system calls, the proc file system, etc.
|
||||
|
||||
**5. TEEs as top-tier targets.** (Todo)
|
||||
|
||||
|
@ -20,12 +20,12 @@ capabilities in a limited fashion, mostly as a means to limit the access from
|
||||
external users (e.g., via syscall), rather than a mechanism to enforce advanced
|
||||
security policies internally (e.g., module-level isolation).
|
||||
|
||||
So we ask this question: is it possible to use capabilities as a _ubitiquous_ security primitive throughout Jinux to enhance the security and robustness of the
|
||||
So we ask this question: is it possible to use capabilities as a _ubitiquous_ security primitive throughout Asterinas to enhance the security and robustness of the
|
||||
OS? Specifically, we propose a new principle called "_everything is a capability_".
|
||||
Here, "everything" refers to any type of OS resource, internal or external alike.
|
||||
In traditional OSes, treating everything as a capability is unrewarding
|
||||
because (1) capabilities themselves are unreliable due to memory safety problems
|
||||
, and (2) capabilities are no free lunch as they incur memory and CPU overheads. But these arguments may no longer stand in a well-designed Rust OS like Jinux.
|
||||
, and (2) capabilities are no free lunch as they incur memory and CPU overheads. But these arguments may no longer stand in a well-designed Rust OS like Asterinas.
|
||||
Because the odds of memory safety bugs are minimized and
|
||||
advanced Rust features like type-level programming allow us to implement
|
||||
capabilities as a zero-cost abstraction.
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Zero-Cost Capabilities
|
||||
|
||||
To strengthen the security of Jinux, we aim to implement all kinds of OS resources
|
||||
To strengthen the security of Asterinas, we aim to implement all kinds of OS resources
|
||||
as capabilities. As the capabilities are going to be used throughout the OS,
|
||||
it is highly desirable to minimize their costs. For this purpose,
|
||||
we want to implement capabilities as a _zero-cost abstraction_.
|
||||
|
@ -1,15 +1,15 @@
|
||||
# Privilege Separation
|
||||
|
||||
One fundamental design goal of Jinux is to support _privilege separation_, i.e., the separation between the privileged OS core and the unprivileged OS components. The privileged portion is allowed to use `unsafe` keyword to carry out dangerous tasks like accessing CPU registers, manipulating stack frames, and doing MMIO or PIO. In contrast, the unprivileged portion, which forms the majority of the OS, must be free from `unsafe` code. With privilege separation, the memory safety of Jinux can be boiled down to the correctness of the privileged OS core, regardless of the correctness of the unprivileged OS components, thus reducing the size of TCB significantly.
|
||||
One fundamental design goal of Asterinas is to support _privilege separation_, i.e., the separation between the privileged OS core and the unprivileged OS components. The privileged portion is allowed to use `unsafe` keyword to carry out dangerous tasks like accessing CPU registers, manipulating stack frames, and doing MMIO or PIO. In contrast, the unprivileged portion, which forms the majority of the OS, must be free from `unsafe` code. With privilege separation, the memory safety of Asterinas can be boiled down to the correctness of the privileged OS core, regardless of the correctness of the unprivileged OS components, thus reducing the size of TCB significantly.
|
||||
|
||||
To put privilege separation into perspective, let's compare the architectures
|
||||
of the monolithic kernels, microkernels, and Jinux.
|
||||
of the monolithic kernels, microkernels, and Asterinas.
|
||||
|
||||

|
||||
|
||||
The diagram above highlights the characteristics of different OS architectures
|
||||
in terms of communication overheads and the TCB for memory safety.
|
||||
Thanks to privilege separation, Jinux promises the benefit of being _as safe as a microkernel and as fast as a monolithic kernel_.
|
||||
Thanks to privilege separation, Asterinas promises the benefit of being _as safe as a microkernel and as fast as a monolithic kernel_.
|
||||
|
||||
Privilege separation is an interesting research problem, prompting us to
|
||||
answer a series of technical questions.
|
||||
|
@ -22,7 +22,7 @@ Here are some of the elements in PCI-based Virtio devices that may involve `unsa
|
||||
### Privileged part
|
||||
|
||||
```rust
|
||||
// file: jinux-core-libs/pci-io-port/lib.rs
|
||||
// file: aster-core-libs/pci-io-port/lib.rs
|
||||
use x86::IoPort;
|
||||
|
||||
/// The I/O port to write an address in the PCI
|
||||
@ -49,7 +49,7 @@ pub const PCI_DATA_PORT: IoPort<u32> = {
|
||||
### Unprivileged part
|
||||
|
||||
```rust
|
||||
// file: jinux-comps/pci/lib.rs
|
||||
// file: aster-comps/pci/lib.rs
|
||||
use pci_io_port::{PCI_ADDR_PORT, PCI_DATA_PORT};
|
||||
|
||||
/// The PCI configuration space, which enables the discovery,
|
||||
@ -128,7 +128,7 @@ pub struct PciCapabilities {
|
||||
Most code of Virtio drivers can be unprivileged thanks to the abstractions of `VmPager` and `VmCell` provided by the OS core.
|
||||
|
||||
```rust
|
||||
// file: jinux-comp-libs/virtio/transport.rs
|
||||
// file: aster-comp-libs/virtio/transport.rs
|
||||
|
||||
/// The transport layer for configuring a Virtio device.
|
||||
pub struct VirtioTransport {
|
||||
|
@ -138,7 +138,7 @@ impl<T, P: Write> UserPtr<T, P> {
|
||||
}
|
||||
```
|
||||
|
||||
The examples reveal two important considerations in designing Jinux:
|
||||
The examples reveal two important considerations in designing Asterinas:
|
||||
1. Exposing _truly_ safe APIs. The privileged OS core must expose _truly safe_ APIs: however buggy or silly the unprivileged OS components may be written, they must _not_ cause undefined behaviors.
|
||||
2. Handling _arbitrary_ pointers safely. The safe API of the OS core must provide a safe way to deal with arbitrary pointers.
|
||||
|
||||
@ -146,15 +146,15 @@ With the two points in mind, let's get back to our main goal of privilege separa
|
||||
|
||||
## Code organization with privilege separation
|
||||
|
||||
Our first step is to separate privileged and unprivileged code in the codebase of Jinux. For our purpose of demonstrating a syscall handling framework, a minimal codebase may look like the following.
|
||||
Our first step is to separate privileged and unprivileged code in the codebase of Asterinas. For our purpose of demonstrating a syscall handling framework, a minimal codebase may look like the following.
|
||||
|
||||
```text
|
||||
.
|
||||
├── jinux
|
||||
├── asterinas
|
||||
│ ├── src
|
||||
│ │ └── main.rs
|
||||
│ └── Cargo.toml
|
||||
├── jinux-core
|
||||
├── aster-core
|
||||
│ ├── src
|
||||
│ │ ├── lib.rs
|
||||
│ │ ├── syscall_handler.rs
|
||||
@ -162,7 +162,7 @@ Our first step is to separate privileged and unprivileged code in the codebase o
|
||||
│ │ ├── vmo.rs
|
||||
│ │ └── vmar.rs
|
||||
│ └── Cargo.toml
|
||||
├── jinux-core-libs
|
||||
├── aster-core-libs
|
||||
│ ├── linux-abi-types
|
||||
│ │ ├── src
|
||||
│ │ │ └── lib.rs
|
||||
@ -171,34 +171,34 @@ Our first step is to separate privileged and unprivileged code in the codebase o
|
||||
│ ├── src
|
||||
│ │ └── lib.rs
|
||||
│ └── Cargo.toml
|
||||
├── jinux-comps
|
||||
├── aster-comps
|
||||
│ └── linux-syscall
|
||||
│ ├── src
|
||||
│ │ └── lib.rs
|
||||
│ └── Cargo.toml
|
||||
└── jinux-comp-libs
|
||||
└── aster-comp-libs
|
||||
└── linux-abi
|
||||
├── src
|
||||
│ └── lib.rs
|
||||
└── Cargo.toml
|
||||
```
|
||||
|
||||
The ultimate build target of the codebase is the `jinux` crate, which is an OS kernel that consists of a privileged OS core (crate `jinux-core`) and multiple OS components (the crates under `jinux-comps/`).
|
||||
The ultimate build target of the codebase is the `asterinas` crate, which is an OS kernel that consists of a privileged OS core (crate `aster-core`) and multiple OS components (the crates under `aster-comps/`).
|
||||
|
||||
For the sake of privilege separation, only crate `jinux` and `jinux-core` along with the crates under `jinux-core-libs` are allowed to use the `unsafe` keyword. To the contrary, the crates under `jinux-comps/` along with their dependent crates under `jinux-comp-libs/` are not allowed to use `unsafe` directly; they may only borrow the superpower of `unsafe` by using the safe API exposed by `jinux-core` or the crates under `jinux-core-libs`. To summarize, the memory safety of the OS only relies on a small and well-defined TCB that constitutes the `jinux` and `jinux-core` crate plus the crates under `jinux-core-libs/`.
|
||||
For the sake of privilege separation, only crate `asterinas` and `aster-core` along with the crates under `aster-core-libs` are allowed to use the `unsafe` keyword. To the contrary, the crates under `aster-comps/` along with their dependent crates under `aster-comp-libs/` are not allowed to use `unsafe` directly; they may only borrow the superpower of `unsafe` by using the safe API exposed by `aster-core` or the crates under `aster-core-libs`. To summarize, the memory safety of the OS only relies on a small and well-defined TCB that constitutes the `asterinas` and `aster-core` crate plus the crates under `aster-core-libs/`.
|
||||
|
||||
Under this setting, all implementation of system calls goes to the `linux-syscall` crate. We are about to show that the _safe_ API provided by `jinux-core` is powerful enough to enable the _safe_ implementation of `linux-syscall`.
|
||||
Under this setting, all implementation of system calls goes to the `linux-syscall` crate. We are about to show that the _safe_ API provided by `aster-core` is powerful enough to enable the _safe_ implementation of `linux-syscall`.
|
||||
|
||||
## Crate `jinux-core`
|
||||
## Crate `aster-core`
|
||||
|
||||
For our purposes here, the two most relevant APIs provided by `jinux-core` is the abstraction for syscall handlers and virtual memory (VM).
|
||||
For our purposes here, the two most relevant APIs provided by `aster-core` is the abstraction for syscall handlers and virtual memory (VM).
|
||||
|
||||
### Syscall handlers
|
||||
|
||||
The `SyscallHandler` abstraction enables the OS core to hide the low-level, architectural-dependent aspects of syscall handling workflow (e.g., user-kernel switching and CPU register manipulation) and allow the unprivileged OS components to implement system calls.
|
||||
|
||||
```rust
|
||||
// file: jinux-core/src/syscall_handler.rs
|
||||
// file: aster-core/src/syscall_handler.rs
|
||||
|
||||
pub trait SyscallHandler {
|
||||
fn handle_syscall(&self, ctx: &mut SyscallContext);
|
||||
@ -243,8 +243,8 @@ an important concept that we will elaborate on later. Basically, they are capabi
|
||||
Here we demonstrate how to leverage the APIs of `ksos-core` to implement system calls with safe Rust code in crate `linux-syscall`.
|
||||
|
||||
```rust
|
||||
// file: jinux-comps/linux-syscall/src/lib.rs
|
||||
use jinux_core::{SyscallContext, SyscallHandler, Vmar};
|
||||
// file: aster-comps/linux-syscall/src/lib.rs
|
||||
use aster_core::{SyscallContext, SyscallHandler, Vmar};
|
||||
use linux_abi::{SyscallNum::*, UserPtr, RawFd, RawTimeVal, RawTimeZone};
|
||||
|
||||
pub struct SampleHandler;
|
||||
@ -315,7 +315,7 @@ impl SampleHandler {
|
||||
This crate defines a marker trait `Pod`, which represents plain-old data.
|
||||
|
||||
```rust
|
||||
/// file: jinux-core-libs/pod/src/lib.rs
|
||||
/// file: aster-core-libs/pod/src/lib.rs
|
||||
|
||||
/// A marker trait for plain old data (POD).
|
||||
///
|
||||
@ -388,7 +388,7 @@ unsafe impl<T: Pod, const N> [T; N] for Pod {}
|
||||
## Crate `linux-abi-type`
|
||||
|
||||
```rust
|
||||
// file: jinux-core-libs/linux-abi-types
|
||||
// file: aster-core-libs/linux-abi-types
|
||||
use pod::Pod;
|
||||
|
||||
pub type RawFd = i32;
|
||||
@ -404,7 +404,7 @@ unsafe impl Pod for RawTimeVal {}
|
||||
## Crate `linux-abi`
|
||||
|
||||
```rust
|
||||
// file: jinux-comp-libs/linux-abi
|
||||
// file: aster-comp-libs/linux-abi
|
||||
pub use linux_abi_types::*;
|
||||
|
||||
pub enum SyscallNum {
|
||||
|
Reference in New Issue
Block a user