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