1*ec63e07aSXin Li // Copyright 2019 Google LLC 2*ec63e07aSXin Li // 3*ec63e07aSXin Li // Licensed under the Apache License, Version 2.0 (the "License"); 4*ec63e07aSXin Li // you may not use this file except in compliance with the License. 5*ec63e07aSXin Li // You may obtain a copy of the License at 6*ec63e07aSXin Li // 7*ec63e07aSXin Li // https://www.apache.org/licenses/LICENSE-2.0 8*ec63e07aSXin Li // 9*ec63e07aSXin Li // Unless required by applicable law or agreed to in writing, software 10*ec63e07aSXin Li // distributed under the License is distributed on an "AS IS" BASIS, 11*ec63e07aSXin Li // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*ec63e07aSXin Li // See the License for the specific language governing permissions and 13*ec63e07aSXin Li // limitations under the License. 14*ec63e07aSXin Li 15*ec63e07aSXin Li // The sandbox2::Limits class defined various client- and sandbox- side limits 16*ec63e07aSXin Li // which are applied to the execution process of sandboxees. 17*ec63e07aSXin Li 18*ec63e07aSXin Li #ifndef SANDBOXED_API_SANDBOX2_LIMITS_H_ 19*ec63e07aSXin Li #define SANDBOXED_API_SANDBOX2_LIMITS_H_ 20*ec63e07aSXin Li 21*ec63e07aSXin Li #include <sys/resource.h> 22*ec63e07aSXin Li 23*ec63e07aSXin Li #include <cstdint> 24*ec63e07aSXin Li #include <ctime> 25*ec63e07aSXin Li 26*ec63e07aSXin Li #include "absl/base/macros.h" 27*ec63e07aSXin Li #include "absl/time/time.h" 28*ec63e07aSXin Li 29*ec63e07aSXin Li namespace sandbox2 { 30*ec63e07aSXin Li 31*ec63e07aSXin Li class Limits final { 32*ec63e07aSXin Li public: 33*ec63e07aSXin Li Limits() = default; 34*ec63e07aSXin Li 35*ec63e07aSXin Li Limits(const Limits&) = delete; 36*ec63e07aSXin Li Limits& operator=(const Limits&) = delete; 37*ec63e07aSXin Li 38*ec63e07aSXin Li // rlimits getters/setters. 39*ec63e07aSXin Li // 40*ec63e07aSXin Li // Use RLIM64_INFINITY for unlimited values, but remember that some of those 41*ec63e07aSXin Li // cannot exceed system limits (e.g. RLIMIT_NOFILE). rlimit_as()42*ec63e07aSXin Li const rlimit64& rlimit_as() const { return rlimit_as_; } set_rlimit_as(const rlimit64 & value)43*ec63e07aSXin Li Limits& set_rlimit_as(const rlimit64& value) { 44*ec63e07aSXin Li rlimit_as_ = value; 45*ec63e07aSXin Li return *this; 46*ec63e07aSXin Li } set_rlimit_as(uint64_t value)47*ec63e07aSXin Li Limits& set_rlimit_as(uint64_t value) { 48*ec63e07aSXin Li rlimit_as_ = MakeRlimit64(value); 49*ec63e07aSXin Li return *this; 50*ec63e07aSXin Li } 51*ec63e07aSXin Li rlimit_cpu()52*ec63e07aSXin Li const rlimit64& rlimit_cpu() const { return rlimit_cpu_; } set_rlimit_cpu(const rlimit64 & value)53*ec63e07aSXin Li Limits& set_rlimit_cpu(const rlimit64& value) { 54*ec63e07aSXin Li rlimit_cpu_ = value; 55*ec63e07aSXin Li return *this; 56*ec63e07aSXin Li } set_rlimit_cpu(uint64_t value)57*ec63e07aSXin Li Limits& set_rlimit_cpu(uint64_t value) { 58*ec63e07aSXin Li rlimit_cpu_ = MakeRlimit64(value); 59*ec63e07aSXin Li return *this; 60*ec63e07aSXin Li } 61*ec63e07aSXin Li rlimit_fsize()62*ec63e07aSXin Li const rlimit64& rlimit_fsize() const { return rlimit_fsize_; } set_rlimit_fsize(const rlimit64 & value)63*ec63e07aSXin Li Limits& set_rlimit_fsize(const rlimit64& value) { 64*ec63e07aSXin Li rlimit_fsize_ = value; 65*ec63e07aSXin Li return *this; 66*ec63e07aSXin Li } set_rlimit_fsize(uint64_t value)67*ec63e07aSXin Li Limits& set_rlimit_fsize(uint64_t value) { 68*ec63e07aSXin Li rlimit_fsize_ = MakeRlimit64(value); 69*ec63e07aSXin Li return *this; 70*ec63e07aSXin Li } 71*ec63e07aSXin Li rlimit_nofile()72*ec63e07aSXin Li const rlimit64& rlimit_nofile() const { return rlimit_nofile_; } set_rlimit_nofile(const rlimit64 & value)73*ec63e07aSXin Li Limits& set_rlimit_nofile(const rlimit64& value) { 74*ec63e07aSXin Li rlimit_nofile_ = value; 75*ec63e07aSXin Li return *this; 76*ec63e07aSXin Li } set_rlimit_nofile(uint64_t value)77*ec63e07aSXin Li Limits& set_rlimit_nofile(uint64_t value) { 78*ec63e07aSXin Li rlimit_nofile_ = MakeRlimit64(value); 79*ec63e07aSXin Li return *this; 80*ec63e07aSXin Li } 81*ec63e07aSXin Li rlimit_core()82*ec63e07aSXin Li const rlimit64& rlimit_core() const { return rlimit_core_; } set_rlimit_core(const rlimit64 & value)83*ec63e07aSXin Li Limits& set_rlimit_core(const rlimit64& value) { 84*ec63e07aSXin Li rlimit_core_ = value; 85*ec63e07aSXin Li return *this; 86*ec63e07aSXin Li } set_rlimit_core(uint64_t value)87*ec63e07aSXin Li Limits& set_rlimit_core(uint64_t value) { 88*ec63e07aSXin Li rlimit_core_ = MakeRlimit64(value); 89*ec63e07aSXin Li return *this; 90*ec63e07aSXin Li } 91*ec63e07aSXin Li 92*ec63e07aSXin Li // Sets a wall time limit on an executor before running it. Set to 93*ec63e07aSXin Li // absl::ZeroDuration() to disarm. The walltime limit is a timeout duration 94*ec63e07aSXin Li // (e.g. 10 secs) not a deadline (e.g. 12:00). This can be useful in a simple 95*ec63e07aSXin Li // scenario to set a wall limit before running the sandboxee, run the 96*ec63e07aSXin Li // sandboxee, and expect it to finish within the limit. For an example, see 97*ec63e07aSXin Li // examples/crc4. set_walltime_limit(absl::Duration value)98*ec63e07aSXin Li Limits& set_walltime_limit(absl::Duration value) { 99*ec63e07aSXin Li wall_time_limit_ = value; 100*ec63e07aSXin Li return *this; 101*ec63e07aSXin Li } wall_time_limit()102*ec63e07aSXin Li absl::Duration wall_time_limit() const { return wall_time_limit_; } 103*ec63e07aSXin Li 104*ec63e07aSXin Li private: MakeRlimit64(uint64_t value)105*ec63e07aSXin Li constexpr rlimit64 MakeRlimit64(uint64_t value) { 106*ec63e07aSXin Li return {.rlim_cur = value, .rlim_max = value}; 107*ec63e07aSXin Li } 108*ec63e07aSXin Li 109*ec63e07aSXin Li // Address space size of a process, if big enough (say, above 512M), this 110*ec63e07aSXin Li // will be a rough approximation of the maximum RAM usage by the sandboxed 111*ec63e07aSXin Li // process. 112*ec63e07aSXin Li rlimit64 rlimit_as_ = MakeRlimit64(RLIM64_INFINITY); 113*ec63e07aSXin Li 114*ec63e07aSXin Li // CPU time, measured in seconds. This limit might be triggered faster than 115*ec63e07aSXin Li // the wall-time limit, if many threads are used. 116*ec63e07aSXin Li rlimit64 rlimit_cpu_ = MakeRlimit64(1024 /* seconds */); 117*ec63e07aSXin Li 118*ec63e07aSXin Li // Total number of bytes that can be written to the filesystem by the process 119*ec63e07aSXin Li // (creating empty files is not considered writing). 120*ec63e07aSXin Li rlimit64 rlimit_fsize_ = MakeRlimit64(8ULL << 30 /* 8GiB */); 121*ec63e07aSXin Li 122*ec63e07aSXin Li // Number of NEW file descriptors which can be obtained by a process. 0 123*ec63e07aSXin Li // means that no new descriptors (files, sockets) can be created. 124*ec63e07aSXin Li rlimit64 rlimit_nofile_ = MakeRlimit64(1024); 125*ec63e07aSXin Li 126*ec63e07aSXin Li // Size of a core file which is allowed to be created. The default value of 127*ec63e07aSXin Li // zero disables the creation of core files. Unless you have special 128*ec63e07aSXin Li // requirements, this should not be changed. 129*ec63e07aSXin Li rlimit64 rlimit_core_ = MakeRlimit64(0); 130*ec63e07aSXin Li 131*ec63e07aSXin Li // Wall-time limit (local to Monitor). Depending on the sandboxed load, this 132*ec63e07aSXin Li // one, or RLIMIT_CPU limit might be triggered faster (see 133*ec63e07aSXin Li // https://en.wikipedia.org/wiki/Time_(Unix)#Real_time_vs_CPU_time). 134*ec63e07aSXin Li absl::Duration wall_time_limit_ = absl::Seconds(120); 135*ec63e07aSXin Li }; 136*ec63e07aSXin Li 137*ec63e07aSXin Li } // namespace sandbox2 138*ec63e07aSXin Li 139*ec63e07aSXin Li #endif // SANDBOXED_API_SANDBOX2_LIMITS_H_ 140