,-      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~   Trustworthy.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. Safe  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. 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.  Version of  $ with the arguments swapped around. FPerforms an action and a subsequent action if an exceptino is raised. >This function allows you to execute an action with an initial  "acquire resource" and final "release resource" as bracket  of Control.Exception.  Variant of  ' where the return value from the first  computation is not required. ,Performs an action and a subsequent action. 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.  Function A that takes a mask-restoring function as argument and returns an  action to execute.  Computation to run Handler Computation to run first Computation to run after, if  an exception was raised. Computation to run first Computation to run last Computation to run in-between Computation to run first Computation to run after On exception function Action to perform first Action to perform last Action to perform in-between Result of in-between action      UnsafeJ?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  I instead of H) 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. +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 5 L_1 L_2  implies 5 p L_1 L_2 for all p, but for some labels and  privileges, - will hold even where 5 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 == 6, the resulting  label  L_r == L `3`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, W could be  implemented as:   taintP p l = do lcurrent <- >  V (lostar p l lcurrent) /PrivTCB4 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. 0>This class defines a label format, corresponding to a bounded Blattice. Specifically, it is necessary to define a bottom element 1 (in literature, written as "), a top element 2 (in literature, written as "!), a join, or least upper bound, 3 (in literature, written as "), a meet, or greatest lower bound, 4 (in literature, written as "), and of course the can-flow-to partial-order 5 (in literature, written as "). 1Bottom 2Top 3'Least upper bound (join) of two labels 4*Greatest lower bound (meet) of two labels 5Can-flow-to relation 6 Alias for . 7Get internal state. 8Put internal state. 9$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. :%Sets the label-specific state of the ! monad. See 7. ;Generate a fresh state to pass < when invoking it for the ) first time. The current label is set to 1, the current  clearance is set to 2(, and the current privileges are set to  none. <<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  H.) >'Returns the current value of the thread' s label. ?'Returns the current value of the thread' s clearance. @ Returns the current privileges. ABExecute 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. BIf 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 `5` newLabel && newLabel `5` clearance.  Note that there is no setLabel variant without the ...P  because the V( function provides essentially the same  functionality that setLabel would. C;Set the current label to anything, with no security check. DAReduce the current clearance. One cannot raise the current label A or create object with labels higher than the current clearance. E4Raise the current clearance (undoing the effects of D).  This requires privileges. F?Set the current clearance to anything, with no security check. G9Lowers 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 R 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 E. H 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 I instead of H. I 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  \. This function's name stands for " re-throw io". JReturns label of a   type. KFunction 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 `5` l && l `5` ccurrent. L 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 `5` ccurrent. D Note that privilege is not used to bypass the clearance. You must  use E- to raise the clearance first if you wish to  create an  / at a higher label than the current clearance. M1Trusted constructor that creates labeled values. N 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 J to check if N will succeed  without throwing an exception. OExtracts the value of an   just like N, but takes a E privilege argument to minimize the amount the current label must be  raised. Will still throw  under the same  circumstances as N. PExtracts the value from an  , discarding the label and any  protection. QRaises the label of a   to the 3 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. R toLabeled is the dual of N. It allows one to invoke > computations that would raise the current label, but without 9 actually raising the label. Instead, the result of the  computation is packaged into a   with a supplied / label. (Of couse, the computation executed by  toLabeled must @ most observe any data whose label exceeds the supplied label.) >To get at the result of the computation one will have to call  N4 and raise the label, but this can be postponed, or  done inside some other call to R. This suggests that > the provided label must be above the current label and below  the current clearance.  Note that  toLabeled+ always restores the clearance to whatever @ it was 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. If an exception is thrown a a  toLabeled block, the join of @ the exception label and supplied label will be used as the new @ label. If the current label of the inner computation is above A the supplied label, an exception (whose label will reflect this  observatoin) is throw by  toLabeled.  WARNING:  toLabeled( is susceptible to termination attacks. SSame as R- 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. T?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 \.) 8WARNING: discard is susceptible to termination attacks. USame as T1, but uses privileges when comparing initial and ! final label of the computation. VUse taint l4 in trusted code before observing an object labeled  l0. This will raise the current label to a value l' such that  l `5` l' , or throw  if l' would have to be $ higher than the current clearance. WLike V3, but use privileges to reduce the amount of taint  required. Note that unlike B, taintP will never lower D the current label. It simply uses privileges to avoid raising the  label as high as V would raise it. XUse wguard l4 in trusted code before modifying an object labeled  l. If l'7 is the current label, then this function ensures that  l' `5` l before doing the same thing as V l . Throws   if the current label l' is too high. YLike X6, but takes privilege argument to be more permissive. Z?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. [Like [6, but takes privilege argument to be more permissive. \BCatches 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. ]Trusted catch functin. ^ Version of \ with arguments swapped. _ 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. `Like standard #, but with privileges to downgrade  exception. aFForces 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. b Execute an !- action with the combination of the supplied  privileges (usually passed to ...P functions) and current  privileges. ] !"#$%&'()*+,-. Privileges  Label from which data must flow  Goal label Result /0123456789:;<=The LIO computation to execute &Initial value of label-specific state 0IO computation that will execute first argument >?@ABCDEFGHIJKLMNOPQR#Label of result and upper bound on  inner-computations' observation Inner computation STUVWPrivileges to invoke #Label to taint to if no privileges XYZ[\-Privileges with which to downgrade exception Computation to run Exception handler !Result of computation or handler ]Computation to run Exception handler !Result of computation or handler ^-Privileges with which to downgrade exception Exception handler Computation to run !Result of computation or handler _"Privileges to downgrade exception The computation to run Handler to run on exception Result if no exception thrown `Priviliges used to downgrade Computation to run first Computation to run last Computation to run in-between ab]  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ab]012345,-.6@Ab!")=<;>B?DEG JKLNOQRSTUVWXYZ[ \^_`a/*+#$%&'(789:CFMP]HID !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abUnsafecAn 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. dSame as e 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. e=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. f5Trusted constructor that creates labeled references. gGet the label of a reference. hSame as i except  readLIORefP takes a privilege object 1 which is used when the current label is raised. iBRead 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 g to check  that a read will suceed. j?Trusted function used to read the value of a reference without  raising the current label. kSame as l 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. l@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. m:Trusted function used to write a new value into a labeled  reference, ignoring IFC. nSame as o 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. o@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. p1Trusted function that mutates the contents on an c,  ignoring IFC. qSame as r except atomicModifyLIORefP takes C a set of privileges which are accounted for in label comparisons. r'Atomically modifies the contents of an c. It is required A that the label of the reference be above the current label, but  below the current clearance. s=Trusted function used to atomically modify the contents of a " labeled reference, ignoring IFC. cdeLabel of reference Initial value Mutable reference fghijklmnoLabeled reference  Modifier pqrscdefghijklmnopqrscegilordhknqfjmpscdefghijklmnopqrs  Trustworthy cdeghiklnoqr Safe cdeghiklnoqrUnsafe tAn LMVar+ is a labeled synchronization variable (an ) that 3 can be used by concurrent threads to communicate. u3This function returns the label of a labeled MVar. vSame as w except it takes a set of > privileges which are accounted for in comparing the label of . the MVar to the current label and clearance. w<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. x)Trusted function used to create an empty LMVar, ignoring IFC. ySame as z/ 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. z@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. {#Trusted function used to create an LMVar with the supplied  value, ignoring IFC. |Same as } except  takeLMVarP takes a privilege object 1 which is used when the current label is raised. }Return contents of the t&. Note that a take consists of a read 3 and a write, since it observes whether or not the t is full, < and thus the current label must be the same as that of the  t: (of course, this is not the case when using privileges).  Hence, if the label of the t! 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  t is empty,  takeLMVar blocks. ~Read the contents of an t, 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 t%. Note that a put consists of a read 3 and a write, since it observes whether or not the t is empty, : and so the current label must be the same as that of the t D (of course, this is not the case when using privileges). As in the  } case, if the label of the t 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 t is full, putLMVar blocks. Put a value into an t, 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 t. 0Trusted function used to read (take and put) an t, 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 t, puts a new value into the LMvar, . and returns the taken value. Like the other t operations it # is required that the label of the t 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 t. %Trusted function that swaps value of t, ignoring IFC. Same as 2, but uses priviliges when raising current label. Non-blocking version of } . It returns Nothing if the  t is empty, otherwise it returns Just value, emptying the t. Same as , but ignorses IFC. Same as 2, but uses privileges when raising current label. Non-blocking version of  . It returns True if the  t7 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 t!, i.e., whether it is empty. The ' function succeeds if the label of the t is below the current = clearance -- the current label is raised to the join of the t 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 t. The original  contents of the t0 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. tuvw Label of LMVar New mutable location xyz Label of LMVar Initial value of LMVar New mutable location {|}~Source t  New value Source LMVar  New value  Taken value tuvwxyz{|}~ tuwvzy}|x{~ tuvwxyz{|}~ TrustworthySame 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 R, 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 (whose 5 label will reflect this observation) being thrown. BIf an exception is thrown in the inner computation, the exception C label will be raised to the join of the result label and original  exception label. Not that, compared to R, 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 . 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. Label of result *Computation to execute in separate thread Labeled result   Trustworthytuvwyz|}Safetuvwyz|} Safe-Infered 0 associated with a . 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 1 is used as the  root label. &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. Same as * but takes an additional privilege object 3 that is exercised when raising the current label. ?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.  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. Filesystem root Label of root  LIO action Initial state Path to object  Privilege Path to object  TrustworthyA 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.) >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. 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. 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. 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. ' Privilege  Directory  Privilege Label of new directory Path of directory  Privileges Label of file if created  File to open Mode of handle  Privileges Labeled handle Number of bytes to read '' Trustworthy%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. ,       TrustworthyMonadIO-like class.  Trustworthy2 !),-.0123456=>?@ABDEGJKLNOQRSTUVWXYZ[\^_`ab2012345,-.6@Ab!)=>B?DEGJKLNOQRSTUVWXYZ[ \^_`aSafe5 !),-.0123456=>?@ABDEGJKLNOQRSTUVWXYZ[\^_`ab !"#$%&'()*+,-./01234456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                        !  "  #  $  %  &  '  (  )  *  +  ,  -  .  /  0  1  2  3  4  5  6  7  8  9 : ;< lio-0.1.2 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 LabelStateMintTCBmintTCBPrivleqplostarPrivTCBLabellbotltoplubglbleqnoPrivsgetTCBputTCBgetLabelStateTCBputLabelStateTCBnewStaterunLIOevalLIOgetLabel 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 DCPrivTCBDCPrivDCCatSetevalDCevalDCWithRootMonadLIOliftLIOliftIOmkstempGHC.IOFilePathmkstempsmkdtemp$fMonadCatchIO Text.ReadreadGHC.Read readsPrecGHC.ShowShow Data.Monoidmemptyghc-prim GHC.TypesIOControl.Exception.Base$fMonadErrorIOExceptionLIO$fOnExceptionTCBLIO$fOnExceptionTCBIO$fMonadCatchLIO$fExceptionLabeledException$fShowLabeledException$fExceptionLabelFault$fShowLabelFault$fReadTCBLabeled$fShowTCBLabeledGHC.MVarMVarControl.Concurrent.MVarreadMVarLResfilepath-1.3.0.0System.FilePath.Posix pathSeparator $fShowFSErr$fExceptionFSErr$fHandleOpsLHandlebLIO$fCloseOpsLHandleLIO$fDirectoryOpsLHandleLIO$fHandleOpsHandleByteStringIO$fCloseOpsHandleIO$fDirectoryOpsHandleIO dclabel-0.0.5 DCLabel.CoreDCLabel$fLabelStateDCLabelTCBPriv()$fPrivDCLabelTCBPriv$fMintTCBTCBPrivPrincipal$fMintTCBTCBPrivComponent$fPrivTCBTCBPriv$fLabelDCLabelDCLabel.NanoEDSL><<> singleton.\/../\.newDC newTCBPrivnewPrivNewPrivcomponentToListlistToComponentnoPriv delegatePriv principaldisjMkDisjDisjconjMkConjConj canflowtoMkComponentAll component MkComponent Component integritysecrecy MkDCLabelname PrincipalTCBPriv canflowto_p canDelegateowns disjToList listToDisj$fMonadLIOtlps$fMonadLIOLIOlps