Building Secure Systems using Programming Languages and Analysis

Singularity

Author: Deian Stefan

What is the motivation behind Singularity and, more broadly, a message passing OS?

  • Bugs/vulnerabilities in existing systems due to interaction between different components. In the OS world, device drivers are plagued by vulnerabilities.
  • Isolation between different components: bugs in one wont affect other
  • In the real world, we want message passing for device drivers, browser extensions, plugins, ets
  • Low-level languages are prone to UAFs and memory leaks.

They believe that these problems can be addressed by high-level languages and message passing.

Shared messaging only seems simple; in practice it gets complicated once you need to worry about races. Locks and barriers are not easy to use.

What are the limitations/downsides of existing message passing systems?

  • Complicated programming models
  • Performance due to copying data

What is the big downside of high-level languages?

  • GC, and directly: performance

At a high-level, how does Singularity address this?

  • SIPs (software isolated processes) run in isolation from each other.
    • In general most things process handles are GCd.
    • Can allocate data in the exchange heap to share with other processes. This data is manually managed.
    • No dynamically loaded code (can’t reason about ownership etc.)
  • Only communication between processes: channels.
  • Can send scalars, channel end points and pointers on the exchange heap to other SIPs.
    • Ownership model ensures memory safety.

Why is Singularity so fast?

  • Context switching is cheap: no user-priv mode, no MMU to get in the way, all isolation is done in software. Only marginally more expensive than a function call.
  • Message passing is cheap: no allocation, the 0-copy sends means only pointer is sent and no data is copied. (Trade-off? programming model + flexibility)

What do they mean when they say memory safety?

  • No UAFs
  • No memory leaks

How do they address this?

  • Only one SIP can own a block in the exchange heap.
  • When you send pointer as message to another heap, they are now the owner of this block. You can no longer use the pointer.
  • They ensure this statically by tracking ownership at the language level:
    • You get ownership by allocating, as function parameter, or return value.
    • You lose ownership when you call function or call delete.
  • Invariants: only 1 owner (UAF), owner must free (leak).

What’s the point of expose and what can go wrong without it?

Transfer ownership of field from struct to function. Otherwise, we can have issues like UAFs:

void func(NetworkPacket* in ExHeap pk) {
  byte []  in ExHeap d = pkt->data;
  f(pkt); // if f deletes pkt or if pkt->data is deleted, etc. we crash below:
  d[32] = 44;
}

Why does Singularity have channel contracts? What are contracts? And, explain 2 issues contracts address and how they address them.

  • Homework question

What is the role of the TCell<T> constructor?

  • Homework question