# Security ## Reporting Since Gila is new and not used in any critical settings, vulnerabilities may be filed as regular issues for the time being. Please ensure to specify that the issue is a security issue when submitting. ## Foreward Part of what inspires my design philosophy for Gila is the idea of creating a new, fast, and safe kernel with security as a central focus. Much of today's operating system security discourse comes down to "Sure, you can harden this, this, and this. But *(insert OS)*'s security model is deeply flawed." This isn't a dig at any one OS- it applies to all of them. Kernels such as Linux, Mach, and NT were built long before today's most salient concepts in computing security were established. Great work is being done on improving what we already have, but it's counterintuitive to try to establish a secure system on a flawed foundation. Gila aims to start fresh, using modern theories and models, all in a memory safe language that lends itself well to formal verification. ## Goals - Distrustful by default - Small, simple, and transparent - Performant - Capability based - Highly isolated ## Gila's security model ### Microkernel architecture Gila is a microkernel. Only the most important functionality runs at Ring 0 (Protected Mode) to reduce attack surface. This functionality includes: - Modifying and reading kernel configurations - Process creation and destruction - Scheduling - Memory allocation and management - Inter-process communication - Minimal IO drivers, only for debugging Unprivileged user processes perform complex functionality by interacting with similarly unprivileged server processes via inter-process communication. Servers can perform many different tasks, such as: - PCI(e) - ACPI - AHCI/SATA - USB - Ethernet - TCP/IP - Security policy - Filesystems - Logins - Graphics - Managing resources Servers do one thing each, and one thing well. If a server needs to do a lot of the same thing, it should fork into several processes, so inter-process isolation can improve security. For example, if there are multiple of the same device in the system, the driver server should fork for each instance. This ensures that any one server can crash or be compromised without crashing or compromising all the others. Another scenario might involve running separate login server processes for every single user on the system. Running all these servers in one process introduces a serious security risk, as any compromise or failure of the login server could result in security failures, resource exhaustion, denial of service, or other undesirable events, affecting all other users on the system. ### Realms A complete OS using the Gila microkernel will consist of four "realms". Each realm depends on the realm preceeding it. - Kernel Realm: The kernel itself, providing MMIO pages to the Driver Realm - Driver Realm: Driver processes supplying interfaces to the Service Realm - Service Realm: System services, supplying services like filesystems to the User Realm - User realm: User services/apps, running at the least privileged level Typically, for a secure deployment of an OS designed for a focused purpose, one has no real need to dynamically modify the Service Realm, Driver Realm, or Kernel Realm. So to simplify the deployment, the Driver and Service realms can be contained in the kernel's initramfs. For embedded use, or for virtual appliances, the User Realm can additionally be embedded in the initramfs. This eliminates the need for verifying or decrypting a hard disk, or loading information from the network. Of course, volatile information can still be stored on a hard drive, but the mission critical pieces of code can be stored in a read-only format until the system needs to be updated. Furthermore, the signatures of the kernel and any kernel modules can be calculated and stored in the Limine config file, whose hash can be embedded in the bootloader itself for use with Secure Boot. This quickly establishes hardware-based root-of-trust for the kernel and all realms stored in the initramfs. ### Namespaces Namespaces will be a critical part of how process isolation works. Details are still TBD, but I want each process to start in its own empty namespace, unless the parent process specifies that the child should share the parent's namespace. As device drivers and protocol drivers are simply processes, and subject to the same namespace rules as any other process, the kernel can enforce access to any kind of function or resource for any process arbitrarily. The same could eventually go for virtual machines. Namespaces are a way by which the resources available to a process are isolated and controlled. Mainly, this affects inter-process communication (IPC) as it's the primary method processes will use to do useful things, but it will also affect shared memory regions. A process cannot establish IPC unless it is part of some namespace the target process is also part of. ### Capability based MAC Gila has no concept of ambient authority. Resource access is not governed based on any inherent privilege level of the accessing process- rather, processes must possess capabilities specific to that resource. A process cannot defer a resource access to a process which already has the capability, it must *copy* or *transfer* its own capability to that resource, to the process which will access it. Namespaces will be enforced using capabilities, where a process holds a capability object representing the namespace it is in, and the rights it has within that namespace. By default, processes have no such capabilities, but a parent process can choose to copy one of its own and delegate it to the child process. Details are still a work in progress.