Files
notes/docs/lectures/security/06_reference_monitors.md
2026-10-04 15:24:17 +01:00

6.5 KiB
Raw Permalink Blame History

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 hypervisor
    • 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

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

In practice, Windows and Unix only use Ring 0&3 to save on overhead

Controlled Invocation

  • Many functions are held 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

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

Modern Kernels
  • Intel introduced the sysenter and sysexit operations with the Pentium II
    • performs with much less overhead

1645472755.png

We go immediately into 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

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

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 accessed outside ring 0
  • Meltdown is an exploit that allows us to read this privileged memory
    • We do this using a side-channel

1645474135.png

  • In Intel CPUs, it’s common to speculatively evaluate code prior to 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
...
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

  • 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