Securing Software

Run-time Enforcement

Goals

  • Understand how Control-Flow Integrity (CFI) works
    • Analyze the strengths and weaknesses of CFI
    • Construct basic control-flow graphs
  • Type systems
    • Understand what type safety does (and does not) guarantee
    • Assess whether a language is strongly typed

CFI

  • What is the adversary model for CFI?
    • How does this compare to the adversary model for previous defenses we’ve seen (e.g., canaries)?
  • What properties does CFI require to be sound?
  • What guarantees does CFI give us?
    • How does this compare to previous defenses?
  • Why does CFI require a control-flow graph?

  • Control Flow Graphs (CFGs)
    • What is a basic block?
    • How are CFGs defined?
    • Building a CFG
      • What distinguishes a sensitive vs. an insensitive analysis?
      • What properties might an analysis be sensitive to?
      • Define soundness vs. completeness
  • Where and how does CFI instrument a binary?

  • How can CFI instrumentation be verified?

  • What’s the performance impact of CFI?

  • What kinds of attacks can bypass CFI?

Types

  • Why do we need types?
  • Why are types necessary for compilation?
  • What kinds of properties can types provide?
    • Why don’t most type systems support verification?
  • What does it mean for a language to be type safe?
  • Why is C considered unsafe?
  • Give some examples of untyped, weakly-typed, and strongly-typed languages
  • What elements do you need to prove that a language is type safe?

  • From safety to security
    • How can types be used to encode safety properties?
    • What is non-interference? Why does it match our intuitive notion of secrecy?