`P.      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~  .Make a unique filename and open it for reading/writing. The returned  ? is the (possibly relative) path of the created file, which is L padded with 6 random characters. The argument is the desired prefix of the / filepath of the temporary file to be created. FMake a unique filename with a given prefix and suffix and open it for  reading/writing. The returned $ is the (possibly relative) path of M the created file, which contains 6 random characters in between the prefix M and suffix. The first argument is the desired prefix of the filepath of the H temporary file to be created. The second argument is the suffix of the  temporary file to be created. %If you are using as system that doesn'&t support the mkstemps glibc function H (supported in glibc > 2.11) then this function simply throws an error. &Make a unique directory. The returned  is the path of the N created directory, which is padded with 6 random characters. The argument is N the desired prefix of the filepath of the temporary directory to be created.   MonadCatch1 is the class used to generalize the standard IO  catch and throwIO- functions to methods that can be defined in  multiple monads.  Minimal definition requires: mask, throwIO, catch, and   onException. <Executes a computation with asynchronous exceptions masked.  See Control.Exception for more details.  Function A that takes a mask-restoring function as argument and returns an  action to execute. Like 6, but does not pass a restore action to the argument.  A variant of throwIO$ that can be used within the monad. &Simplest exception-catching function. Computation to run Handler  Version of  $ with the arguments swapped around. FPerforms an action and a subsequent action if an exceptino is raised. Computation to run first Computation to run after, if  an exception was raised. >This function allows you to execute an action with an initial  "acquire resource" and final "release resource" as bracket  of Control.Exception. Computation to run first Computation to run last Computation to run in-between  Variant of  ' where the return value from the first  computation is not required. ,Performs an action and a subsequent action. Computation to run first Computation to run after Given some general  onException function, genericBracket 1 allows you to execute an action with an initial "acquire resource"  and final "release resource" as bracket of Control.Exception. On exception function Action to perform first Action to perform last Action to perform in-between Result of in-between action        X?For privileged code that needs to catch all exceptions in some & cleanup function. Note that for the ! monad, these methods do  not8 label the exceptions. It is assumed that you will use  G instead of F) for IO within the computation arguments  of these methods. DA labeled exception is simply an exception associated with a label. AViolation of information flow conditions, or label checks should  throw exceptions of type  LabelFault. The  LerrInval constructor C takes a string parameter -- it is important that trusted code use : this carefully and aovid leaking information through it. Invalid request Insufficient privileges Label would exceed clearance Current label too high Requested label too low !It is useful to have the dual of , ReadTCB, that allows  for the reading of  s that were written using . Only  readTCB (corresponding to ) and  readsPrecTCB (corresponding  to ) are implemented. AIt would be a security issue to make certain objects a member of  the 3 class, but nonetheless it is useful to be able to + examine such objects when debugging. The  method can be used  to examine such objects.  Labeled( is a type representing labeled data. !ALIO monad is a State monad transformer with IO as the underlying  monad. "Internal state of an ! computation. #$label-specific state %current label &current clearance 'current privileges (@Empty class used to specify the functional dependency between a  label and it state. ) A generic - instance that works for all 1s and confers  no downgrading privileges. *+,8A function that mints new objects (such as instances of  -:) in a way that only privileged code should be allowed to 6 do. Because the MintTCB method is only available to @ priviledged code, other modules imported by unpriviledged code " can define instances of mintTCB. -?This class defines privileges and the more-permissive relation  (.7) on labels using privileges. Additionally, it defines  /: which is used to compute the smallest difference between & two labels given a set of privilege. .The "can-flow-to given privileges" pre-order used to 3 compare two labels in the presence of privileges.  If . p L_1 L_2 holds, then privileges p are sufficient to  downgrade data from L_1 to L_2 . Note that 6 L_1 L_2  implies 6 p L_1 L_2 for all p, but for some labels and  privileges, . will hold even where 6 does not. /Roughly speaking, L_r = lostar p L L_g computes how close * one can come to downgrading data labeled L to the goal label  L_g, given privileges p. When p == *), the resulting  label  L_r == L `4`L_g. If p# contains all possible privileges,  then  L_r == L_g. More specifically, L_r$ is the greatest lower bound of the  set of all labels L_l satisfying:    L_g " L_l, and   L "  L_l. Operationally, lostar) captures the minimum change required to - the current label when viewing data labeled L_l . A common ! pattern is to use the result of < as L_g (i.e.,  the goal is to use privileges p to avoid changing the label  at all), and then compute L_r based on the label of data - the code is about to observe. For example, U could be  implemented as:   taintP p l = do lcurrent <- <  T (lostar p l lcurrent)  Privileges  Label from which data must flow  Goal label Result 0PrivTCB4 is a method-less class whose only purpose is to be * unavailable to unprivileged code. Since (PrivTCB t) => is in the  context of class -) and unprivileged code cannot create new  instances of the PrivTCB' class, this ensures unprivileged code $ cannot create new instances of the - class either, even though  the symbol - is exported by LIO.Base and visible to  untrusted code. 1>This class defines a label format, corresponding to a bounded Blattice. Specifically, it is necessary to define a bottom element 2 (in literature, written as "), a top element 3 (in literature, written as "!), a join, or least upper bound, 4 (in literature, written as "), a meet, or greatest lower bound, 5 (in literature, written as "), and of course the can-flow-to partial-order 6 (in literature, written as "). 2Bottom 3Top 4'Least upper bound (join) of two labels 5*Greatest lower bound (meet) of two labels 6Can-flow-to relation 7$Returns label-specific state of the ! monad. This is the * data specified as the second argument of ;, whose type is  s in the monad LIO l s. 8%Sets the label-specific state of the ! monad. See 7. 9Generate a fresh state to pass : when invoking it for the ) first time. The current label is set to 2, the current  clearance is set to 3(, and the current privileges are set to  none. Lift an IO computation into LIO. ,Given an LIO computation and state, run it. :<Execute an LIO action. The label on exceptions are removed.  See ;. ; Produces an , computation that will execute a particular ! 5 computation. Because untrusted code cannot execute  B computations, this function should only be useful within trusted * code. No harm is done from exposing the evalLIO symbol to A untrusted code. (In general, untrusted code is free to produce   computations--it just can'!t execute them without access to  F.) The LIO computation to execute &Initial value of label-specific state 0IO computation that will execute first argument <'Returns the current value of the thread' s label. ='Returns the current value of the thread' s clearance. > Returns the current privileges. ?BExecute an LIO action with a set of underlying privileges. Within  a withPrivileges3 block, the supplied privileges are used in every  even (non ...P) operation. For instance,   unlabelP p x can instead be written as:   withPrivileges p $ unlabel x 9The original privileges of the thread are restored after # the action is executed within the withPrivileges block.  The withPrivileges- combinator provides a middle-ground between , a fully explicit, but safe, privilege use (...P combinators), : and an implicit, but less safe, interface (provide getter/setter, > and always use underlying privileges). It allows for the use @ of implicit privileges by explicitly enclosing the code with a  withPrivileges block. @If the current label is oldLabel and the current clearance is   clearance2, this function allows code to raise the label to  any value newLabel such that   oldLabel `6` newLabel && newLabel `6` clearance.  Note that there is no setLabel variant without the ...P  because the T( function provides essentially the same  functionality that setLabel would. A;Set the current label to anything, with no security check. BAReduce the current clearance. One cannot raise the current label A or create object with labels higher than the current clearance. C4Raise the current clearance (undoing the effects of B).  This requires privileges. D?Set the current clearance to anything, with no security check. E9Lowers the clearance of a computation, then restores the ; clearance to its previous value. Useful to wrap around a D computation if you want to be sure you can catch exceptions thrown $ by it. Also useful to wrap around P to ensure that the D computation does not access data exceeding a particular label. If   withClearance is given a label that can't flow to the current @ clearance, then the clearance is lowered to the greatest lower 8 bound of the label supplied and the current clearance. $Note that if the computation inside  withClearance acquires any  -9s, it may still be able to raise its clearance above the  supplied argument using C. F Lifts an  computation into the ! monad. Note that  exceptions thrown within the  computation cannot directly be  caught within the !( computation. Thus, you will generally  want to use G instead of F. G Lifts an  computation into the ! monad. If the  C computation throws an exception, it labels the exception with the 8 current label so that the exception can be caught with   or  Z. This function's name stands for " re-throw io". HReturns label of a   type. IFunction to construct a  " from a label and pure value. If  the current label is lcurrent and the current clearance is  ccurrent, then the label l specified must satisfy   lcurrent `6` l && l `6` ccurrent. J Constructs a   using privilege to allow the  's label 9 to be below the current label. If the current label is lcurrent  and the current clearance is ccurrent, then the privilege p and  label l specified must satisfy  (leqp p lcurrent l) && l `6` ccurrent. D Note that privilege is not used to bypass the clearance. You must  use C- to raise the clearance first if you wish to  create an  / at a higher label than the current clearance. K1Trusted constructor that creates labeled values. L Within the ! monad, this function takes a   and returns  the value. Thus, in the ! monad one can say:  0 x <- unlabel (xv :: Labeled SomeLabelType Int) +And now it is possible to use the value of x, which is the pure  value of what was stored in xv. Of course, unlabel also raises C the current label. If raising the label would exceed the current  clearance, then unlabel throws .  However, you can use H to check if L will succeed  without throwing an exception. MExtracts the value of an   just like L, but takes a E privilege argument to minimize the amount the current label must be  raised. Will still throw  under the same  circumstances as L. NExtracts the value from an  , discarding the label and any  protection. ORaises the label of a   to the 4 of it's current label C and the value supplied. The label supplied must be less than the A current clearance, though the resulting label may not be if the   $ is already above the current thread' s clearance. P toLabeled is the dual of unlabel. It allows one to invoke > computations that would raise the current label, but without E actually raising the label. Instead, the result of the computation  is packaged into a   with a supplied label. # Thus, to get at the result of the # computation one will have to call L and raise the label, but : this can be postponed, or done inside some other call to P. A This suggests that the provided label must be above the current ( label and below the current clearance.  Note that  toLabeled2 always restores the clearance to whatever it was E when it was invoked, regardless of what occurred in the computation  producing the value of the  . = This highlights one main use of clearance: to ensure that a Labeled . computed does not exceed a particular label.  WARNING:  toLabeled( is susceptible to termination attacks. QSame as P- but allows one to supply a privilege object @ when comparing the initial and final label of the computation.  WARNING:  toLabeledP( is susceptible to termination attacks. R?Executes a computation that would raise the current label, but B discards the result so as to keep the label the same. Used when > one only cares about the side effects of a computation. For  instance, if  log_handle is an LHandle with a high label, one  can execute    discard ltop $  hputStrLn log_handle " Log message" Bto create a log message without affecting the current label. (Of  course, if  log_handle, is closed and this throws an exception, it 7 may not be possible to catch the exception within the ! monad $ without sufficient privileges--see Z.) 8WARNING: discard is susceptible to termination attacks. SSame as R1, but uses privileges when comparing initial and ! final label of the computation. )General (internal) taint function. Uses mylub instead of  49, so that privileges can optionally be passed in. Throws  / if raising the current label would exceed the  current clearance. mylub function l - Label to taint with TUse taint l4 in trusted code before observing an object labeled  l0. This will raise the current label to a value l' such that  l `6` l' , or throw  if l' would have to be $ higher than the current clearance. ULike T3, but use privileges to reduce the amount of taint  required. Note that unlike @, taintP will never lower D the current label. It simply uses privileges to avoid raising the  label as high as T would raise it. Privileges to invoke #Label to taint to if no privileges VUse wguard l4 in trusted code before modifying an object labeled  l. If l'7 is the current label, then this function ensures that  l' `6` l before doing the same thing as T l . Throws   if the current label l' is too high. WLike V6, but takes privilege argument to be more permissive. X?Ensures the label argument is between the current IO label and A current IO clearance. Use this function in code that allocates  objects--untrusted code shouldn't be able to create an object  labeled l unless aguard l does not throw an exception. YLike Y6, but takes privilege argument to be more permissive. ZBCatches an exception, so long as the label at the point where the 5 exception was thrown can flow to the label at which catchP is B invoked, modulo the privileges specified. Note that the handler @ receives an extra first argument (before the exception), which - is the label when the exception was thrown. -Privileges with which to downgrade exception Computation to run Exception handler !Result of computation or handler [Trusted catch functin. Computation to run Exception handler !Result of computation or handler \ Version of Z with arguments swapped. -Privileges with which to downgrade exception Exception handler Computation to run !Result of computation or handler ] 3 cannot run its handler if the label was raised in @ the computation that threw the exception. This variant allows D privileges to be supplied, so as to catch exceptions thrown with a  raised label. "Privileges to downgrade exception The computation to run Handler to run on exception Result if no exception thrown ^Like standard #, but with privileges to downgrade  exception. Priviliges used to downgrade Computation to run first Computation to run last Computation to run in-between _FForces its argument to be evaluated to weak head normal form when the A resultant LIO action is executed. This is simply a wrapper for  Control.Exception's evaluate. ` Execute an !- action with the combination of the supplied  privileges (usually passed to ...P functions) and current  privileges. [  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`[123456-./)*>?`!(;:9<@=BCE HIJLMOPQRSTUVWXY Z\]^_0+,"#$%&'78ADKN[FGQ !"#$%&'#$%&'()**+,,-././012345623456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`aAn LIORef is an IORef$ with an associated, static label. B The restriction of an immutable label come from the fact that it < is possible to leak information through the label itself.  Hence, LIO is flow-insensitive. Of course, you can create an  LIORef of  , to get a limited form of flow-sensitivity. bSame as c except  newLIORefP takes a set of > privileges which are accounted for in comparing the label of 3 the reference to the current label and clearance. c=To create a new reference the label of the reference must be  below the thread'1s current clearance and above the current label. . If this is the case, the reference is built. Label of reference Initial value Mutable reference d5Trusted constructor that creates labeled references. eGet the label of a reference. fSame as g except  readLIORefP takes a privilege object 1 which is used when the current label is raised. gBRead the value of a labeled refernce. A read succeeds only if the B label of the reference is below the current clearance. Moreover, B the current label is raised to the join of the current label and , the reference label. To avoid failures use e to check  that a read will suceed. h?Trusted function used to read the value of a reference without  raising the current label. iSame as j except  writeLIORefP takes a set of > privileges which are accounted for in comparing the label of 3 the reference to the current label and clearance. j@Write a new value into a labeled reference. A write succeeds if C the current label can-flow-to the label of the reference, and the ; label of the reference can-flow-to the current clearance. k:Trusted function used to write a new value into a labeled  reference, ignoring IFC. lSame as m except  modifyLIORefP takes a set of > privileges which are accounted for in comparing the label of 3 the reference to the current label and clearance. m@Mutate the contents of a labeled reference. For the mutation to D succeed it must be that the current label can-flow-to the label of ? the reference, and the label of the reference can-flow-to the A current clearance. Note that because a modifer is provided, the D reference contents are not observable by the outer computation and 9 so it is not required that the current label be raised. Labeled reference  Modifier n1Trusted function that mutates the contents on an a,  ignoring IFC. oSame as p except atomicModifyLIORefP takes C a set of privileges which are accounted for in label comparisons. p'Atomically modifies the contents of an a. It is required A that the label of the reference be above the current label, but  below the current clearance. q=Trusted function used to atomically modify the contents of a " labeled reference, ignoring IFC. abcdefghijklmnopqacegjmpbfilodhknqabcdefghijklmnopq abcefgijlmop abcefgijlmop!rAn LMVar+ is a labeled synchronization variable (an ) that 3 can be used by concurrent threads to communicate. s3This function returns the label of a labeled MVar. tSame as u except it takes a set of > privileges which are accounted for in comparing the label of . the MVar to the current label and clearance. u<Create a new labeled MVar, in an empty state. Note that the F supplied label must be above the current label and below the current  clearance.  Label of LMVar New mutable location v)Trusted function used to create an empty LMVar, ignoring IFC. wSame as x/ except it takes a set of privileges which are G accounted for in comparing the label of the MVar to the current label  and clearance. x@Create a new labeled MVar, in an filled state with the supplied E value. Note that the supplied label must be above the current label " and below the current clearance.  Label of LMVar Initial value of LMVar New mutable location y#Trusted function used to create an LMVar with the supplied  value, ignoring IFC. zSame as { except  takeLMVarP takes a privilege object 1 which is used when the current label is raised. {Return contents of the r&. Note that a take consists of a read 3 and a write, since it observes whether or not the r is full, < and thus the current label must be the same as that of the  r: (of course, this is not the case when using privileges).  Hence, if the label of the r! is below the current clearance, E we raise the current label to the join of the current label and the 0 label of the MVar and read the contents of the MVar . If the  r is empty,  takeLMVar blocks. |Read the contents of an r, ignoring IFC. }Same as ~ except  putLMVarP takes a privilege object 1 which is used when the current label is raised. ~Puts a value into an r%. Note that a put consists of a read 3 and a write, since it observes whether or not the r is empty, : and so the current label must be the same as that of the r D (of course, this is not the case when using privileges). As in the  { case, if the label of the r is below the current B clearance, we raise the current label to the join of the current < label and the label of the MVar and put the value into the MVar.  If the r is full, putLMVar blocks. Source r  New value Put a value into an r, ignoring IFC. Same as  except  readLMVarP takes a privilege object 1 which is used when the current label is raised. Combination of { and ~. Read the value, and just  put it back. As specified for , this operation is atomic & iff there is no other thread calling ~ for this r. 0Trusted function used to read (take and put) an r, ignoring IFC. Same as  except  swapLMVarP takes a privilege object 1 which is used when the current label is raised. Takes a value from an r, puts a new value into the LMvar, . and returns the taken value. Like the other r operations it # is required that the label of the r be above the current label H and below the current clearance. Moreover, the current label is raised B to accommodate for the observation. This operation is atomic iff " there is no other thread calling ~ for this r. Source LMVar  New value  Taken value %Trusted function that swaps value of r, ignoring IFC. Same as 2, but uses priviliges when raising current label. Non-blocking version of { . It returns Nothing if the  r is empty, otherwise it returns Just value, emptying the r. Same as , but ignorses IFC. Same as 2, but uses privileges when raising current label. Non-blocking version of ~ . It returns True if the  r7 was empty and the put succeeded, otherwise it returns False. Same as , but ignorses IFC. Same as 2, but uses privileges when raising current label. Check the status of an r!, i.e., whether it is empty. The ' function succeeds if the label of the r is below the current = clearance -- the current label is raised to the join of the r E label and the current label. Note that this function only returns a  snapshot of the state. Same as , but ignorses IFC. Same as ,, but uses privileges when performing label  comparisons/raises. +Exception-safe wrapper for working with an r. The original  contents of the r0 will be restored if the supplied action throws @ an exception. The function is atomic only if there is no other  thread that performs a ~. Same as , but ignores IFC. rstuvwxyz{|}~ rsutxw{z~}vy| rstuvwxyz{|}~BA labeled thread result is simply a wrapper for a labeled MVar. A E thread can observe the result of another thread, only after raising ' its label to the label of the result.  An LIO fork. Same as 3, but the supplied set of priviliges are accounted ( for when performing label comparisons. Labeled fork. lFork( allows one to invoke computations taht ? would otherwise raise the current label, but without actually E raising the label. The computation is executed in a separate thread = and writes its result into a labeled result (whose label is @ supplied). To observe the result of the computation, or if the 3 computation has terminated, one will have to call  and * raise the current label. Of couse, as in P, this can be ' postponed until the result is needed. lFork6 takes a label, which corresponds to the label of the C result. It is require that this label is above the current label, E and below the current clearance. Moreover, the supplied computation E must not read anything more sensitive, i.e., with a label above the ? supplied label --- doing so will result in an exception being  thrown. Not that, compared to P, lFork immediately returns a  labeled result of type , which is essentially a "future",  or "promise"2. Moreover, to guarantee that the computation has @ completed, it is important that some thread actually touch the  future, i.e., perform an . Label of result *Computation to execute in separate thread Labeled result Same as 2, but uses priviliges in label checks and raises. #Given a labeled result (a future), lWait returns the unwrapped $ result (blocks, if necessary). For lWait to succeed, the label of B the result must be above the current label and below the current + clearnce. Moreover, before block-reading, lWait raises the current = label to the join of the current label and label of result.  If the thread lWait. is terminates with an exception (for example E if it violates clearance), the exceptin is rethrown. Similarly, if A the thread reads values above the result label, an exception is  thrown in place of the result.  rstuwxz{}~rstuwxz{}~51 associated with a . /A wrapper for a new, not yet commited, object. (An object can be a directory or a file.  File object Directory object Filesystem errors $Root is invalid (must be absolute). Root structure is corrupt Root of labeled filesystem.  Temporary files have the prefix '#'. Prefix of object filenames. 3Shadow directory containing the actual FS objects. 8We need to serialize the label in each label directory. Root of the filesystem. 9Magic file. Last file created when the the filesystem is D initially created. If the magic file is invalid, then it is likely / that a failure occured in the set up process.  Content written to magic file. Same as ;&, but takes two additional parameters C corresponding to the path of the labeled filesystem store and the D label of the root. If the labeled filesystem store does not exist, > it is created at the specified path with the root having the  supplied label. F If the filesystem does exist, the supplied label is ignored and thus A unnecessary. However, if the root label is not provided and the + filesystem has not been initialized, then 2 is used as the  root label. Filesystem root Label of root  LIO action Initial state AInitialize the filesystem with a given label and root file path. Label of root Path to the filesystem root  Check the filesystem structure. >Encoding of a label into a filepath. We need to take the hash D of a label (as opposed to e.g. just 64-base encoding of the label) = in order to keep the filename lengths to a reasonable size. 2Create a new directory object with a given label. 0Create a new file object with a given label and . HCreate a new temporary unique object directory. The function retries if 2 there exists an object with the same name but no . CCreate a new temporary unique object file. The function retries if 2 there exists an object with the same name but no . @Create a new file or directory object (given the make temporary D object functino). For example, we can create a new file object as:  A newDirObj l = newObj l $ \p -> (New . DirObj) <$> mkTmpObjDir p or a new directory object as # newFileObj l m = newObj l $ \p -> B (New . uncurry FileObj) <$> mkTmpObjFile m p) Label of object Object creation function .Create the label directory (and corresponding ) in . This function creates a  for the given label @ directory. It also verifies that the label in the file is the C same as the given label (as another thread might have created the B file, or a previous write might have corrupted the file). If the @ file is invalid, it removes the existing label file and writes D the given label. An assumption made here is that there is a 1-to-1 8 correspondence between a label and its encoding (i.e.,   is a bijection).  Link the  to an object directory. Link without returning object. Link a filepath to an object. It';s possible that either a program crashed before renaming a   into a $, or that another thread is calling  / and for some reason is being slow between the   and  ! calls. Either way it should be  fine for us just to   the , because the link to # the object would not exist if the  were not ready to be > renamed. This function is primarily used when traversing the  filesystem tree with  .  >Clean up a newly created object. If the object is a temporary  directory, remove it. If it''s a file, close the handle, and remove  the file. &Get the label of a labeled filepath. Trusted version of  that ignores IFC. Same as $ but uses privileges to unlabel the  filepath. @Unlabel a filepath. If the path corresponds to a directory, you 1 can now get the contents of the directory; if it's a file, you can  open the file. ;Given a pathname (forced to be relative to the root of the A labeled filesystem), find the path to the corresponding object. G The current label is raised to reflect all the directories traversed. E Note that if the object does not exist an exception will be thrown; J the label of the exception will be the join of all the directory labels  up to the lookup failure. *Additionally, this function cleans up the - path before doing the lookup, so e.g., path foobar/.. will  first be rewritten to /foo and thus no traversal to bar. D Note that this is a more permissive behavior than forcing the read  of .. from bar. Path to object Same as * but takes an additional privilege object 3 that is exercised when raising the current label.  Privilege Path to object ?Read the label file of an object. Note that because the format D of the supplied path is not checked this function is considered to  be in the TCB.  3Given a privilege, root-path prefix and a directory/ file within  the prefix, read the " of the root-path prefix, raising D the current label to reflect this. This function is used to taint = a process that traverses a filesystem tree. The function is TCB = because we do not check any properties of the root -- it is  primarily used by .  Remove any  !s from the front of a file path. -Cleanup a file path, if it starts out with a .., we consider @ this invalid as it can be used explore parts of the filesystem A that should otherwise be unaccessible. Similarly, we remove any .  from the path. <Create a directory object with the given label and link the  supplied path to the object. 7Create a file object with the given label and link the B supplied path to the object. The handle to the file is returned.  'Remove the prefix from a list (usually ). String Prefix  Remove the " prefix from a file or directory. rmPrefixDir path prefix removes prefix from path. Ignore  IOExceptions. Same as  , but only catches  IOExceptions. Same as $, but does not crash on empty list. "A labeled handle. @Class used to abstract reading and writing from and to handles,  respectively. >Class used to abstract close and flush operations on handles. =Class used to abstract reading and creating directories, and $ opening (possibly creating) files. !Get the contents of a directory. )Create a directory at the supplied path. ? The LIO instance labels the directory with the current label. 5Open handle to manage the file at the supplied path. #Get the label of a labeled handle. @Get the contents of a directory. The current label is raised to ? the join of the current label and that of all the directories A traversed to the leaf directory (of course, using privileges to D keep the current label unchanged when possible). Note that, unlike  the standard Haskell , we first normalise the  path by collapsing all the ..' s. (The LIO filesystem does not  support links.)  Privilege  Directory >Create a directory at the supplied path with the given label. ; The current label (after traversing the filesystem to the D directory path) must flow to the supplied label which in turn must B flow to the current label (of course, using privileges to bypass @ certain restrictions). If this information flow restriction is & satisfied, the directory is created.  Privilege Label of new directory Path of directory EGiven a set of privileges, a new (maybe) label of a file, a filepath H and the handle mode, open (and possibly create) the file. If the file L exists the supplied label is not necessary; otherwise it must be supplied. G The current label is raised to reflect all the traversed directories G (of course, using privileges to minimize the taint). Additionally the G label of the file (new or existing) must be between the current label I and clearance. If the file is created, it is further required that the ? current process be able to write to the containing directory.  Privileges Label of file if created  File to open Mode of handle Close a labeled file handle. Flush a labeled file handle. Read n6 bytes from the labeled handle, using privileges when , performing label comparisons and tainting.  Privileges Labeled handle Number of bytes to read Same as 0, but will not block waiting for data to become < available. Instead, it returns whatever data is available. ? Privileges are used in the label comparisons and when raising  the current label. >Read the entire labeled handle contents and close handle upon  reading EOF0. Privileges are used in the label comparisons % and when raising the current label. ?Output the given (Byte)String to the specified labeled handle. ? Privileges are used in the label comparisons and when raising  the current label.  Synonym for . >Output the given (Byte)String with an appended newline to the < specified labeled handle. Privileges are used in the label 1 comparisons and when raising the current label. EReads a file and returns the contents of the file as a (Byte)String.  Write a (Byte)String to a file. Same as ) but uses privilege in opening the file. Same as ) but uses privilege in opening the file. Same as ' but also takes the label of the file. Same as ) but uses privilege in opening the file. ''!%The monad for LIO computations using  as the label.  The type for   values uinsg  as the label. A DCLabel privilege. A DCLabel (untrusted) privilege. A DCLabel category set. 8Runs a computation in the LIO Monad, returning both the  computation'&s result and the label of the result. Same as #, but with support for filesystem. 5 !"#$%&'()*+,-./0123456789:;<=>?@AB MonadIO-like class. 0 !()*-./123456;<=@BCEHIJLMOPQRSTUVWXYZ\]^_0123456-./)*!(;<@=BCEHIJLMOPQRSTUVWXY Z\]^_3 !()*-./123456;<=@BCEHIJLMOPQRSTUVWXYZ\]^_C !"#$%&'()*+,-./01234456789::;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~         !"#$%&'()*+,-./01203403503603703803903:03;03<03=03>03?03@01A01B01C01D01E01F01G01H01I01J01K01L01M01N01O01P01Q01R01S01T01U01V01W01X01Y01Z01[01\01]01^01_01`a lio-0.1.1 LIO.HandleLIO.MonadCatchLIO.TCBLIO.LIORef.TCBLIO.Concurrent.LMVar.TCBLIO.ConcurrentLIO.FS LIO.DCLabel LIO.MonadLIOSystem.Posix.TmpLIO.LIORef.Safe LIO.LIORefLIO.Concurrent.LMVar.SafeLIO.Concurrent.LMVarLIO.SafeLIObase GHC.IO.IOModeReadMode WriteMode AppendMode ReadWriteModeIOMode MonadCatchmaskmask_throwIOcatchhandle onExceptionbracketbracket_finallygenericBracketOnExceptionTCBonExceptionTCB bracketTCBLabeledExceptionLabeledExceptionTCB LabelFault LerrInvalLerrPriv LerrClearanceLerrHighLerrLowReadTCB readsPrecTCBreadTCBShowTCBshowTCBLabeledLIOstate labelStatelioLlioClioP LabelStateNoPrivsMintTCBmintTCBPrivleqplostarPrivTCBLabellbotltoplubglbleqgetTCBputTCBnewStaterunLIOevalLIOgetLabel getClearance getPrivilegeswithPrivileges setLabelP setLabelTCBlowerClr lowerClrP lowerClrTCB withClearanceioTCBrtioTCBlabelOflabellabelPlabelTCBunlabelunlabelP unlabelTCB taintLabeled toLabeled toLabeledPdiscarddiscardPtainttaintPwguardwguardPaguardaguardPcatchPcatchTCBhandleP onExceptionPbracketPevaluatewithCombinedPrivsLIORef newLIORefP newLIORef newLIORefTCB labelOfLIORef readLIORefP readLIORef readLIORefTCB writeLIORefP writeLIORefwriteLIORefTCB modifyLIORefP modifyLIORefmodifyLIORefTCBatomicModifyLIORefPatomicModifyLIORefatomicModifyLIORefTCBLMVar labelOfLMVarnewEmptyLMVarP newEmptyLMVarnewEmptyLMVarTCB newLMVarPnewLMVar newLMVarTCB takeLMVarP takeLMVar takeLMVarTCB putLMVarPputLMVar putLMVarTCB readLMVarP readLMVar readLMVarTCB swapLMVarP swapLMVar swapLMVarTCB tryTakeLMVarP tryTakeLMVartryTakeLMVarTCB tryPutLMVarP tryPutLMVartryPutLMVarTCB isEmptyLMVarP isEmptyLMVarisEmptyLMVarTCB withLMVarP withLMVar withLMVarTCBlForkPlForklWaitPlWait LFilePath evalWithRootlabelOfFilePathunlabelFilePathTCBunlabelFilePathPunlabelFilePath lookupObjPathlookupObjPathPgetObjLabelTCB stripSlash cleanUpPathcreateDirectoryTCB createFileTCBLHandle HandleOpshGethGetNonBlocking hGetContentshPuthPutStr hPutStrLnCloseOpshClosehFlush DirectoryOpsgetDirectoryContentscreateDirectoryopenFile labelOfHandlegetDirectoryContentsPcreateDirectoryP openFilePhClosePhFlushPhGetPhGetNonBlockingP hGetContentsPhPutPhPutStrP hPutStrLnPreadFile writeFile readFileP writeFileP writeFileL writeFileLPDC DCLabeled DCPrivTCBDCPrivDCCatSetevalDCevalDCWithRootMonadLIOliftLIOliftIO c_mkdtemp c_mkstemps c_mkstempmkstempGHC.IOFilePathmkstempsmkdtemp Text.ReadreadGHC.Read readsPrecGHC.ShowShow LabeledTCBgetputmkLIOunLIOghc-prim GHC.TypesIOgtaintControl.Exception.Base LIORefTCBGHC.MVarMVarLMVarTCBControl.Concurrent.MVarreadMVarLResforkLIO LFilePathTCB NewObjectNewObjectFileObjDirObjFSErr FSRootInvalid FSRootCorruptrootDir getRootDir tmpPrefix objPrefixobjDir labelFilerootLink magicFile magicContentinitFScheckFS encodeLabel newDirObj newFileObj mkTmpObjDir mkTmpObjFilenewObj getLabelDircreateLabelFileIfMissinglinkRootlinkObj_linkObj fixObjLink unix-2.5.0.0System.Posix.FilescreateSymbolicLinkrename pathTaintTCB cleanUpNewObjfilepath-1.2.0.1System.FilePath.Posix pathSeparatorrmPrefix rmTmpPrefix rmPrefixDir ignoreErrcatchIOsafeinitGHC.Listinit LHandleTCB dclabel-0.0.4 DCLabel.CoreDCLabelDCLabel.NanoEDSL Singleton DisjunctionOf ConjunctionOfNewDC><<> singleton.\/../\.newDC newTCBPrivnewPrivNewPrivcomponentToListlistToComponentnoPriv delegatePriv principaldisjMkDisjDisjconjMkConjConj canflowtoLatticeMkComponentAll component MkComponent Component integritysecrecy MkDCLabelname PrincipalTCBPriv canflowto_pRelaxedLattice canDelegate CanDelegateownsOwns disjToList listToDisjDisjToFromList