module Mueval.Resources (limitResources) where import Control.Monad (when) import System.Posix.Process (nice) import System.Posix.Resource -- (Resource(..), ResourceLimits, setResourceLimit) -- | Pull together several methods of reducing priority and easy access to resources: -- 'nice', and the rlimit bindings, -- If called with False, 'limitResources' will not use POSIX rlimits. limitResources :: Bool -> IO () limitResources rlimit = do nice 20 -- Set our process priority way down when rlimit $ mapM_ (uncurry setResourceLimit) limits -- | Set all the available rlimits. -- These values have been determined through trial-and-error stackSizeLimitSoft, stackSizeLimitHard, totalMemoryLimitSoft, totalMemoryLimitHard, dataSizeLimitSoft, openFilesLimitSoft, openFilesLimitHard, fileSizeLimitSoft, fileSizeLimitHard, dataSizeLimitHard, cpuTimeLimitSoft, cpuTimeLimitHard, coreSizeLimitSoft, coreSizeLimitHard, zero :: ResourceLimit totalMemoryLimitSoft = dataSizeLimitSoft totalMemoryLimitHard = dataSizeLimitHard -- These limits seem to be useless? stackSizeLimitSoft = zero stackSizeLimitHard = zero -- We allow a few files to be opened, such as package.conf, because they are necessary. This -- doesn't seem to be security problem because it'll be opened at the module -- stage, before code ever evaluates. I hope. openFilesLimitSoft = openFilesLimitHard openFilesLimitHard = ResourceLimit 7 -- TODO: It would be nice to set these to zero, but right now Hint gets around the -- insecurity of the GHC API by writing stuff out to a file in /tmp, so we need -- to allow our compiled binary to do file I/O... :( But at least we can still limit -- how much we write out! fileSizeLimitSoft = fileSizeLimitHard fileSizeLimitHard = ResourceLimit 10800 dataSizeLimitSoft = dataSizeLimitHard dataSizeLimitHard = ResourceLimit $ 6^(12::Int) -- These should not be identical, to give the XCPU handler time to trigger cpuTimeLimitSoft = ResourceLimit 4 cpuTimeLimitHard = ResourceLimit 5 coreSizeLimitSoft = coreSizeLimitHard coreSizeLimitHard = zero -- convenience zero = ResourceLimit 0 limits :: [(Resource, ResourceLimits)] limits = [ (ResourceStackSize, ResourceLimits stackSizeLimitSoft stackSizeLimitHard) , (ResourceTotalMemory, ResourceLimits totalMemoryLimitSoft totalMemoryLimitHard) , (ResourceOpenFiles, ResourceLimits openFilesLimitSoft openFilesLimitHard) , (ResourceFileSize, ResourceLimits fileSizeLimitSoft fileSizeLimitHard) , (ResourceDataSize, ResourceLimits dataSizeLimitSoft dataSizeLimitHard) , (ResourceCoreFileSize, ResourceLimits coreSizeLimitSoft coreSizeLimitHard) , (ResourceCPUTime, ResourceLimits cpuTimeLimitSoft cpuTimeLimitHard)]