Add the rest of university notes

This commit is contained in:
John Gatward committed 2026-10-04 14:02:35 +01:00
1 parent c1b84c7f7d
commit d0f27f276b
366 files changed
+9844 -110

No files matched your search

@@ -0,0 +1,186 @@
# Reference Monitors
The reference monitor is an abstract concept
> An access control concept that refers to an abstract machine that mediates all access to objects by subjects
- Must be tamper proof
- Must *always be invoked* when access to an object is required
- Must be small enough to be verifiable / subject to analysis to ensure correctness
##### Placement
- Can be placed anywhere within the system
- Hardware - dedicated registers for defining privileges
- Operating system kernel - virtual machine hyper-visor
- Operating system - Windows security reference monitor
- Services layer - `JVM`, `.NET`
- Application layer - Firewalls
Reference monitors could be placed in a variety of locations relative to the program being run
![1645471173.png](img/1645471173.png)
The last example where the program contains its own reference monitor, as found in Windows XP, is a terrible idea - it leaves permissions down to the developer.
###### Lower is better
- Using a reference monitor or other security features at a lower level means:
- We can **assure** a higher degree of security
- Usually **simple structures** to implement
- Reduced performance **overheads**
- Has to be extremely quick as many calls will be made
- Fewer layer below attack possibilities
- However
- Access control decisions are far removed from applications
#### OS Integrity
- The operating system
- Arbitrates access requests
- Is itself a resource that must be accessed
- This is a conflict, we want to use the OS but not mess with it
> Users must not be able to modify the operating system
- Modes of operation
- Defines which actions are permitted in which mode e.g. system calls, machine instructions, I/O
- Controlled Invocation
- Allows us to execute privileged instructions safely, before returning to user code
We must distinguish computations done on behalf of:
- The OS
- The user
A status flag within the CPU allows the OS to operate in different modes
![1645471731.png](img/1645471731.png)
In practice, Windows and Unix only use Ring 0&3 to save on overhead
### Controlled Invocation
- Many functions are helf at kernel level, but are quite reasonably called from within user level code
- Network and File IO
- Memory allocation
- Halting the CPU (at shutdown only)
- We need a mechanism to transfer safely between kernel mode (ring 0) and user mode (ring 3)
> We don’t actually perform privileged operations, we asking the operating system to perform them for us - The operating system can refuse to do it
##### Interrupts
- Exceptions or Interrupts
- In many ways is the hardware equivalent to a software exception - not always bad
- Handled by an interrupt handler which resolves the issue and returns to the original code
Processing an Interrupt
- Given an interrupt, the CPU will switch execution to location given in an interrupt descriptor table
![1645472211.png](img/1645472211.png)
#### Descriptors and Selectors
- Descriptors hold information on crucial system objects like kernel structure locations
- Descriptors are held in descriptor tables
- Contain a Descriptor Privilege Level (DPL)
- Descriptors are indexed by selectors
- Loaded when required (jump calls)
- The CPU protects the kernel by checking the Current Privilege Level (CPL) when a Selector is loaded
##### Interrupt Gates
- The code segment (CS) register in x86 CPUs has 2-bits reserved for the Current Privilege Level (CPL)
- Descriptors that have a privilege level higher than where they point are called gates
- Since these descriptors are created by the kernel, they offer a secure means of entry into ring 0
![1645472444.png](img/1645472444.png)
###### Modern Kernels
- Intel introduced the `sysenter` and `sysexit` operations with the Pentium II
- performs with much less overhead
![1645472755.png](img/1645472755.png)
We got immediately in to ring 0
However where we go next is dictated by the `sysenter` pointer, users cannot write to `sysenter`
#### Patching the Kernel
- If you can run custom PL 0 code, you can insert your own handler - **Rootkit**
![1645473063.png](img/1645473063.png)
## Memory Protection
- A process is a program being executed currently
- Important unit of control
- Exists in its own address space
- Communicates with other processes via the OS
- Separation for security
- A thread is a strand of execution within a process
- Share a common address space
- Segmentation - divides data into logical units
- Good for security
- Challenging memory management
- Not used much in modern OSs
- Modern OSs only have two segments, one for user space, the other for kernel space
- Paging - divides memory into pages of equal size
- Efficient memory management
- Less good for access control
- Extremely common in modern OSs
##### Page Tables
- All processes see an individual linear address space
- Page tables map from a linear address space to the physical address space
![1645473936.png](img/1645473936.png)
###### Meltdown
- In most operating systems, the entire kernel is stored in the upper address space
- Pages in this area are flagged as supervisor, and cannot be access outside ring 0
- Meltdown is an exploit that allows us to read this privileged memory
- We do this using a *side-channel*
![1645474135.png](img/1645474135.png)
- In Intel CPUs, it’s common to speculatively evaluate code prior reaching it
- E.g. conditionals
- **Significant** speed up
- No harm done, changes are just rolled back
- But the **cache isn’t rolled back**
- This is called side-channelling and cache timing
```java
...
w = illegal_instruction;
x = memory[data * 4096];
...
```
- When the CPU runs this code, it will take a significant amount of time to determine that `w` shouldn’t be run, however by that point the speculative code has run `memory[data*4096]`.
- We won’t see the result as it’ll be discarded once it is discovered `w` was an illegal instruction, although it will appear in cache
![1645474511.png](img/1645474511.png)
- When all the cache is loaded, one page will load significantly quicker than others as it was loaded during speculative running.
###### Attack steps
1. Flush the cache
2. CPU speculatively evaluates our read using *data*
3. Read all pages pointed to by `memory[]` and time it
4. Page 117 was quicker
- Meltdown attempts to read a value from kernel memory
- Read from kernel
- Mask out single bit
- Access user memory at that location
- If we repeat we can read all memory in kernel space