fCWt      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~   MonadCatch1 is the class used to generalize the standard IO  catch and throwIO- functions to methods that can be defined in  multiple monads.  On exception function Action to perform before Action for afterwards Main (in between) action Result of main action     \?For privileged code that needs to catch all exceptions in some & cleanup function. Note that for the  monad, these methods do  not call Y) to label the exceptions. It is assumed  that you will use X instead of W for IO within the ) computation arguments of these methods. Invalid request Insufficient privileges Label would exceed clearance Current label too high Requested label too low  A generic  instance that works for all +s and confers  no downgrading privileges.   leqp p l1 l2 means that privileges p are sufficient to  downgrade data from l1 to l2 . Note that 2 l1 l2  implies 2 p l1 l2 for all p, but for some labels and  privileges, leqp will hold even where 2 does not. !Roughly speaking, the function   result = lostar p label goal <computes how close one can come to downgrading data labeled  label to goal given privileges p. When p == ,   result == . label goal. If p contains all possible  privileges, then result == goal. More specifically, result$ is the greatest lower bound of the  set of all labels r satisfying:   2 goal r, and   p label rOperationally, lostar) captures the minimum change required to - the current label when viewing data labeled label . A common ! pattern is to use the result of ? as goal (i.e.,  the goal is to use privileges p to avoid changing the label  at all), and then compute result based on the label of data - the code is about to observe. For example, B could be  implemented as:   taintP p l = do lcurrent <- ?  A (lostar p l lcurrent)  Privileges  Label from which data must flow  Goal label Result "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. #!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. $%&'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. (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 5 examine such objects from within the debugger. The ) - method can be used to examine such objects. )*Labeled( is a type representing labeled data. +,bottom -top .'least upper bound (join) of two labels /*greatest lower bound (meet) of two labels 012342Incomparable (neither less than nor greater than) 5 Greater than 6 Less than 7Equal 89:Raises the label of a * to the . of it's current label C and the value supplied. The label supplied must be less than the @ current clarance, though the resulting label may not be if the  *$ is already above the current thread' s clearance. ;Extracts the value from an *, discarding the label and any  protection. <Returns label of a + type. =Function to construct an *" 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 `2` l && l `2` ccurrent. >Constructs an * 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 `2` ccurrent. D Note that privilege is not used to bypass the clearance. You must  use J- to raise the clearance first if you wish to  create an */ at a higher label than the current clearance. ?'Returns the current value of the thread' s label. @'Returns the current value of the thread' s clearance. )General (internal) taint function. Uses mylub instead of  .:, 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 AUse taint l4 in trusted code before observing an object labeled  l0. This will raise the current label to a value l' such that  l `2` l' , or throw  if l' would have to be $ higher than the current clearance. BLike A3, but use privileges to reduce the amount of taint  required. Note that unlike G, taintP will never lower D the current label. It simply uses privileges to avoid raising the  label as high as A would raise it. Privileges to invoke #Label to taint to if no privileges CUse wguard l4 in trusted code before modifying an object labeled  l. If l'7 is the current label, then this function ensures that  l' `2` l before doing the same thing as A l . Throws   if the current label l' is too high. DLike C6, but takes privilege argument to be more permissive. E?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. FLike F6, but takes privilege argument to be more permissive. GIf the current label is oldLabel and the current clearance is   clearance6, this function allows code to raise the label to any  value newLabel such that   oldLabel `2` newLabel && newLabel `2` clearance.  Note that there is no setLabel variant without the ...P because  the A6 function provides essentially the same functionality  that setLabel would. H;Set the current label to anything, with no security check. IBReduce the current clearance. One cannot raise the current label A or create object with labels higher than the current clearance. J4Raise the current clearance (undoing the effects of I).  This requires privileges. K?Set the current clearance to anything, with no security check. L9Lowers 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 O 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 J. M Within the  monad, this function takes an * 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 < to check if M will suceed without  throwing an exception. NExtracts the value of an * just like M, but takes a E privilege argument to minimize the amount the current label must be  raised. Will still throw  under the same  circumstances as M. O 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 M and raise the label, but : this can be postponed, or done inside some other call to O. B This suggestst 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 D when it was invoked, regardless of what occured in the computation  producing the value of the *. < This higlights one main use of clearance: to ensure that a Labeled . computed does not exceed a particular label. PQ?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.) R$Returns label-specific state of the  monad. This is the * data specified as the second argument of V, whose type is  s in the monad LIO l s. S%Sets the label-specific state of the  monad. See R. TGenerate a fresh state to pass U when invoking it for the  first time. UExecute an LIO action. V 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  W.) The LIO computation to execute &Initial value of label-specific state 0IO computation that will execute first argument W Lifts an  computation into the  monad. Note that  exceptions thrown within the  computation cannot directly be  caught within the - computation. Thus, if you are not inside a  Y' block, you will generally want to use X  instead of W. X 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" , because ' the functionality is a combination of Y and W.  Effectively   rtioTCB = Y . W AMap a function over the underlying IO computation within an LIO. D Obviously this symbol should not be exported, as it is privileged. Like  if you don't need the state. YBPrivileged code that does IO operations may cause exceptions that + should be caught by untrusted code in the  monad. Such ! operations should be wrapped by  rethrowTCB (or X, which  uses  rethrowTCB1) to ensure the exception is labeled. Note that ; it is very important that the computation executed inside   rethrowTCB/ not in any way change the label, as otherwise   rethrowTCB- would put the wrong label on the exception. ZBCatches an exception, so long as the label at the point where the ? exception was thrown can flow to the label at which catchP is B invoked, modulo the privileges specified. Note that the handler C receives an 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 [ 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. ^Evaluate in LIO. Y  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^Y376540128+,-./ !?G@IJLABCDEF*=>MNOPQ<: Z[\]^VU()#$%9"&';HKRSWXYTQ ! !"#$%$%&''())*+,-./,-./0121237654456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_%The monad for LIO computations using  as the label. `A DCLabel privilege. aA DCLabel (untrusted) privilege. bA DCLabel category set. c8Runs a computation in the LIO Monad, returning both the  computation'&s result and the label of the result. %_`abcba`_c_`abcdefdefdefdefefghijklmnopqrstghijklmnopqrstgikmpshlorjnqtghijklmnopqrst ghiklmoprs ghiklmoprs 6 !*+,-./012345678:<=>?@ABCDEFGIJLMNOPQVZ[\]^uvwxyz{|}~Q !*+,-./012345678:<=>?@ABCDEFGIJLMNOPQVZ[\]^uvwxyz{|}~}~{|yzvwxuuvwxwxyzz{||}~~Return 3 iff the caracter could have been in the output of  .  >Serialize an Integer into an array of bytes, in little-endian  order. "Minimum number of bytes to return The Integer to serialize ;Take an array of bytes containing an Integer serialized in . little-endian order, and return the Integer. ?Return a temorary file name, based on the value of the current  time of day clock. When the file name returned by  already exists,   nextTmpName/ modifies the file name to generate a new one. ?Opens a file in exclusive mode, throwing AlreadyExistsError if " the file name is already in use. ?Executes a function on temporary file names until the function 2 does not throw AlreadyExistsError. For example,  is  defined as: 3 mkTmpFile m d s = mkTmp (openFileExclusive m) d s The function to execute (f) (Directory to prepend to temp file names Suffix for new file name The result of f and the  FilePath on which it finally  succeeded. @Creates a new file with a unique name in a particular directory  WriteMode,  AppendMode, or   ReadWriteMode (It is an error to  use ReadMode.) "Directory in which to create file Suffix for new file name Returns open handle to new  file, along with pathname of  new file >Creates a new subdirectory with uniqe file name. Returns the E pathname of the new directory as the second element of a pair, just ' for consistency with the interface to . See   if you don't want this behavior. *Directory in which to create subdirectory 'Suffix to append to new directory name #Returns full path to new directory Like 6, but just returns the pathname of the new directory. *Directory in which to create subdirectory 'Suffix to append to new directory name #Returns full path to new directory &Flushes a Handle to disk with fsync() 2The Name7 type represents user-chosen (non-opaque) filenames of  symbolic links, either "root" or pathnames of the form   LabelHash/ OpaqueName/filename". Intermediary components of the ' file name must not be symbolic links. When a Node- is first created, it has a file name with a '~' B character at the end. This is so that in the case of a crash, a C node that was not linked to can be easily recognized and deleted.  The NewNode7 type wrapper represents a node that is not yet linked  to. The Node' type represents filenames of the form   LabelHash/ OpaqueName,. These names must always point to regular E files or directories (not symbolic links). There must always exist  a file  LabalHash/LABEL specifying the label of a Node. "Type containing the pathname of a  LabelHash directory (which  must contain a file named ). !File Containing Label is Corrupt      Delete a name whether it''s a file or directory, by trying both. C This is slow, but only used for error conditions when performance  shouldn' t matter. (File name in which labels are stored in s. +File name of root directory for each label The subdirectory depth of s. Because many file systems C have linear lookup time in large directories, it is better to use D the first few characters of the hash of a label as subdirectories. A Putting all hash values into one huge directory would get slow. /Hash a label down to the directory storing all  s with that  label.  that contains a  8 that contains the directory that contains a file name. .Takes an LDir and returns the label stored in  in that  directory. May throw . AGets the LDir for a particular label. Creates it if it does not  exist. May throw . BString that gets appended to new file names. After a crash these # may need to be garbage collected. )Label protecting the contents of a node. @Create new Node in the appropriate directory for a given label. D The node gets created with an extra ~ appended, and wrapped in the  type  to reflect this fact. Label for the new node Either  or  with curried  /Returns file handle or () and destination path -Wrapper around mkNode to create a directory. 0Wrapper around mkNode to create a regular file. )Used when creating a symbolic link named src that points to  dst . If both src and dst% are relative to the current working D directory and in subdirectories, then the contents of the symbolic  link cannot just be dst, instead it is makeRelativeTo dst src. Destination of symbolic link Name of symbolic link )Returns contents to put in symbolic link  Assign a  to a , turning it into a . Note E that unlike the Unix file system, only a single link may be created  to each node. It';s possible that either a program crashed before renaming a   into a $, or that another thread is calling  0 and for some reason is being slow betweeen the   and ! calls. Either way it should be  fine for us just to  the , because the   would not exist if the  were not ready to be renamed. Thie function just calls  on the filename in a . : However, on the off chance that the file system is in an ? inconsistent state (e.g., because of a crash during a call to  3), it tries to finish creating a partially created  . "Thie function is a wrapper around  that & tries to fixup errors analogously to . BLabel protecting the name of a file. Note that this is the label A of the directory containing the file name, not the label of the % Node that the file name designates. @This function reads the contents of a symbolic link and returns B the pathname of its destination, relative to the current working  directory. It elides ..# components at the begining of the - symbolic link contents, so that if the link foo/ bar -> ../baz  exists,  expandLink "foo/bar" will return "foo/baz". Warning:8 This function assumes no itermediary components of the 4 path to the symbolic link are also symbolic links.  that a  is pointing to.  Gives the % of a directory entry in a directory .  !AReturn the root directory for the default root label. (There is < a root directory for each label, but only one label is the  default.) /Get the root directory for a particular label. 1Creates a root directory for a particular label. 'Looks up a FilePath, turning it into a , and raising to E current label to reflect all directories traversed. Note that this  only looks up a ; it does not ensure the  actually & exists. The intent is that you call  lookupName before creating  or opening files. CNote that this function will touch bad parts of the file system if  it is supplied with a malicous . Thus, it is important to  keep the constructor of # private, so that the only way for . user code to generate names is to start with  and call   lookupName. Privileges to limit tainting  Start point Name to look up Privileges to limit tainting Start point (e.g., ) Name to look up True if you want to write it ;Creates a temporary directory in an existing directory (or ' label-specific root directory, if the  argument comes from  ).  Privileges to minimize tainting Label for the new directory % of dir in which to create directory Suffix for name of directory #Returns both name in directory and  of new directory " Privileges Label for the new directory  Start point Name to create Privileges to minimize taint Label if new file is created Starting point of pathname Path of file relative to prev Mode of handle a !*+,-./012345678:<=>?@ABCDEFGIJLMNOPQVZ[\]^defghiklmoprs# !"#$%&'())*+,--./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~   (                        ! " # $ % & ' ( )*+,*+-./0 1 2 3 4 567 lio-0.0.1 LIO.HandleLIO.MonadCatchLIO.TCB LIO.DCLabel LIO.MonadLIOLIO.LIORef.TCB LIO.HiStar LIO.Armor LIO.TmpFileLIO.FSLIO.LIORef.Safe LIO.LIORefLIO.BaseLIO.LIObase GHC.IO.IOModeReadMode WriteMode AppendMode ReadWriteModeIOMode MonadCatchblockunblockthrowIOcatchhandle onExceptionbracketgenericBracketOnExceptionTCBonExceptionTCB bracketTCB LabelFault LerrInvalLerrPriv LerrClearanceLerrHighLerrLowLIOLIOstate labelStatelioLlioCNoPrivsPrivleqplostarPrivTCBReadTCB readsPrecTCBreadTCBMintTCBmintTCBShowTCBshowTCBLabeledLabellbotltoplubglbPOrdpcompareleq POrderingPNEPGTPLTPEQo2polabelTCB taintLabeled unlabelTCBlabelOflabellabelPgetLabel getClearancetainttaintPwguardwguardPaguardaguardP setLabelP setLabelTCBlowerClr lowerClrP lowerClrTCB withClearanceunlabelunlabelP toLabeled toLabeledPdiscardgetTCBputTCBnewstaterunLIOevalLIOioTCBrtioTCB rethrowTCBcatchPhandleP onExceptionPbracketPevaluateDC DCPrivTCBDCPrivDCCatSetevalDCMonadLIOliftLIOliftIOLIORef newLIORefP newLIORef newLIORefTCB labelOfLIORef readLIORefP readLIORef readLIORefTCB writeLIORefP writeLIORefwriteLIORefTCBatomicModifyLIORefPatomicModifyLIORefatomicModifyLIORefTCBHSHSStatenextCatHSPrivsHSLabelHSLHSLevelL3L2L1L0 HSCategoryHSC withDefaultsassocs2 mergeWith combineLabellupdatelupdateslapplynewcatevalHSa2barmor32b2a dearmor32a32Valid serializele unserializeletmpName nextTmpNameopenFileExclusivemkTmp mkTmpFilemkTmpDir mkTmpDir'hSyncNameNodetryPred labelOfNodemkNode mkNodeDir mkNodeReglinkNodeopenNodegetDirectoryContentsNode labelOfName nodeOfNameinitFSrootDir getRootDir mkRootDir lookupName lookupNode mkTmpDirLLHandle HandleOpshGethGetNonBlocking hGetContentshPut hPutStrLnCloseOpshClosehFlush DirectoryOpsgetDirectoryContentscreateDirectoryopenFilehlabelOfmkDir mkLHandlereadFile writeFilecreateDirectoryPR writeFilePR openFilePRcreateDirectoryP writeFileP openFilePLabeledExceptionTCB Text.ReadreadGHC.Read readsPrecGHC.ShowShow LabeledTCBgetputgtaintmkLIOunLIOghc-prim GHC.TypesIOiomapsiomapControl.Exception.Base dclabel-0.0.1 DCLabel.CoreDCLabelDCLabel.NanoEDSL Singleton DisjunctionOf ConjunctionOfNewDC><<> singleton.\/../\.newDC newTCBPrivnewPrivNewPriv labelToList listToLabel delegatePriv principal canflowtoLattice integritysecrecyTCBPriv canflowto_pRelaxedLattice canDelegate CanDelegateownsOwns disjToList listToDisjDisjToFromList LIORefTCBlcatnoprivsnewHSinvalTruec_fsyncRootDirNameTCBNewNodeNodeTCBLDir labelFileFSErrFSCorruptLabelstrictReadFilecatchIO catchPred ignoreErrcleanprefixrootFile lDirNdirs lDirOfLabel lDirOfNode lDirOfName labelOfLDirgetLDir newNodeExtmakeRelativeTofixNode unix-2.5.0.0System.Posix.FilescreateSymbolicLinkrenameGHC.IO.Handle.FDdirectory-1.1.0.1System.Directory expandLink pathOfName nodeEntry mkRootDirIOdefRoot LHandleTCB