Information Flow Control for Standard OS Abstractions Landon Cox April 6, 2016 Access control and the kernel • What are the primary responsibilities of a kernel? • Managing the file system • Launching/scheduling processes • Managing memory • How do processes invoke the kernel? • • • • Via system calls Hardware shepherds transition from user process to kernel Processor knows when it is running kernel code Represents this through protection rings or mode bit Access control and the kernel • How does kernel know if system call is allowed? • • • • Looks are user id (uid) of process making the call Looks at resources accessed by call (e.g., file) Checks access-control policy associated with resource Decides if policy allows uid to access resources • How is a uid normally assigned to a process? • On fork, child inherits parent’s uid MOO accounting problem • Multi-player game called Moo • Want to maintain high score in a file • Should players be able to update score? Game client (uid x) • Yes • Do we trust users to write file directly? • No, they could lie about their score High score Game client (uid y) MOO accounting problem • Multi-player game called Moo Game client (uid x) • Want to maintain high score in a file • Should players be able to update score? • Yes • Do we trust users to write file directly? • No, they could lie about their score • Could have a trusted process update scores • Why isn’t this sufficient? Trusted process (root) • Can’t be sure that reported score is genuine • Also want to ensure that score was computed correctly High score Game client (uid y) Access control • Simple inheritance of uids is not sufficient for • Tasks involving management of “user id” state • Logging in (login) • Changing passwords (passwd) • Why isn’t this code just inside the kernel? • This functionality doesn’t really require interaction w/ hardware • Would like to keep kernel as small as possible • How are “trusted” user-space processes identified? • Run as super user or root (uid 0) • Like a software kernel mode • If a process runs under uid 0, then it has more privileges Access control • Why does login need to run as root? • Needs to check username/password correctness • Needs to fork/exec process under another uid • Why does passwd need to run as root? • Needs to modify password database (file) • Database is shared by all users • What makes passwd particularly tricky? • Easy to allow process to shed privileges • passwd requires an escalation of privileges • Solution: setuid • Executable files can have their setuid bit set • If setuid bit is set, process inherits uid of image file’s owner on exec MOO accounting problem • Multi-player game called Moo • Want to maintain high score in a file • How does setuid allow us to know that score is correct? • • • • Game executable is owned by trusted entity Game cannot be modified by normal users Users can run executable though High-score is also owned by trusted entity Game client (uid x) High score • This is a form of trustworthy computing • High-score maintainer knows exactly which code will update score • Ensures code integrity, even when run by untrusted users Game client (uid y) Information Flow Control (IFC) • Goal: track which secrets a process has seen • Mechanism: each process gets a secrecy label • Label summarizes which categories of data a process is assumed to have seen. “tag” • Examples: “label” • { “Financial Reports” } • { “HR Documents” } • { “Financial Reports” and “HR Documents” } Slide by Max Krohn Secrecy, Integrity, and Privilege • Secrecy label (Sp) How did endorsements work in the Moo prob? • Specifies what data P has read • “/usr/bin/login may read the password file” What is an endorsement? • Integrity label (Ip) • • • • Used to endorse trustworthiness of P Why is this restriction necessary? “/usr/bin/login can only be updated by root” Also limits what P can read “/usr/bin/login can only read user libs and config files endorsed by root” • Ownership (Op) • • • • Regulates how P can update Sp and Ip Tags P can add to its labels (e.g., t+), i.e., endorse via integrity label Tags P can remove from its labels (e.g., t-), i.e., declassify via secrecy label Dp is the set of tags that P can both add and remove Secrecy, Integrity, and Privilege • Secrecy • “At some point process p added data with tag s to its address space.” • s ∈ Sp ∃(data) : p read data with tag s • Integrity • “All inputs to process p had tag i.” • i ∈ Ip ∀(data) : p read data with tag i • Privilege • • • • “p can remove tag s from Spand add tag i to Ip.” s ∈ t- p is trusted to declassify s i ∈ t+ p is trusted to endorse i t ∈ Dp t ∈ t- and t ∈ t+ Tags + Secrecy Labels Secrets P has Process p viewed change_label({Finance}); tag_t HR = create_tag(); change_label({}); change_label({Finance,HR}); Any process can add SpS=p {=Finance, {SpFinance = {} HR } } any tag to its label. change_label({Finance}); D = {} Dp p= { HR } DIFC Rule: A process can Tags P can add and remove from its label HR Universe of Tags: create a new tag; gets Same asto Step 1. ability declassify it. DIFC: Declassification Legal in action. Finance SecretProjects Slide by Max Krohn Tags + Integrity Labels change_label({}); Process Endorsementspof P Any process can remove any tag from its label. Ip = {Apple} Dp = {} Tags P can add and remove from its label Legal Universe of Tags: Finance Apple Slide by Max Krohn Tags + Integrity Labels change_label({}); Process p Ip = {} Dp = {} Legal Universe of Tags: Finance Apple Slide by Max Krohn Tags + Integrity Labels Process p change_label({}); tag_t HR = create_tag(); change_label({Microsoft}); Ip = {} Dp = {} Legal Universe of Tags: Finance Apple Slide by Max Krohn Tags + Integrity Labels Process p change_label({}); tag_t HR = create_tag(); Ip = {} Dp = {} Legal Universe of Tags: Finance Apple Slide by Max Krohn Tags + Integrity Labels Process p change_label({}); tag_t HR = create_tag(); Ip = {} Dp = {HR} DIFC Rule: A process can create a new tag; gets ability to endorse w/ it. Legal HR Universe of Tags: Finance Apple Slide by Max Krohn Tags + Integrity Labels Process p Ip = {} Dp = {HR} change_label({}); tag_t HR = create_tag(); change_label({HR}); Legal HR Universe of Tags: Finance Apple Slide by Max Krohn Tags + Integrity Labels Process p Ip = {HR} Dp = {HR} change_label({}); tag_t HR = create_tag(); change_label({HR}); DIFC: Endorsement in action. Legal HR Universe of Tags: Finance Apple Slide by Max Krohn Privilege in action (secrecy) HR Universe of Secrecy Tags: Legal Finance SecretProjects Process p Sp = {} Dp = { HR, Admin } Microsoft Bob’s code Admin Alice’s code Universe of Integrity Tags Privilege in action (secrecy) HR Universe of Secrecy Tags: Legal Finance SecretProjects Process p Sp = { HR } Dp = { HR, Admin } Microsoft Bob’s code Admin Why is this allowed? Alice’s code Universe of Integrity Tags Privilege in action (secrecy) HR Universe of Secrecy Tags: Legal Finance SecretProjects Process p Sp = { HR } Dp = { HR, Admin } Microsoft Bob’s code Admin What is the effect? Alice’s code Universe of Integrity Tags Privilege in action (secrecy) HR Universe of Secrecy Tags: Legal Finance SecretProjects Process p Sp = { HR } Dp = { HR, Admin } q Sq = { HR } Microsoft Bob’s code Admin What is the effect? Can now receive data from HR processes Alice’s code Universe of Integrity Tags Privilege in action (secrecy) HR Universe of Secrecy Tags: Legal Finance SecretProjects Process p Sp = {} Dp = { HR, Admin } q Sq = { HR } Microsoft Bob’s code Admin Why is this allowed? Alice’s code Universe of Integrity Tags Privilege in action (secrecy) HR Universe of Secrecy Tags: Legal Finance SecretProjects Process p Sp = {} Dp = { HR, Admin } q Sq = { HR } Microsoft Bob’s code Admin What is the effect? Alice’s code Universe of Integrity Tags Privilege in action (secrecy) r HR Universe of Secrecy Tags: Legal Finance Sr = {} SecretProjects Process p Sp = {} Dp = { HR, Admin } q Sq = { HR } Microsoft Bob’s code Admin What is the effect? Declassifies HR data received from q Alice’s code Universe of Integrity Tags Privilege in action (integrity) HR Universe of Secrecy Tags: Legal Finance SecretProjects Process p Ip = {Admin} Dp = { HR, Admin } Microsoft Bob’s code Admin Admin+ makes p a certifier Alice’s code Universe of Integrity Tags Privilege in action (integrity) Fake vi Ip = {} Process p vi Ip = {Admin} Dp = { HR, Admin } Ip = {Admin} /etc/r c Ip = {Admin} libc Ip = {Admin} Privilege in action (integrity) Fake vi Ip = {} “Run vi” Process p vi Ip = {Admin} Dp = { HR, Admin } Ip = {Admin} /etc/r c Ip = {Admin} libc Ip = {Admin} Privilege in action (integrity) Ip = {Admin} Dp = { HR, Admin } Fake vi q fork() “Run vi” Ip = {} Process p vi Ip = {Admin} Dp = { HR, Admin } Ip = {Admin} /etc/r c Ip = {Admin} libc Ip = {Admin} Privilege in action (integrity) Why drop Admin+? Ip = {Admin} Dp = { HR } Fake vi q fork() “Run vi” Ip = {} Process p vi Ip = {Admin} Dp = { HR, Admin } Ip = {Admin} /etc/r c Ip = {Admin} libc Ip = {Admin} Privilege in action (integrity) Should this work? Ip = {Admin} Dp = { HR } q fork() “Run vi” Fake vi Ip = {} Process p vi Ip = {Admin} Dp = { HR, Admin } Ip = {Admin} /etc/r c Ip = {Admin} libc Ip = {Admin} Privilege in action (integrity) Ip = {Admin} Dp = { HR } Fake vi q fork() “Run vi” Ip = {} Process p vi Ip = {Admin} Dp = { HR, Admin } Ip = {Admin} /etc/r c Ip = {Admin} libc Ip = {Admin} Privilege in action (integrity) Ip = {Admin} Dp = { HR } Fake vi q fork() “Run vi” Ip = {} Process p vi Ip = {Admin} Dp = { HR, Admin } Ip = {Admin} /etc/r c Ip = {Admin} libc Ip = {Admin} Privilege in action (integrity) Fake vi Ip = {} “Run Fakevi” Process p vi Ip = {Admin} Dp = { HR, Admin } Ip = {Admin} /etc/r c Ip = {Admin} libc Ip = {Admin} Privilege in action (integrity) Ip = {Admin} Dp = { HR, Admin } Fake vi q fork() “Run Fakevi” Ip = {} Process p vi Ip = {Admin} Dp = { HR, Admin } Ip = {Admin} /etc/r c Ip = {Admin} libc Ip = {Admin} Privilege in action (integrity) Ip = {Admin} Dp = { HR } Fake vi q fork() “Run Fakevi” Ip = {} Process p vi Ip = {Admin} Dp = { HR, Admin } Ip = {Admin} /etc/r c Ip = {Admin} libc Ip = {Admin} Privilege in action (integrity) Ip = {Admin} Dp = { HR } exec(“fakevi”) q fork() “Run Fakevi” Fake vi Ip = {} Process p vi Ip = {Admin} Dp = { HR, Admin } Ip = {Admin} /etc/r c Ip = {Admin} libc Ip = {Admin} Privilege in action (integrity) Should this work? Ip = {Admin} Dp = { HR } exec(“fakevi”) q fork() “Run Fakevi” Fake vi Ip = {} Process p vi Ip = {Admin} Dp = { HR, Admin } Ip = {Admin} /etc/r c Ip = {Admin} libc Ip = {Admin} Communication Rule Process p Sp = { HR } P Process q Sq = { HR, Finance } p can send to q iff Sp Sq Slide by Max Krohn Flume Communication Rule MoinMoin (p) ? P Sp = { Alice } Sp Sq Database (q) Sq =Sq{ =Alice {} } Dq = { Alice, Bob } 1. q changes to Sq = { Alice } 2. p sends to q 3. q changes back to Sq= {} Slide by Max Krohn ? MoinMoin (r) Sr = { Bob } Flume Communication Rule MoinMoin (p) Sp = { Alice } P Database (q) MoinMoin (r) Sr = { Bob } Sq = {} Senders get extra latitude Dq= { Alice, Bob } • p can send to q iff: • In IFC: Sp Sq • In Flume: Sp – Dp Sq Dq Slide by Max Krohn P Receivers get extra latitude Unexpected Program Behavior (Unreliable Communication) Process p Process q P “Fire Alice, Bob, Charlie, Doug, Eddie, Frank, George, Hilda, Ilya…” “I stopped reading” “I crashed” Slide by Max Krohn Unreliable communication Process p stdout stdin Sp = {} Dp = { HR } Process q Sq = { HR } P “Fire Alice, Bob, Charlie, Doug, Eddie, Frank, George, Hilda, Ilya…” ? “SLOW DOWN!!” “I crashed” Slide by Max Krohn New Abstraction: Endpoints Process p e f Se = { HR } Process q Sf = { HR } Sp = {} Dp = { HR } Sq = { HR } P P If Se S allowGeorge, e to send to f Ilya…” f , then “Fire Alice, Bob, Charlie,• Doug, Eddie, Frank, Hilda, • If Sf Se , then allow f to send to e • If Sf = Se , then allow bidirectional flow “SLOW DOWN!!” “I crashed” Slide by Max Krohn Endpoints Declassify Data Data enters process p with secrecy { HR } Process p e Se = { HR } Sp = {} Dp = { HR } Slide by Max Krohn But p keeps its label Sp = {} Thus p needs HR Dp Endpoint Invariant • For any tag t Sp and t Se • Or any tag t Se and t Sp • It must be that t Dp Process p e Se = { HR } Sp = { Finance } Dp = { Finance, HR} Slide by Max Krohn Export inf. Import inf. Endpoints Labels Are Independent g Sg = {} Process p e Se = { HR } Sp = {} Dp = { HR } Slide by Max Krohn f Process q Sf = { HR } Sq = { HR } Example App: MoinMoin Wiki Slide by Max Krohn How Problems Arise… if not self.request.user.may.read(pagename): return self.notAllowedFault() x43 LayoffPlans MoinMoin Wiki (100 kLOC) FreeTShirts Slide by Max Krohn MoinMoin + DIFC LayoffPlans Apache Web Server Trusted Slide by Max Krohn Declassifier 1 kLOC MoinMoin Wiki (100 kLOC) Untrusted FreeTShirts FlumeWiki Web Client FlumeOblivious unconfined confined reliable IPC GET /LayoffPlans?user=Intern&PW=abcd LayoffPlans S={ HR } Apache Declassifier 1 kLOC MoinMoin (100 kLOC) FreeTShirts S={} file I/O Slide by Max Krohn Results • Does Flume allow adoption of Unix software? • 1,000 LOC launcher/declassifier • 1,000 out of 100,000 LOC in MoinMoin changed • Python interpreter, Apache, unchanged • Does Flume solve security vulnerabilities? • Without our knowing, we inherited two ACL bypass bugs from MoinMoin • Both are not exploitable in Flume’s MoinMoin • Does Flume perform reasonably? • Performs within a factor of 2 of the original on read and write benchmarks Slide by Max Krohn Limitations • Bigger TCB than HiStar / Asbestos • Linux stack (Kernel + glibc + linker) • Reference monitor (~22 kLOC) • Covert channels via disk quotas • Confined processes like MoinMoin don’t get full POSIX API. • spawn() instead of fork() & exec() • flume_pipe() instead of pipe() Slide by Max Krohn Summary • DIFC is a challenge to Programmers • Flume: DIFC in User-Level • Preserves legacy software • Complements today’s programming techniques • MoinMoin Wiki: Flume works as promised • Invite you to play around: http://flume.csail.mit.edu Slide by Max Krohn