packages feed

lio 0.1.1 → 0.1.2

raw patch · 18 files changed

+169/−133 lines, 18 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- LIO.Safe: NoPrivs :: NoPrivs
- LIO.Safe: data NoPrivs
- LIO.TCB: NoPrivs :: NoPrivs
- LIO.TCB: data LIO l p s a
- LIO.TCB: data NoPrivs
- LIO.TCB: instance Label l => Priv l NoPrivs
- LIO.TCB: instance Monoid NoPrivs
- LIO.TCB: instance PrivTCB NoPrivs
+ LIO.Safe: getPrivileges :: LabelState l p s => LIO l p s p
+ LIO.Safe: noPrivs :: Monoid p => p
+ LIO.Safe: withCombinedPrivs :: LabelState l p s => p -> (p -> LIO l p s a) -> LIO l p s a
+ LIO.Safe: withPrivileges :: LabelState l p s => p -> LIO l p s a -> LIO l p s a
+ LIO.TCB: LIO :: (StateT (LIOstate l p s) IO a) -> LIO l p s a
+ LIO.TCB: getLabelStateTCB :: LabelState l p s => LIO l p s s
+ LIO.TCB: newtype LIO l p s a
+ LIO.TCB: noPrivs :: Monoid p => p
+ LIO.TCB: putLabelStateTCB :: LabelState l p s => s -> LIO l p s ()
- LIO.Handle: class CloseOps h m => HandleOps h b m
+ LIO.Handle: class CloseOps h m => HandleOps h b m where hPutStr = hPut
- LIO.MonadCatch: class Monad m => MonadCatch m
+ LIO.MonadCatch: class Monad m => MonadCatch m where mask_ io = mask $ \ _ -> io handle = flip catch onException io h = io `catch` \ e -> h >> throwIO (e :: SomeException) bracket = genericBracket onException bracket_ a b c = bracket a (const b) (const c) finally a b = mask $ \ restore -> do { r <- restore a `onException` b; _ <- b; return r }
- LIO.MonadLIO: class (Monad m, LabelState l p s) => MonadLIO m l p s | m -> l p s
+ LIO.MonadLIO: class (Monad m, LabelState l p s) => MonadLIO m l p s | m -> l p s where liftIO = liftLIO
- LIO.Safe: class (Label l, Monoid p, PrivTCB p) => Priv l p
+ LIO.Safe: class (Label l, Monoid p, PrivTCB p) => Priv l p where leqp p a b = lostar p a b `leq` b
- LIO.TCB: class Monad m => MonadCatch m
+ LIO.TCB: class Monad m => MonadCatch m where mask_ io = mask $ \ _ -> io handle = flip catch onException io h = io `catch` \ e -> h >> throwIO (e :: SomeException) bracket = genericBracket onException bracket_ a b c = bracket a (const b) (const c) finally a b = mask $ \ restore -> do { r <- restore a `onException` b; _ <- b; return r }
- LIO.TCB: class MonadCatch m => OnExceptionTCB m
+ LIO.TCB: class MonadCatch m => OnExceptionTCB m where bracketTCB = genericBracket onExceptionTCB
- LIO.TCB: class (Label l, Monoid p, PrivTCB p) => Priv l p
+ LIO.TCB: class (Label l, Monoid p, PrivTCB p) => Priv l p where leqp p a b = lostar p a b `leq` b
- LIO.TCB: class ReadTCB a
+ LIO.TCB: class ReadTCB a where readTCB str = check $ readsPrecTCB minPrec str where check [] = error "readTCB: no parse" check [(x, rst)] | all (== ' ') rst = x | otherwise = error "readTCB: no parse" check _ = error "readTCB: ambiguous parse"
- LIO.TCB: getTCB :: LabelState l p s => LIO l p s s
+ LIO.TCB: getTCB :: LabelState l p s => LIO l p s (LIOstate l p s)
- LIO.TCB: putTCB :: LabelState l p s => s -> LIO l p s ()
+ LIO.TCB: putTCB :: LabelState l p s => LIOstate l p s -> LIO l p s ()

Files

LIO/Concurrent.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE CPP #-}-#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif -- |This module exposes the concurrent interface to LIO. Specifically,@@ -20,7 +20,7 @@ forkLIO :: (LabelState l p s) => LIO l p s () -> LIO l p s ThreadId forkLIO m = do   s <- getTCB-  ioTCB . forkIO $ evalLIO m s >> return ()+  ioTCB . forkIO $ runLIO m s >> return ()   -- | Same as 'lFork', but the supplied set of priviliges are accounted@@ -29,15 +29,21 @@        => p -> l -> LIO l p s a -> LIO l p s (LRes l a) lForkP p' l m = withCombinedPrivs p' $ \p -> do   mv <- newEmptyLMVarP p l-  _ <- forkLIO $ do res <- (Right <$> m) `catchTCB` (return . Left .  lubErr)-                    lastL <- getLabel-                    putLMVarTCB mv (if leqp p lastL l-                                      then res-                                      else (mkErr lastL LerrLow))+  _ <- forkLIO $ do+         res <- (Right <$> m) `catchTCB` (return . Left . (lubErr l))+         lastL <- getLabel+         putLMVarTCB mv (if leqp p lastL l+                           then res+                           else let l' = lub lastL l+                                in Left . mkErr . (lub l') $+                                      either getELabel (const l') res+                        )    return $ LRes mv-    where mkErr cl e = Left . (LabeledExceptionTCB cl) . toException $ e-          lubErr (LabeledExceptionTCB le e) = LabeledExceptionTCB (l `lub` le) e+    where mkErr le = LabeledExceptionTCB le $ toException LerrLow+          lubErr lnew (LabeledExceptionTCB le e) =+                  LabeledExceptionTCB (le `lub` lnew) e+          getELabel (LabeledExceptionTCB le _) = le  -- | Labeled fork. @lFork@ allows one to invoke computations taht -- would otherwise raise the current label, but without actually@@ -52,8 +58,12 @@ -- result. It is require that this label is above the current label, -- and below the current clearance. Moreover, the supplied computation -- must not read anything more sensitive, i.e., with a label above the--- supplied label --- doing so will result in an exception being--- thrown. +-- supplied label --- doing so will result in an exception (whose+-- label will reflect this observation) being thrown. +--+-- If an exception is thrown in the inner computation, the exception+-- label will be raised to the join of the result label and original+-- exception label. --  -- Not that, compared to 'toLabeled', @lFork@ immediately returns a -- labeled result of type 'LRes', which is essentially a \"future\",@@ -64,7 +74,7 @@       => l                    -- ^ Label of result       -> LIO l p s a          -- ^ Computation to execute in separate thread       -> LIO l p s (LRes l a) -- ^ Labeled result-lFork l m = getPrivileges >>= \p -> lForkP p l m+lFork = lForkP noPrivs  -- | A labeled thread result is simply a wrapper for a labeled MVar. A -- thread can observe the result of another thread, only after raising@@ -89,4 +99,4 @@ -- the thread reads values above the result label, an exception is -- thrown in place of the result. lWait :: (LabelState l p s) => LRes l a -> LIO l p s a-lWait v = getPrivileges >>= \p -> lWaitP p v+lWait = lWaitP noPrivs
LIO/Concurrent/LMVar/TCB.hs view
@@ -1,6 +1,9 @@ {-# LANGUAGE CPP #-}-#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702) && (__GLASGOW_HASKELL__ < 704) {-# LANGUAGE SafeImports #-}+#endif+#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 704)+{-# LANGUAGE Unsafe #-} #endif {-| This module provides an implementation for labeled MVars.  A labeled
LIO/DCLabel.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE CPP #-}-#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif @@ -26,7 +26,7 @@  import LIO.Handle (evalWithRoot) -#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if __GLASGOW_HASKELL__ >= 702 import safe Data.Typeable #else import Data.Typeable
LIO/FS.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE CPP #-}-#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ < 704 {-# LANGUAGE SafeImports #-} #endif {-# LANGUAGE DeriveDataTypeable #-}@@ -494,7 +494,7 @@ -- open the file. unlabelFilePath :: LabelState l p s                  => LFilePath l -> LIO l p s FilePath-unlabelFilePath f = getPrivileges >>= \p -> unlabelFilePathP p f+unlabelFilePath = unlabelFilePathP noPrivs  -- | Given a pathname (forced to be relative to the root of the -- labeled filesystem), find the path to the corresponding object.@@ -511,7 +511,7 @@ lookupObjPath :: (LabelState l p s, Serialize l)               => FilePath  -- ^ Path to object               -> LIO l p s (LFilePath l)-lookupObjPath f = getPrivileges >>= \p -> lookupObjPathP p f+lookupObjPath = lookupObjPathP noPrivs  -- | Same as 'lookupObjPath' but takes an additional privilege object -- that is exercised when raising the current label.
LIO/Handle.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE CPP #-}-#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif {-# LANGUAGE MultiParamTypeClasses #-}@@ -60,7 +60,7 @@                   ) where  -#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if __GLASGOW_HASKELL__ >= 702 import safe Prelude hiding (catch, readFile, writeFile) import safe System.IO (IOMode(..)) import safe qualified System.IO as IO@@ -139,13 +139,11 @@  instance (Serialize l, LabelState l p s)           => DirectoryOps (LHandle l) (LIO l p s) where-  getDirectoryContents f = getPrivileges >>= \p -> getDirectoryContentsP p f+  getDirectoryContents = getDirectoryContentsP noPrivs   createDirectory  f   = do l <- getLabel -                            p <- getPrivileges-                            createDirectoryP p l f+                            createDirectoryP noPrivs l f   openFile f m         = do l <- getLabel -                            p <- getPrivileges-                            openFileP p (Just l) f m+                            openFileP noPrivs (Just l) f m  -- | Get the contents of a directory. The current label is raised to -- the join of the current label and that of all the directories@@ -233,17 +231,17 @@               instance (LabelState l p s) => CloseOps (LHandle l) (LIO l p s) where-  hClose h = getPrivileges >>= \p -> hCloseP p h-  hFlush h = getPrivileges >>= \p -> hFlushP p h+  hClose = hCloseP noPrivs+  hFlush = hFlushP noPrivs  instance (LabelState l p s, CloseOps (LHandle l) (LIO l p s)          , HandleOps IO.Handle b IO) =>            HandleOps (LHandle l) b (LIO l p s) where-  hGet h i            = getPrivileges >>= \p -> hGetP p h i-  hGetNonBlocking h i = getPrivileges >>= \p -> hGetNonBlockingP p h i-  hGetContents h      = getPrivileges >>= \p -> hGetContentsP p h-  hPut h b            = getPrivileges >>= \p -> hPutP p h b-  hPutStrLn h b       = getPrivileges >>= \p -> hPutStrLnP p h b+  hGet            = hGetP noPrivs+  hGetNonBlocking = hGetNonBlockingP noPrivs+  hGetContents    = hGetContentsP noPrivs+  hPut            = hPutP noPrivs+  hPutStrLn       = hPutStrLnP noPrivs  -- | Close a labeled file handle. hCloseP :: (LabelState l p s) => p -> LHandle l -> LIO l p s ()@@ -334,8 +332,7 @@ -- | Same as 'writeFile' but also takes the label of the file. writeFileL  :: (HandleOps IO.Handle b IO, LabelState l p s, Serialize l) =>                l -> FilePath -> b -> LIO l p s ()-writeFileL l path contents = getPrivileges >>= \p ->-                             writeFileLP p l path contents+writeFileL = writeFileLP noPrivs  -- | Same as 'writeFileL' but uses privilege in opening the file. writeFileLP  :: (HandleOps IO.Handle b IO, LabelState l p s, Serialize l) =>
LIO/LIORef.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE CPP #-}-#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Safe #-} #endif -- |This module implements labeled IORefs.  The interface is analogous
LIO/LIORef/TCB.hs view
@@ -1,6 +1,9 @@ {-# LANGUAGE CPP #-}-#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702) && (__GLASGOW_HASKELL__ < 704) {-# LANGUAGE SafeImports #-}+#endif+#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 704)+{-# LANGUAGE Unsafe #-} #endif -- |This module implements labeled IORefs.  The interface is analogous -- to "Data.IORef", but the operations take place in the LIO monad.
LIO/MonadCatch.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE CPP #-}-#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Safe #-} #endif {-# LANGUAGE FlexibleInstances #-}
LIO/MonadLIO.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE CPP #-}-#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif {-# LANGUAGE MultiParamTypeClasses #-}
LIO/Safe.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE CPP #-}-#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif @@ -8,7 +8,9 @@ -- module for documentation.  module LIO.Safe ( Label(..)-                 , Priv(..), NoPrivs(..)+                 , Priv(..), noPrivs+                 , getPrivileges, withPrivileges+                 , withCombinedPrivs                   , LIO, LabelState                  , evalLIO                  , getLabel, setLabelP@@ -27,7 +29,9 @@                  ) where  import LIO.TCB ( Label(..)-               , Priv(..), NoPrivs(..)+               , Priv(..), noPrivs+               , getPrivileges, withPrivileges+               , withCombinedPrivs                 , LIO, LabelState                , evalLIO                , getLabel, setLabelP
LIO/TCB.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE CPP #-}-#if __GLASGOW_HASKELL__ >= 702+#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ < 704 {-# LANGUAGE SafeImports #-} #endif #if __GLASGOW_HASKELL__ >= 704@@ -55,12 +55,12 @@                 Label(..)                 -- * Basic Privilige Functions                 -- $privs-               , Priv(..), NoPrivs(..)+               , Priv(..), noPrivs                , getPrivileges, withPrivileges                , withCombinedPrivs                 -- * Labeled IO Monad (LIO)                -- $LIO-               , LIO, LabelState+               , LIO(..), LabelState                , evalLIO, runLIO                , newState                , getLabel, setLabelP@@ -95,6 +95,7 @@                -- ** Labeled IO Monad (LIO)                , LIOstate(..)                , getTCB, putTCB+               , getLabelStateTCB, putLabelStateTCB                , setLabelTCB, lowerClrTCB                -- ** Labeled Values                , ShowTCB(..), ReadTCB(..)@@ -265,7 +266,7 @@      -- | 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 == 'NoPrivs'@, the resulting+    -- @L_g@, given privileges @p@.  When @p == 'noPrivs'@, the resulting     -- label @L_r == L ``lub``L_g@.  If @p@ contains all possible privileges,     -- then @L_r == L_g@.     --@@ -301,16 +302,9 @@     -- can define instances of mintTCB.     mintTCB :: i -> t --- |A generic 'Priv' instance that works for all 'Label's and confers--- no downgrading privileges.-data NoPrivs = NoPrivs-instance PrivTCB NoPrivs-instance Monoid NoPrivs where-    mempty      = NoPrivs-    mappend _ _ = NoPrivs-instance (Label l) => Priv l NoPrivs where-    leqp _ a b      = leq a b-    lostar _ l goal = lub l goal+-- | Alias for 'mempty'.+noPrivs :: Monoid p => p+noPrivs = mempty  --------------------------------------------------------------------- -- Labeled IO -------------------------------------------------------@@ -348,21 +342,24 @@ newtype LIO l p s a = LIO (StateT (LIOstate l p s) IO a)     deriving (Functor, Applicative, Monad) -get :: (LabelState l p s) => LIO l p s (LIOstate l p s)-get = mkLIO $ \s -> return (s, s) -put :: (LabelState l p s) => LIOstate l p s -> LIO l p s ()-put s = mkLIO $ \_ -> return (() , s)+-- | Get internal state.+getTCB :: (LabelState l p s) => LIO l p s (LIOstate l p s)+getTCB = mkLIO $ \s -> return (s, s) +-- | Put internal state.+putTCB :: (LabelState l p s) => LIOstate l p s -> LIO l p s ()+putTCB s = mkLIO $ \_ -> return (() , s)+ -- | Returns label-specific state of the 'LIO' monad.  This is the -- data specified as the second argument of 'evalLIO', whose type is -- @s@ in the monad @LIO l s@.-getTCB :: (LabelState l p s) => LIO l p s s-getTCB = labelState <$> get+getLabelStateTCB :: (LabelState l p s) => LIO l p s s+getLabelStateTCB = labelState <$> getTCB  -- | Sets the label-specific state of the 'LIO' monad.  See 'getTCB'.-putTCB :: (LabelState l p s) => s -> LIO l p s ()-putTCB ls = get >>= put . update+putLabelStateTCB :: (LabelState l p s) => s -> LIO l p s ()+putLabelStateTCB ls = getTCB >>= putTCB . update     where update s = s { labelState = ls }  -- | Generate a fresh state to pass 'runLIO' when invoking it for the@@ -373,7 +370,7 @@ newState s = LIOstate { labelState = s                       , lioL = lbot                       , lioC = ltop-                      , lioP = mempty }+                      , lioP = noPrivs }  -- | Lift an IO computation into @LIO@. mkLIO :: (LabelState l p s)@@ -409,16 +406,16 @@  -- | Returns the current value of the thread's label. getLabel :: (LabelState l p s) => LIO l p s l-getLabel = lioL <$> get+getLabel = lioL <$> getTCB  -- | Returns the current value of the thread's clearance. getClearance :: (LabelState l p s) => LIO l p s l-getClearance = lioC <$> get+getClearance = lioC <$> getTCB   -- | Returns the current privileges. getPrivileges :: (LabelState l p s) => LIO l p s p-getPrivileges = lioP <$> get+getPrivileges = lioP <$> getTCB  -- | Execute an LIO action with a set of underlying privileges. Within -- a @withPrivileges@ block, the supplied privileges are used in every @@ -440,11 +437,11 @@ -- @withPrivileges@ block. withPrivileges :: (LabelState l p s) => p -> LIO l p s a -> LIO l p s a withPrivileges p m = do-  s <- get+  s <- getTCB   p0 <- getPrivileges-  put s { lioP = p `mappend` p0 }+  putTCB s { lioP = p `mappend` p0 }   a <- m-  put s { lioP = p0 }+  putTCB s { lioP = p0 }   return a  -- | If the current label is @oldLabel@ and the current clearance is@@ -456,41 +453,41 @@ -- functionality that @setLabel@ would. setLabelP :: (LabelState l p s) => p -> l -> LIO l p s () setLabelP p' l = withCombinedPrivs p' $ \p -> do-  s <- get+  s <- getTCB   if leqp p (lioL s) l-    then put s { lioL = l }+    then putTCB s { lioL = l }     else throwIO LerrPriv  -- | Set the current label to anything, with no security check. setLabelTCB :: (LabelState l p s) => l -> LIO l p s ()-setLabelTCB l = do s <- get+setLabelTCB l = do s <- getTCB                    if l `leq` lioC s-                      then put s { lioL = l }+                      then putTCB s { lioL = l }                       else throwIO LerrClearance  -- | Reduce the current clearance. One cannot raise the current label -- or create object with labels higher than the current clearance. lowerClr :: (LabelState l p s) => l -> LIO l p s ()-lowerClr l = get >>= doit+lowerClr l = getTCB >>= doit     where doit s | not $ l `leq` lioC s = throwIO LerrClearance                  | not $ lioL s `leq` l = throwIO LerrLow-                 | otherwise            = put s { lioC = l }+                 | otherwise            = putTCB s { lioC = l }  -- | Raise the current clearance (undoing the effects of 'lowerClr'). -- This requires privileges. lowerClrP :: (LabelState l p s) => p -> l -> LIO l p s ()-lowerClrP p' l = withCombinedPrivs p' $ \p -> get >>= doit p+lowerClrP p' l = withCombinedPrivs p' $ \p -> getTCB >>= doit p     where doit p s | not $ leqp p l $ lioC s = throwIO LerrPriv                    | not $ lioL s `leq` l = throwIO LerrLow-                   | otherwise            = put s { lioC = l }+                   | otherwise            = putTCB s { lioC = l }  -- | Set the current clearance to anything, with no security check. lowerClrTCB :: (LabelState l p s) => l -> LIO l p s ()-lowerClrTCB l = get >>= doit+lowerClrTCB l = getTCB >>= doit     where doit s | not $ lioL s `leq` l =             throwIO $ LerrInval ("Cannot lower the current clearance"                                  ++ " below current label.")-                 | otherwise            = put s { lioC = l }+                 | otherwise            = putTCB s { lioC = l }  -- | Lowers the clearance of a computation, then restores the -- clearance to its previous value.  Useful to wrap around a@@ -506,10 +503,10 @@ -- supplied argument using 'lowerClrP'. withClearance :: (LabelState l p s) => l -> LIO l p s a -> LIO l p s a withClearance l m = do-  s <- get-  put s { lioC = l `glb` lioC s }+  s <- getTCB+  putTCB s { lioC = l `glb` lioC s }   a <- m-  put s { lioC = lioC s }+  putTCB s { lioC = lioC s }   return a  -- | Lifts an 'IO' computation into the 'LIO' monad.  Note that@@ -547,7 +544,7 @@ -- @ccurrent@, then the label @l@ specified must satisfy -- @lcurrent ``leq`` l && l ``leq`` ccurrent@. label :: (LabelState l p s) => l -> a -> LIO l p s (Labeled l a)-label l a = getPrivileges >>= \p -> labelP p l a+label = labelP noPrivs  -- | Constructs a 'Labeled' using privilege to allow the `Labeled`'s label -- to be below the current label.  If the current label is @lcurrent@@@ -558,7 +555,7 @@ -- use 'lowerClrP' to raise the clearance first if you wish to -- create an 'Labeled' at a higher label than the current clearance. labelP :: (LabelState l p s) => p -> l -> a -> LIO l p s (Labeled l a)-labelP p' l a = withCombinedPrivs p' $ \p -> get >>= doit p+labelP p' l a = withCombinedPrivs p' $ \p -> getTCB >>= doit p     where doit p s | not $ l `leq` lioC s    = throwIO LerrClearance                    | not $ leqp p (lioL s) l = throwIO LerrLow                    | otherwise               = return $ LabeledTCB l a@@ -579,7 +576,7 @@ -- However, you can use 'labelOf' to check if 'unlabel' will succeed -- without throwing an exception. unlabel :: (LabelState l p s) => Labeled l a -> LIO l p s a-unlabel x = getPrivileges >>= \p -> unlabelP p x+unlabel = unlabelP noPrivs  -- | Extracts the value of an 'Labeled' just like 'unlabel', but takes a -- privilege argument to minimize the amount the current label must be@@ -605,26 +602,39 @@   return $ LabeledTCB (lub l la) a  --- | @toLabeled@ is the dual of @unlabel@.  It allows one to invoke+-- | @toLabeled@ is the dual of 'unlabel'.  It allows one to invoke -- computations that would raise the current label, but without--- actually raising the label.  Instead, the result of the computation--- is packaged into a 'Labeled' with a supplied label.--- Thus, to get at the result of the--- computation one will have to call 'unlabel' and raise the label, but--- this can be postponed, or done inside some other call to 'toLabeled'.--- This suggests that the provided label must be above the current--- label and below the current clearance.+-- actually raising the label.  Instead, the result of the+-- computation is packaged into a 'Labeled' with a supplied+-- label. (Of couse, the computation executed by @toLabeled@ must+-- most observe any data whose label exceeds the supplied label.) ----- 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 'Labeled'. --- This highlights one main use of clearance: to ensure that a @Labeled@--- computed does not exceed a particular label.+-- To get at the result of the computation one will have to call+-- 'unlabel' and raise the label, but this can be postponed, or+-- done inside some other call to 'toLabeled'.  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 'Labeled'.  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+-- the supplied label, an exception (whose label will reflect this+-- observatoin) is throw by @toLabeled@.+-- -- WARNING: @toLabeled@ is susceptible to termination attacks. ---toLabeled :: (LabelState l p s) => l -> LIO l p s a -> LIO l p s (Labeled l a)-toLabeled l x = getPrivileges >>= \p -> toLabeledP p l x+toLabeled :: (LabelState l p s)+          => l -- ^ Label of result and upper bound on+               --  inner-computations' observation+          -> LIO l p s a -- ^ Inner computation+          -> LIO l p s (Labeled l a)+toLabeled = toLabeledP noPrivs {-# WARNING toLabeled "toLabeled is susceptible to termination attacks" #-}  -- | Same as 'toLabeled' but allows one to supply a privilege object@@ -636,13 +646,20 @@            => p -> l -> LIO l p s a -> LIO l p s (Labeled l a) toLabeledP p' l m = withCombinedPrivs p' $ \p -> do   aguardP p l-  save_s <- get-  a <- m `catchTCB` (\(LabeledExceptionTCB le se) -> ioTCB $ throwIO-                       (LabeledExceptionTCB (l `lub` le) se))-  s <- get-  put s { lioL = lioL save_s, lioC = lioC save_s}-  unless (leqp p (lioL s) l) $ throwIO LerrLow -- l is too low-  return $ LabeledTCB l a+  save_s <- getTCB+  --+  res <- (Right <$> m) `catchTCB` (return . Left .  (lubErr l))+  s <- getTCB+  let lastL = lioL s+  putTCB s { lioL = lioL save_s, lioC = lioC save_s, lioP = lioP save_s }+  if leqp p lastL l+    then either (ioTCB . throwIO) (return . LabeledTCB l) res+    else let l' = lub lastL l+         in ioTCB . throwIO . mkErr . (lub l') $ either getELabel (const l') res+    where mkErr le = LabeledExceptionTCB le $ toException LerrLow+          lubErr lnew (LabeledExceptionTCB le e) =+                  LabeledExceptionTCB (le `lub` lnew) e+          getELabel (LabeledExceptionTCB le _) = le {-# WARNING toLabeledP "toLabeledP is susceptible to termination attacks" #-}  -- | Executes a computation that would raise the current label, but@@ -663,7 +680,7 @@ -- WARNING: discard is susceptible to termination attacks. -- discard :: (LabelState l p s) =>  l -> LIO l p s a -> LIO l p s ()-discard l x = getPrivileges >>= \p -> discardP p l x+discard = discardP noPrivs {-# WARNING discard "discard is susceptible to termination attacks" #-}  -- | Same as 'discard', but uses privileges when comparing initial and@@ -756,10 +773,10 @@        -> l                     -- ^ @l@ - Label to taint with        -> LIO l p s () gtaint mylub l = do-  s <- get+  s <- getTCB   let lnew = l `mylub` (lioL s)   if lnew `leq` lioC s-     then put s { lioL = lnew }+     then putTCB s { lioL = lnew }      else ioTCB $ E.throwIO $ LabeledExceptionTCB (lioL s)           (toException LerrClearance) @@ -785,7 +802,7 @@ -- @l' ``leq`` l@ before doing the same thing as @'taint' l@.  Throws -- @'LerrHigh'@ if the current label @l'@ is too high. wguard :: (LabelState l p s) => l -> LIO l p s ()-wguard l = getPrivileges >>= \p -> wguardP p l+wguard = wguardP noPrivs  -- |Like 'wguard', but takes privilege argument to be more permissive. wguardP :: (LabelState l p s) => p -> l -> LIO l p s ()@@ -800,14 +817,14 @@ -- objects--untrusted code shouldn't be able to create an object -- labeled @l@ unless @aguard l@ does not throw an exception. aguard :: (LabelState l p s) => l -> LIO l p s ()-aguard l = getPrivileges >>= \p -> aguardP p l+aguard = aguardP noPrivs  -- | Like 'aguardP', but takes privilege argument to be more permissive. aguardP :: (LabelState l p s) => p -> l -> LIO l p s () aguardP p' newl = withCombinedPrivs p' $ \p -> do   c <- getClearance   l <- getLabel-  unless (leqp p newl c) $ throwIO LerrClearance+  unless (newl `leq` c)  $ throwIO LerrClearance   unless (leqp p l newl) $ throwIO LerrLow  @@ -914,9 +931,9 @@     -- | Basic function for catching labeled exceptions. (The fact that     -- they are labeled is hidden from the handler.)     ---    -- > catch = catchP NoPrivs+    -- > catch = catchP noPrivs     ---    catch x h = getPrivileges >>= \p -> catchP p x h+    catch = catchP noPrivs   -- | Catches an exception, so long as the label at the point where the@@ -930,16 +947,16 @@        -> (e -> LIO l p s a) -- ^ Exception handler        -> LIO l p s a        -- ^ Result of computation or handler catchP p' io handler = withCombinedPrivs p' $ \p -> do-  s <- get+  s <- getTCB   clr <- getClearance   (a, s') <- ioTCB $ do     (unLIO io s) `catch` (\e@(LabeledExceptionTCB le se) ->       case fromException se of         Nothing -> throwIO e-        Just e' -> if leqp p le clr+        Just e' -> if le `leq` clr                      then unLIO (taintP p le >> handler e') s                      else throwIO e)-  put s'+  putTCB s'   return a  -- | Trusted catch functin.@@ -948,10 +965,10 @@          -> (LabeledException l -> LIO l p s a) -- ^ Exception handler          -> LIO l p s a        -- ^ Result of computation or handler catchTCB io handler = do-  s <- get+  s <- getTCB   (a, s') <- ioTCB $ do     (unLIO io s) `E.catch` (\e -> unLIO (handler e) s)-  put s'+  putTCB s'   return a  -- | Version of 'catchP' with arguments swapped.
System/Posix/Tmp.hsc view
@@ -42,7 +42,7 @@ #endif  #if HAVE_MKSTEMP-foreign import ccall unsafe "HsUnix.h __hscore_mkstemp"+foreign import ccall unsafe "HsUnix.h __hstmp_mkstemp"   c_mkstemp :: CString -> IO CInt #endif @@ -64,7 +64,7 @@ #endif  #if HAVE_MKSTEMPS-foreign import ccall unsafe "HsUnix.h __hscore_mkstemps"+foreign import ccall unsafe "HsUnix.h __hstmp_mkstemps"   c_mkstemps :: CString -> CInt -> IO CInt #endif @@ -92,7 +92,7 @@ #endif  #if HAVE_MKDTEMP-foreign import ccall unsafe "HsUnix.h __hscore_mkdtemp"+foreign import ccall unsafe "HsUnix.h __hstmp_mkdtemp"   c_mkdtemp :: CString -> IO CString #endif 
examples/LambdaChair/AliceCode.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE CPP #-}-#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Safe #-} #endif module AliceCode ( mainReview ) where
examples/LambdaChair/BobCode.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE CPP #-}-#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Safe #-} #endif module BobCode ( mainReview ) where
examples/LambdaChair/LambdaChair.hs view
@@ -26,7 +26,6 @@ import Control.Monad.State import Data.Maybe import Data.List-import Data.Monoid  import LIO.TCB import LIO.LIORef@@ -146,7 +145,7 @@ getPrivs :: ReviewDC DCPrivTCB getPrivs = do    u <- getCurUser-  return $ maybe mempty (genPrivTCB . name) u+  return $ maybe noPrivs (genPrivTCB . name) u  -- ^ Write new users putUsers :: [User] -> ReviewDC ()
examples/LambdaChair/Main.hs view
@@ -1,11 +1,14 @@ {-# LANGUAGE CPP #-}-#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if __GLASGOW_HASKELL__ >= 702 && __GLASGOW_HASKELL__ < 704 {-# LANGUAGE SafeImports #-} #endif+#if __GLASGOW_HASKELL__ >= 704+{-# LANGUAGE Unsafe #-}+#endif import LambdaChair import DCLabel.PrettyShow -#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if __GLASGOW_HASKELL__ >= 702 import safe AliceCode as Alice import safe BobCode as Bob #else
examples/LambdaChair/Safe.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE CPP #-}-#if defined(__GLASGOW_HASKELL__) && (__GLASGOW_HASKELL__ >= 702)+#if __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-} #endif module Safe ( module LambdaChair ) where
lio.cabal view
@@ -1,5 +1,5 @@ Name:           lio-Version:        0.1.1+Version:        0.1.2 build-type:     Simple License:        GPL License-File:   LICENSE