mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
5aa13876a4
PiperOrigin-RevId: 239159980 Change-Id: Ic6185368392622bf3f4c661e37f6b9fcca0d60a6
157 lines
5.3 KiB
C++
157 lines
5.3 KiB
C++
// Copyright 2019 Google LLC. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
// The sandbox2::Limits class defined various client- and sandbox- side limits
|
|
// which are applied to the execution process of sandboxees.
|
|
|
|
#ifndef SANDBOXED_API_SANDBOX2_LIMITS_H_
|
|
#define SANDBOXED_API_SANDBOX2_LIMITS_H_
|
|
|
|
#include <sys/resource.h>
|
|
#include <cstdint>
|
|
#include <ctime>
|
|
|
|
#include "absl/base/macros.h"
|
|
#include "absl/time/time.h"
|
|
|
|
namespace sandbox2 {
|
|
|
|
class Limits final {
|
|
public:
|
|
Limits() {
|
|
set_rlimit_as(kIniRLimAS);
|
|
set_rlimit_cpu(kIniRLimCPU);
|
|
set_rlimit_fsize(kIniRLimFSIZE);
|
|
set_rlimit_nofile(kIniRLimNOFILE);
|
|
set_rlimit_core(kIniRLimCORE);
|
|
set_walltime_limit(absl::Seconds(kIniWallTimeLimit));
|
|
}
|
|
|
|
Limits(const Limits&) = delete;
|
|
Limits& operator=(const Limits&) = delete;
|
|
|
|
// Rlimit-s getters/setters.
|
|
//
|
|
// Use RLIM64_INFINITY for unlimited values, but remember that some of those
|
|
// cannot exceed system limits (e.g. RLIMIT_NOFILE).
|
|
const rlimit64& rlimit_as() const { return rlimit_as_; }
|
|
Limits& set_rlimit_as(const rlimit64& value) {
|
|
rlimit_as_ = value;
|
|
return *this;
|
|
}
|
|
Limits& set_rlimit_as(uint64_t value) {
|
|
rlimit_as_.rlim_cur = value;
|
|
rlimit_as_.rlim_max = value;
|
|
return *this;
|
|
}
|
|
|
|
const rlimit64& rlimit_cpu() const { return rlimit_cpu_; }
|
|
Limits& set_rlimit_cpu(const rlimit64& value) {
|
|
rlimit_cpu_ = value;
|
|
return *this;
|
|
}
|
|
Limits& set_rlimit_cpu(uint64_t value) {
|
|
rlimit_cpu_.rlim_cur = value;
|
|
rlimit_cpu_.rlim_max = value;
|
|
return *this;
|
|
}
|
|
|
|
const rlimit64& rlimit_fsize() const { return rlimit_fsize_; }
|
|
Limits& set_rlimit_fsize(const rlimit64& value) {
|
|
rlimit_fsize_ = value;
|
|
return *this;
|
|
}
|
|
Limits& set_rlimit_fsize(uint64_t value) {
|
|
rlimit_fsize_.rlim_cur = value;
|
|
rlimit_fsize_.rlim_max = value;
|
|
return *this;
|
|
}
|
|
|
|
const rlimit64& rlimit_nofile() const { return rlimit_nofile_; }
|
|
Limits& set_rlimit_nofile(const rlimit64& value) {
|
|
rlimit_nofile_ = value;
|
|
return *this;
|
|
}
|
|
Limits& set_rlimit_nofile(uint64_t value) {
|
|
rlimit_nofile_.rlim_cur = value;
|
|
rlimit_nofile_.rlim_max = value;
|
|
return *this;
|
|
}
|
|
|
|
const rlimit64& rlimit_core() const { return rlimit_core_; }
|
|
Limits& set_rlimit_core(const rlimit64& value) {
|
|
rlimit_core_ = value;
|
|
return *this;
|
|
}
|
|
Limits& set_rlimit_core(uint64_t value) {
|
|
rlimit_core_.rlim_cur = value;
|
|
rlimit_core_.rlim_max = value;
|
|
return *this;
|
|
}
|
|
|
|
// Sets a wall time limit on an executor before running it. Set to
|
|
// absl::ZeroDuration() to disarm. The walltime limit is a timeout duration
|
|
// (e.g. 10 secs) not a deadline (e.g. 12:00). This can be useful in a simple
|
|
// scenario to set a wall limit before running the sandboxee, run the
|
|
// sandboxee, and expect it to finish within the limit. For an example, see
|
|
// examples/crc4.
|
|
Limits& set_walltime_limit(absl::Duration value) {
|
|
wall_time_limit_ = value;
|
|
return *this;
|
|
}
|
|
absl::Duration wall_time_limit() const { return wall_time_limit_; }
|
|
|
|
private:
|
|
// Initial values for limits. Fields of rlimit64 are defined as __u64,
|
|
// so we use uint64_t here.
|
|
static constexpr uint64_t kIniRLimAS = RLIM64_INFINITY;
|
|
// 1024 seconds of real CPU time for each sandboxed process.
|
|
static constexpr uint64_t kIniRLimCPU = (1ULL << 10);
|
|
// 8GiB - Maximum size of individual files that can be created by each
|
|
// sandboxed process.
|
|
static constexpr uint64_t kIniRLimFSIZE = (8ULL << 30);
|
|
// 1024 file descriptors which can be used by each sandboxed process.
|
|
static constexpr uint64_t kIniRLimNOFILE = (1ULL << 10);
|
|
// No core files are allowed by default
|
|
static constexpr uint64_t kIniRLimCORE = (0);
|
|
// 120s - this is wall-time limit. Depending on the sandboxed load, this one,
|
|
// or the RLIMIT_CPU limit might be triggered faster
|
|
// cf. (https://en.wikipedia.org/wiki/Time_(Unix)#Real_time_vs_CPU_time)
|
|
static constexpr time_t kIniWallTimeLimit = (120ULL);
|
|
|
|
// Address space size of a process, if big enough (say, above 512M), it's a
|
|
// crude representation of maximum RAM size used by the sandboxed process.
|
|
rlimit64 rlimit_as_;
|
|
// CPU time, might be triggered faster than the wall-time limit, if many
|
|
// threads are used.
|
|
rlimit64 rlimit_cpu_;
|
|
// Number of bytes which can be written to the FS by the process (just
|
|
// creating empty files is always allowed).
|
|
rlimit64 rlimit_fsize_;
|
|
// Number of NEW file descriptors which can be obtained by a process. 0
|
|
// means that no new descriptors (files, sockets) can be created.
|
|
rlimit64 rlimit_nofile_;
|
|
// Size of a core file which is allowed to be created. Should be 0, unless
|
|
// you know what you are doing.
|
|
rlimit64 rlimit_core_;
|
|
// Getter for the client_limits_ structure.
|
|
|
|
// Wall-time limit (local to Monitor).
|
|
absl::Duration wall_time_limit_;
|
|
};
|
|
|
|
} // namespace sandbox2
|
|
|
|
#endif // SANDBOXED_API_SANDBOX2_LIMITS_H_
|