$30 off During Our Annual Pro Sale. View Details »

How compilers got less terrible

How compilers got less terrible

A talk I gave at hushcon east

Richo Healey

May 15, 2015
Tweet

More Decks by Richo Healey

Other Decks in Programming

Transcript

  1. how compilers got
    less terribad
    richo

    View Slide

  2. or: richo drinks and is
    mad about golang
    richo

    View Slide

  3. who am I
    • security engineering at Stripe
    • work on (and have capital-F Feelings about)
    compilers
    • Co-own the only CVE for a skateboard with mike
    • (Go lookup 2015-2247 it’s pretty lols)
    • wrong island con

    View Slide

  4. What this isn’t
    • Why you should use $technology
    • Why you should not use $technology

    View Slide

  5. Compilers are super neat
    • Sometimes they’ll save you from yourself
    • Sometimes they won’t
    • Sometimes they’ll essentially go out of their way
    to be footguns

    View Slide

  6. what even is a compiler
    Lex tokens Parse AST
    Codegen
    asm
    Assembler
    Object
    Link Executable
    input

    View Slide

  7. int thing(char* s) {
    puts(s);
    }

    View Slide

  8. TOK int
    TOK thing
    LPAREN
    tok void
    STAR
    tok s
    LBRACE
    tok puts
    LPAREN
    STRING hi!
    RPAREN
    SEMI
    RBRACE

    View Slide

  9. FnDecl
    RetVal
    int
    Args
    char* s
    StmtList
    Ident
    thing
    call

    puts
    s

    View Slide

  10. (FnDecl thing ((char* s))
    (apply puts (s))

    View Slide

  11. Sidenote: Golang
    src/cmd/internal/gc/lex.go

    View Slide

  12. Sidenote: Golang
    src/cmd/internal/gc/lex.go

    View Slide

  13. Sidenote: Golang

    View Slide

  14. what even is a compiler
    Lex tokens Parse AST
    Codeg
    asm
    Assem
    Objec
    Link Execu
    input
    Analysis!

    View Slide

  15. what even is a compiler
    Lex tokens Parse AST
    Codeg
    asm
    Assem
    Objec
    Link Execu
    input
    Type checking
    Coherence
    Optimisation

    View Slide

  16. View Slide

  17. View Slide

  18. cool, so why do I give a
    fuck?
    • In the context of safety there are really only two
    high level things you should actually care about:

    View Slide

  19. cool, so why do I give a
    fuck?
    • How hard is it to crash my program?
    • How hard is it for an attacker to make that crash
    turing complete?

    View Slide

  20. View Slide

  21. difficulty of crash ==
    memory safety
    • Naïve solutions, fully managed memory:
    • Refcounting
    • Garbage collection

    View Slide

  22. memory safety: hardcode
    mode
    • Region based analysis:
    • Apple’s ARC
    • Rust’s borrow checker
    • enferex wrote a paper on slapping this onto
    golang

    View Slide

  23. rust’s approach

    View Slide

  24. You can ~always subvert
    this

    View Slide

  25. You can ~always subvert
    this

    View Slide

  26. The thing about people is

    View Slide

  27. View Slide

  28. View Slide

  29. Smashing the Stack

    View Slide

  30. How *did* it work?

    View Slide

  31. An stack frame
    Dataz
    Old frame pointer
    return address

    View Slide

  32. Creating an stack frame
    Dataz
    Old frame pointer
    return address
    mflr r0
    stw r0, 4(r1)
    stwu r1, -16(r1)
    Dataz
    Old frame pointer
    return address

    View Slide

  33. Destroying an stack frame
    Dataz
    Old frame pointer
    return address
    addi r1, r1, 16
    lwz r0, 4(r1)
    mtlr r0
    blr
    Dataz
    Old frame pointer
    return address

    View Slide

  34. ohnoes
    Dataz
    Old frame pointer
    return address
    lwz r3, -16(r1)
    blr sym.gets
    addi r1, r1, 16
    lwz r0, 4(r1)
    mtlr r0
    blr
    Dataz
    Old frame pointer
    return address

    View Slide

  35. View Slide

  36. Why doesn’t this work?
    • SSP: Stack Smashing Protection

    View Slide

  37. • SSP: Stack Smashing Protection

    View Slide

  38. • SSP: Stack Smashing Protection

    View Slide

  39. • SSP: Stack Smashing Protection

    View Slide

  40. Why doesn’t this work?
    • ASLR: envp is randomised

    View Slide

  41. • ASLR: everything! is randomised.. kinda

    View Slide

  42. • ASLR: everything! is randomised.. kinda

    View Slide

  43. • ASLR: everything! is randomised.. kinda

    View Slide

  44. • echo 0 | sudo tee /proc/sys/kernel/
    randomize_va_space

    View Slide

  45. Why doesn’t this work?
    • DEP: the stack isn’t executable

    View Slide

  46. You don’t even have to do that iff:
    * Your overwite is big enough
    * Some idiot made the stack executable

    View Slide

  47. It’s 2015 though

    View Slide

  48. It’s 2015 though
    Noone would do that

    View Slide

  49. *cough*golang*cough*
    https://github.com/golang/go/commit/
    3f34248a7712e451b4217aa135e9236e93ece964

    View Slide

  50. View Slide

  51. RELRO
    • Not actually a great protection, but a fine
    deterrent
    • Some pretty neat WTF about it’s original design

    View Slide

  52. No relro
    .got
    .dtors
    .data
    .bss

    View Slide

  53. Partial RELRO
    .got
    .dtors
    .data
    .bss

    View Slide

  54. FULL RELRO
    .got
    .dtors
    .data
    .bss

    View Slide

  55. One last lol-go

    View Slide

  56. Conclusion
    • I did not actually have a point
    • I just think compilers are neat
    • Rust == Good
    • Go == Good but fucking lulzy if you dare peek
    under the covers
    • Shoutout to ben who lent me a charger at 1 this
    morning

    View Slide

  57. Questions?
    • richo
    • @rich0H
    • github.com/richo
    • some slideshare url, I’ll toot it

    View Slide