linux-namespaces 0.1.2.0 → 0.1.3.0
raw patch · 4 files changed
+82/−46 lines, 4 filesdep +bytestringPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: bytestring
API changes (from Hackage documentation)
- System.Linux.Namespaces: instance Bounded Namespace
- System.Linux.Namespaces: instance Enum Namespace
- System.Linux.Namespaces: instance Enum NamespaceID
- System.Linux.Namespaces: instance Eq GroupMapping
- System.Linux.Namespaces: instance Eq Namespace
- System.Linux.Namespaces: instance Eq NamespaceID
- System.Linux.Namespaces: instance Eq UserMapping
- System.Linux.Namespaces: instance Integral NamespaceID
- System.Linux.Namespaces: instance Num NamespaceID
- System.Linux.Namespaces: instance Ord NamespaceID
- System.Linux.Namespaces: instance Read GroupMapping
- System.Linux.Namespaces: instance Read Namespace
- System.Linux.Namespaces: instance Read NamespaceID
- System.Linux.Namespaces: instance Read UserMapping
- System.Linux.Namespaces: instance Real NamespaceID
- System.Linux.Namespaces: instance Show GroupMapping
- System.Linux.Namespaces: instance Show Namespace
- System.Linux.Namespaces: instance Show NamespaceID
- System.Linux.Namespaces: instance Show UserMapping
+ System.Linux.Namespaces: instance GHC.Classes.Eq System.Linux.Namespaces.GroupMapping
+ System.Linux.Namespaces: instance GHC.Classes.Eq System.Linux.Namespaces.Namespace
+ System.Linux.Namespaces: instance GHC.Classes.Eq System.Linux.Namespaces.NamespaceID
+ System.Linux.Namespaces: instance GHC.Classes.Eq System.Linux.Namespaces.UserMapping
+ System.Linux.Namespaces: instance GHC.Classes.Ord System.Linux.Namespaces.NamespaceID
+ System.Linux.Namespaces: instance GHC.Enum.Bounded System.Linux.Namespaces.Namespace
+ System.Linux.Namespaces: instance GHC.Enum.Enum System.Linux.Namespaces.Namespace
+ System.Linux.Namespaces: instance GHC.Enum.Enum System.Linux.Namespaces.NamespaceID
+ System.Linux.Namespaces: instance GHC.Num.Num System.Linux.Namespaces.NamespaceID
+ System.Linux.Namespaces: instance GHC.Read.Read System.Linux.Namespaces.GroupMapping
+ System.Linux.Namespaces: instance GHC.Read.Read System.Linux.Namespaces.Namespace
+ System.Linux.Namespaces: instance GHC.Read.Read System.Linux.Namespaces.NamespaceID
+ System.Linux.Namespaces: instance GHC.Read.Read System.Linux.Namespaces.UserMapping
+ System.Linux.Namespaces: instance GHC.Real.Integral System.Linux.Namespaces.NamespaceID
+ System.Linux.Namespaces: instance GHC.Real.Real System.Linux.Namespaces.NamespaceID
+ System.Linux.Namespaces: instance GHC.Show.Show System.Linux.Namespaces.GroupMapping
+ System.Linux.Namespaces: instance GHC.Show.Show System.Linux.Namespaces.Namespace
+ System.Linux.Namespaces: instance GHC.Show.Show System.Linux.Namespaces.NamespaceID
+ System.Linux.Namespaces: instance GHC.Show.Show System.Linux.Namespaces.UserMapping
- System.Linux.Namespaces: writeGroupMappings :: Maybe ProcessID -> [GroupMapping] -> IO ()
+ System.Linux.Namespaces: writeGroupMappings :: Maybe ProcessID -> [GroupMapping] -> Bool -> IO ()
Files
- ChangeLog +0/−11
- ChangeLog.md +16/−0
- System/Linux/Namespaces.hsc +62/−31
- linux-namespaces.cabal +4/−4
− ChangeLog
@@ -1,11 +0,0 @@-v0.1.2.0-- * Provide Read instances for UserMapping & GroupMapping.--v0.1.1.1-- * Improve documentation.--v0.1.1.0-- * Export data constructors for UserMapping & GroupMapping.
+ ChangeLog.md view
@@ -0,0 +1,16 @@+#### 0.1.3.0 *2018-06-21*++ * Use raw POSIX io to write to proc files (Baojun Wang).+ * Support denying setgroups to processes in user namespaces, needed to support unprivileged creation of user namespaces (Baojun Wang).++#### 0.1.2.0 *2014-10-30*++ * Provide Read instances for UserMapping & GroupMapping.++#### 0.1.1.1 *2014-10-30*++ * Improve documentation.++#### 0.1.1.0 *2014-10-29*++ * Export data constructors for UserMapping & GroupMapping.
System/Linux/Namespaces.hsc view
@@ -5,21 +5,24 @@ Portability : non-portable (requires Linux) This module provides bindings to the @unshare(2)@ and @setns(2)@ linux-system calls. These functions can be used to create new namespaces by-detaching the current process from its current namespaces, or to move-the current process to an already existing namespace. Note that linux-also provides the @clone(2)@ function which can be used to create new-namespaces, but we do not support this function in this module; the way-this function works makes it hard to use it from haskell as it interacts-badly with GHC'c RTS.+system calls. The former can be used to create new namespaces and move+the calling process to them, whereas the latter can be used to move the+calling process to an already existing namespace created by some other+process. +Note that linux provides another function related to namespaces which is+not supported by this module: @clone(2)@. This function works like+@fork(2)@ and is used to create new namespaces (like @unshare(2)@).+Unfortunately, like @fork(2)@, it does not interact well with GHC'c RTS+which is why it has been omitted from this module.+ /Note/: Using this module in a program that uses the threaded RTS does not make much sense. Namespaces are per process/thread and manipulating them in one thread will not affect the namespaces of the other threads of the same process. The threaded RTS makes it is hard to predict what OS thread will be used to run the haskell threads. Therefore, using this module in such applications will result in unpredictable behavior.-Similarly, using this module in @ghci@ is also problematic.+Similarly, using this module in @ghci@ is problematic too. -} {-# LANGUAGE GeneralizedNewtypeDeriving #-}@@ -58,6 +61,11 @@ import Data.List (foldl') import Data.Char (isDigit) import Control.Arrow (first)+import Control.Monad (when)+import qualified Data.ByteString.Char8 as C+import qualified Data.ByteString as S+import Data.ByteString (ByteString)+import System.IO.Error (modifyIOError, ioeSetLocation) -------------------------------------------------------------------------------- @@ -93,15 +101,15 @@ where flags = foldl' (.|.) 0 (map toCloneFlags nss) --- | Move process to an already existing namespace. See the man page of--- @setns(2)@ for more details. See also 'enterNamespace' for a slightly--- higher level version of this function.+-- | Move the process to an already existing namespace. See the man page+-- of @setns(2)@ for more details. See also 'enterNamespace' for a+-- slightly higher level version of this function. setNamespace :: Fd -- ^ A file descriptor referring to a namespace file in a -- @\/proc\/[pid]\/ns\/@ directory. -> Maybe Namespace -- ^ Specify the namespace type that the file -- descriptor must refer to. If the two types do not- -- much, the function will fail. Use 'Nothing' to+ -- match, the function will fail. Use 'Nothing' to -- allow any type. -> IO () setNamespace fd mns =@@ -111,9 +119,8 @@ -------------------------------------------------------------------------------- --- | Move process to an already existing namespace. This is a wrapper--- around 'setNamespace'. This function requires @\/proc@ to be--- mounted.+-- | Move the process to an already existing namespace. This is a wrapper+-- around 'setNamespace'. This function requires @\/proc@ to be mounted. enterNamespace :: ProcessID -- ^ The @pid@ of any process in the target namespace. -> Namespace -- ^ The type of the namespace.@@ -122,7 +129,8 @@ bracket openFd' closeFd $ \fd -> setNamespace fd (Just ns) where- openFd' = openFd path ReadOnly Nothing defaultFileFlags {nonBlock = True}+ openFd' = ioeSetLoc "enterNamespace" $+ openFd path ReadOnly Nothing defaultFileFlags {nonBlock = True} path = toProcPath (Just pid) ns -- | A unique namespace id.@@ -137,9 +145,14 @@ -- | Retrieve the id of a Namespace. Useful for debugging. This -- function requires @\/proc@ to be mounted.-getNamespaceID :: Maybe ProcessID -> Namespace -> IO NamespaceID+getNamespaceID+ :: Maybe ProcessID -- ^ The @pid@ of any process in the target+ -- namespace. Use 'Nothing' for the namespace+ -- of the calling process.+ -> Namespace -- ^ The type of the namespace.+ -> IO NamespaceID getNamespaceID mpid ns = do- s <- readSymbolicLink path+ s <- ioeSetLoc "getNamespaceID" $ readSymbolicLink path let s' = takeWhile isDigit $ dropWhile (not . isDigit) s return (read s') where@@ -161,13 +174,14 @@ -- function requires @\/proc@ to be mounted. See @user_namespaces(7)@ -- for more details. writeUserMappings- :: Maybe ProcessID -- ^ The pid of any process in the target user- -- namespace. 'Nothing' means use the current- -- process.- -> [UserMapping] -- The mappings.+ :: Maybe ProcessID -- ^ The @pid@ of any process in the target user+ -- namespace. Use 'Nothing' for the namespace+ -- of the calling process.+ -> [UserMapping] -- ^ The mappings. -> IO () writeUserMappings mpid ms =- writeFile path s+ ioeSetLoc "writeUserMappings" $+ writeProcFile path (C.pack s) where path = toProcDir mpid ++ "/uid_map" s = concatMap toStr ms@@ -177,20 +191,34 @@ -- function requires @\/proc@ to be mounted. See @user_namespaces(7)@ -- for more details. writeGroupMappings- :: Maybe ProcessID -- ^ The pid of any process in the target user- -- namespace. 'Nothing' means use the current- -- process.- -> [GroupMapping] -- The mappings.+ :: Maybe ProcessID -- ^ The @pid@ of any process in the target user+ -- namespace. Use 'Nothing' for the namespace+ -- of the calling process.+ -> [GroupMapping] -- ^ The mappings.+ -> Bool -- ^ Prevent processes in the child user namespace+ -- from calling @setgroups@. This is needed if the+ -- calling process does not have the @CAP_SETGID@+ -- capability in the parent namespace. -> IO ()-writeGroupMappings mpid ms =- writeFile path s+writeGroupMappings mpid ms denySetgroups =+ ioeSetLoc "writeGroupMappings" $ do+ when denySetgroups $+ writeProcFile (dir ++ "/setgroups") (C.pack "deny")+ writeProcFile (dir ++ "/gid_map") (C.pack s) where- path = toProcDir mpid ++ "/gid_map"+ dir = toProcDir mpid s = concatMap toStr ms- toStr (GroupMapping o i l) = show o ++ " " ++ show i ++ " " ++ show l ++ "\n"+ toStr (GroupMapping o i l) =+ show o ++ " " ++ show i ++ " " ++ show l ++ "\n" -------------------------------------------------------------------------------- +writeProcFile :: FilePath -> ByteString -> IO ()+writeProcFile path bs =+ bracket (openFd path WriteOnly Nothing defaultFileFlags) closeFd $ \fd ->+ S.useAsCStringLen bs $ \(ptr, nb) ->+ fdWriteBuf fd (castPtr ptr) (fromIntegral nb) >> return ()+ toProcPath :: Maybe ProcessID -> Namespace -> String toProcPath mpid ns = toProcDir mpid ++ "/ns/" ++ toProcName ns {-# INLINE toProcPath #-}@@ -198,6 +226,9 @@ toProcDir :: Maybe ProcessID -> String toProcDir mpid = "/proc/" ++ maybe "self" show mpid {-# INLINE toProcDir #-}++ioeSetLoc :: String -> IO r -> IO r+ioeSetLoc loc = modifyIOError (flip ioeSetLocation loc) --------------------------------------------------------------------------------
linux-namespaces.cabal view
@@ -1,6 +1,6 @@ name: linux-namespaces-version: 0.1.2.0-synopsis: Create new or enter an existing linux namespaces+version: 0.1.3.0+synopsis: Work with linux namespaces: create new or enter existing ones description: This library provides bindings to the @unshare(2)@ and @setns(2)@ linux system calls.@@ -15,7 +15,7 @@ cabal-version: >=1.10 extra-source-files:- ChangeLog+ ChangeLog.md source-repository head type: git@@ -23,7 +23,7 @@ library exposed-modules: System.Linux.Namespaces- build-depends: base >=4.6 && <5, unix >=2.6+ build-depends: base >=4.6 && <5, unix >=2.6, bytestring >=0.10 build-tools: hsc2hs default-language: Haskell2010 ghc-options: -Wall