diff --git a/landlock/CHANGELOG.md b/landlock/CHANGELOG.md index 23c6c54..3126335 100644 --- a/landlock/CHANGELOG.md +++ b/landlock/CHANGELOG.md @@ -14,6 +14,10 @@ * Support `filepath ^>=1.5`. +* Properly zero-out structs after allocation. + +* Update `landlock.h` to Linux 6.8. + ## 0.2.1.1 -- 2023-02-28 * Extend API documentation with links to man-pages. diff --git a/landlock/cbits/linux/landlock.h b/landlock/cbits/linux/landlock.h index f3223f9..25c8d76 100644 --- a/landlock/cbits/linux/landlock.h +++ b/landlock/cbits/linux/landlock.h @@ -31,6 +31,12 @@ struct landlock_ruleset_attr { * this access right. */ __u64 handled_access_fs; + /** + * @handled_access_net: Bitmask of actions (cf. `Network flags`_) + * that is handled by this ruleset and should then be forbidden if no + * rule explicitly allow them. + */ + __u64 handled_access_net; }; /* @@ -54,6 +60,11 @@ enum landlock_rule_type { * landlock_path_beneath_attr . */ LANDLOCK_RULE_PATH_BENEATH = 1, + /** + * @LANDLOCK_RULE_NET_PORT: Type of a &struct + * landlock_net_port_attr . + */ + LANDLOCK_RULE_NET_PORT, }; /** @@ -79,6 +90,31 @@ struct landlock_path_beneath_attr { */ } __attribute__((packed)); +/** + * struct landlock_net_port_attr - Network port definition + * + * Argument of sys_landlock_add_rule(). + */ +struct landlock_net_port_attr { + /** + * @allowed_access: Bitmask of allowed access network for a port + * (cf. `Network flags`_). + */ + __u64 allowed_access; + /** + * @port: Network port in host endianness. + * + * It should be noted that port 0 passed to :manpage:`bind(2)` will + * bind to an available port from a specific port range. This can be + * configured thanks to the ``/proc/sys/net/ipv4/ip_local_port_range`` + * sysctl (also used for IPv6). A Landlock rule with port 0 and the + * ``LANDLOCK_ACCESS_NET_BIND_TCP`` right means that requesting to bind + * on port 0 is allowed and it will automatically translate to binding + * on the related port range. + */ + __u64 port; +}; + /** * DOC: fs_access * @@ -130,21 +166,37 @@ struct landlock_path_beneath_attr { * - %LANDLOCK_ACCESS_FS_MAKE_BLOCK: Create (or rename or link) a block device. * - %LANDLOCK_ACCESS_FS_MAKE_SYM: Create (or rename or link) a symbolic link. * - %LANDLOCK_ACCESS_FS_REFER: Link or rename a file from or to a different - * directory (i.e. reparent a file hierarchy). This access right is - * available since the second version of the Landlock ABI. This is also the - * only access right which is always considered handled by any ruleset in - * such a way that reparenting a file hierarchy is always denied by default. - * To avoid privilege escalation, it is not enough to add a rule with this - * access right. When linking or renaming a file, the destination directory - * hierarchy must also always have the same or a superset of restrictions of - * the source hierarchy. If it is not the case, or if the domain doesn't - * handle this access right, such actions are denied by default with errno - * set to ``EXDEV``. Linking also requires a ``LANDLOCK_ACCESS_FS_MAKE_*`` - * access right on the destination directory, and renaming also requires a - * ``LANDLOCK_ACCESS_FS_REMOVE_*`` access right on the source's (file or - * directory) parent. Otherwise, such actions are denied with errno set to - * ``EACCES``. The ``EACCES`` errno prevails over ``EXDEV`` to let user space - * efficiently deal with an unrecoverable error. + * directory (i.e. reparent a file hierarchy). + * + * This access right is available since the second version of the Landlock + * ABI. + * + * This is the only access right which is denied by default by any ruleset, + * even if the right is not specified as handled at ruleset creation time. + * The only way to make a ruleset grant this right is to explicitly allow it + * for a specific directory by adding a matching rule to the ruleset. + * + * In particular, when using the first Landlock ABI version, Landlock will + * always deny attempts to reparent files between different directories. + * + * In addition to the source and destination directories having the + * %LANDLOCK_ACCESS_FS_REFER access right, the attempted link or rename + * operation must meet the following constraints: + * + * * The reparented file may not gain more access rights in the destination + * directory than it previously had in the source directory. If this is + * attempted, the operation results in an ``EXDEV`` error. + * + * * When linking or renaming, the ``LANDLOCK_ACCESS_FS_MAKE_*`` right for the + * respective file type must be granted for the destination directory. + * Otherwise, the operation results in an ``EACCES`` error. + * + * * When renaming, the ``LANDLOCK_ACCESS_FS_REMOVE_*`` right for the + * respective file type must be granted for the source directory. Otherwise, + * the operation results in an ``EACCES`` error. + * + * If multiple requirements are not met, the ``EACCES`` error code takes + * precedence over ``EXDEV``. * * .. warning:: * @@ -173,4 +225,23 @@ struct landlock_path_beneath_attr { #define LANDLOCK_ACCESS_FS_TRUNCATE (1ULL << 14) /* clang-format on */ +/** + * DOC: net_access + * + * Network flags + * ~~~~~~~~~~~~~~~~ + * + * These flags enable to restrict a sandboxed process to a set of network + * actions. This is supported since the Landlock ABI version 4. + * + * TCP sockets with allowed actions: + * + * - %LANDLOCK_ACCESS_NET_BIND_TCP: Bind a TCP socket to a local port. + * - %LANDLOCK_ACCESS_NET_CONNECT_TCP: Connect an active TCP socket to + * a remote port. + */ +/* clang-format off */ +#define LANDLOCK_ACCESS_NET_BIND_TCP (1ULL << 0) +#define LANDLOCK_ACCESS_NET_CONNECT_TCP (1ULL << 1) +/* clang-format on */ #endif /* _UAPI_LINUX_LANDLOCK_H */ diff --git a/landlock/internal/System/Landlock/Flags.hs b/landlock/internal/System/Landlock/Flags.hs index 584a266..c3134cf 100644 --- a/landlock/internal/System/Landlock/Flags.hs +++ b/landlock/internal/System/Landlock/Flags.hs @@ -142,27 +142,38 @@ data AccessFsFlag -- ([@LANDLOCK_ACCESS_FS_MAKE_SYM@](https://man.archlinux.org/man/landlock.7.en#LANDLOCK_ACCESS_FS_MAKE_SYM)). AccessFsMakeSym | -- | Link or rename a file from or to a different - -- directory (i.e. reparent a file hierarchy). This access right is - -- available since the second version of the Landlock ABI. This is also the - -- only access right which is always considered handled by any ruleset in - -- such a way that reparenting a file hierarchy is always denied by default. - -- To avoid privilege escalation, it is not enough to add a rule with this - -- access right. When linking or renaming a file, the destination directory - -- hierarchy must also always have the same or a superset of restrictions of - -- the source hierarchy. If it is not the case, or if the domain doesn't - -- handle this access right, such actions are denied by default with - -- [@errno@](https://man.archlinux.org/man/errno.3) - -- set to [@EXDEV@](https://man.archlinux.org/man/errno.3#EXDEV). Linking - -- also requires a @LANDLOCK_ACCESS_FS_MAKE_*@ access right on the - -- destination directory, and renaming also requires a - -- @LANDLOCK_ACCESS_FS_REMOVE_*@ access right on the source's (file or - -- directory) parent. Otherwise, such actions are denied with - -- [@errno@](https://man.archlinux.org/man/errno.3) set to - -- [@EACCES@](https://man.archlinux.org/man/errno.3#EACCES). - -- The [@EACCES@](https://man.archlinux.org/man/errno.3#EACCES) - -- [@errno@](https://man.archlinux.org/man/errno.3) prevails over - -- [@EXDEV@](https://man.archlinux.org/man/errno.3#EXDEV) to let user - -- space efficiently deal with an unrecoverable error. + -- directory (i.e. reparent a file hierarchy) + -- ([@LANDLOCK_ACCESS_FS_REFER@](https://man.archlinux.org/man/landlock.7.en#LANDLOCK_ACCESS_FS_REFER)). + -- + -- This access right is available since the second version of the Landlock + -- ABI. + -- + -- This is the only access right which is denied by default by any ruleset, + -- even if the right is not specified as handled at ruleset creation time. + -- The only way to make a ruleset grant this right is to explicitly allow it + -- for a specific directory by adding a matching rule to the ruleset. + -- + -- In particular, when using the first Landlock ABI version, Landlock will + -- always deny attempts to reparent files between different directories. + -- + -- In addition to the source and destination directories having the + -- @LANDLOCK_ACCESS_FS_REFER@ access right, the attempted link or rename + -- operation must meet the following constraints: + -- + -- * The reparented file may not gain more access rights in the destination + -- directory than it previously had in the source directory. If this is + -- attempted, the operation results in an [@EXDEV@](https://man.archlinux.org/man/errno.3#EXDEV) error. + -- + -- * When linking or renaming, the @LANDLOCK_ACCESS_FS_MAKE_*@ right for the + -- respective file type must be granted for the destination directory. + -- Otherwise, the operation results in an [@EACCES@](https://man.archlinux.org/man/errno.3#EACCES) error. + -- + -- * When renaming, the @LANDLOCK_ACCESS_FS_REMOVE_*@ right for the + -- respective file type must be granted for the source directory. Otherwise, + -- the operation results in an [@EACCES@](https://man.archlinux.org/man/errno.3#EACCES) error. + -- + -- If multiple requirements are not met, the [@EACCES@](https://man.archlinux.org/man/errno.3#EACCES) error code takes + -- precedence over [@EXDEV@](https://man.archlinux.org/man/errno.3#EXDEV). AccessFsRefer | -- | Truncate a file with -- [@truncate@](https://man.archlinux.org/man/truncate.2), diff --git a/landlock/src/System/Landlock.hs b/landlock/src/System/Landlock.hs index e09e7cd..628735d 100644 --- a/landlock/src/System/Landlock.hs +++ b/landlock/src/System/Landlock.hs @@ -77,9 +77,10 @@ import Control.Exception.Base (handleJust) import Control.Monad (void) import Control.Monad.Catch (MonadMask, bracket) import Control.Monad.IO.Class (MonadIO, liftIO) -import Foreign.Marshal.Utils (with) -import Foreign.Ptr (nullPtr) -import Foreign.Storable (Storable, sizeOf) +import Foreign.Marshal.Alloc (alloca) +import Foreign.Marshal.Utils (fillBytes) +import Foreign.Ptr (Ptr, nullPtr) +import Foreign.Storable (Storable, poke, sizeOf) import GHC.IO.Exception (IOErrorType (UnsupportedOperation)) import System.IO.Error (ioeGetErrorType) import System.Landlock.Flags @@ -115,6 +116,15 @@ import System.Landlock.Version (Version (..), version1, version2, version3) import System.Posix.IO (closeFd) import System.Posix.Types (Fd) +-- Like @Foreign.Marshal.Utils.with@, but zeros out the memory first +with0 :: (Storable a) => a -> (Ptr a -> IO b) -> IO b +with0 val f = + alloca $ \ptr -> do + let len = sizeOf val + fillBytes ptr 0 len + poke ptr val + f ptr + -- | Retrieve the Landlock ABI version of the running system. -- -- This invokes @@ -166,7 +176,7 @@ newtype LandlockFd = LandlockFd {unLandlockFd :: Fd} deriving (Show, Eq) createRuleset :: RulesetAttr -> [CreateRulesetFlag] -> IO LandlockFd -createRuleset attr flags = with attr' $ \attrp -> +createRuleset attr flags = with0 attr' $ \attrp -> wrap <$> landlock_create_ruleset attrp (fromIntegral $ sizeOf attr') flags' where wrap = LandlockFd . fromIntegral @@ -244,7 +254,7 @@ addRule :: [AddRuleFlag] -> m () addRule fd rule flags = liftIO $ - with rule $ \ruleAttrp -> + with0 rule $ \ruleAttrp -> landlock_add_rule (fromIntegral $ unLandlockFd fd) (ruleType rule)