Expand description
§Memory State of a process
In the project 1, you implemented the file state management for a process. An equally important state of a process is memory state. This memory state involves managing virtual memory regions, tracking memory allocations, and implementing memory deallocation when memory is no longer needed. The operating system must track all active mappings per process, enforce correct access permissions, and ensure proper cleanup when memory is unmapped.
§Memory in KeOS
The state of a process’s memory is represented by the MmStruct
structure, similiar to the Linux kernel’s struct mm_struct. Each process
maintains an MmStruct instance, which tracks the memory mapping state
for a process. This state plays a central role for serving a memory mapping
system calls: mmap and munmap.
Memory mapping (mmap) allows processes to allocate, share, or access
memory in a flexible way. It is commonly used for:
- Allocating memory dynamically without relying on heap or stack growth.
- Mapping files into memory for fast access.
- Sharing memory between processes.
The mmap system call establishes a mapping between a process’s virtual
address space and either physical memory or a file. These memory mappings
are recorded within the page table, similar to how regular memory pages
are managed. However, unlike normal heap allocations, mmap-based
allocations allow more control over page protection, mapping policies, and
address alignment. When a process accesses an address within the mapped
region, a page fault occurs, triggering the operating system to allocate
and map the corresponding physical pages.
The MmStruct contains the two key components:
- Page Table: Tracks mappings between virtual and physical addresses.
- Pager: Defines the policy for memory mapping. and unmapping.`
§Validating User Input
One of the important aspects of managing memory safely is ensuring that user input, such as memory addresses provided by system calls, is validated correctly. The kernel must never crash due to user input.
Many system calls, like read and write, rely on user-supplied memory
addresses—typically as buffer pointers. These addresses need to be carefully
validated before they can be used to ensure the integrity and stability of
the system.
Without proper validation, several serious problems may arise:
- Unauthorized access to kernel memory: If the user is allowed to access kernel memory, this can lead to privilege escalation vulnerabilities, potentially giving the user more control than intended.
- Dereferencing invalid pointers: Accessing uninitialized or incorrectly mapped memory can result in segmentation faults or undefined behavior, leading to crashes or unexpected outcomes.
- Memory corruption: Improper handling of memory can result in corrupting the system’s memory state, which can affect other processes, crash the kernel, or destabilize the entire system.
MmStruct mitigate these risks with the MmStruct::access_ok method,
which ensures that the memory addresses provided by system calls are valid
and safe before being used. This validation mechanism will
prevent dangerous operations by checking if memory access is allowed, based
on the current process’s memory layout and protection policies.
By incorporating proper validation, MmStruct::access_ok ensures that
invalid memory accesses are handled gracefully, returning appropriate
errors rather than causing kernel panics or undefined behavior. This
validation mechanism plays a crucial role in maintaining system integrity
and protecting the kernel from potential vulnerabilities.
§Pager
The actual behavior of MmStruct lies in the Pager trait.
When a user program invokes those system calls, the MmStruct parses the
arguements from the SyscallAbi and forwarded them to an implementation
of the Pager traits, which provides the core interface for handling
memory mappings. Similarly, the core implementation to validate memory also
lies on the Pager::access_ok.
§Implementation Requirements
You need to implement the followings:
After implementing them, move on to the next section to implement
paging policy, called EagerPager.