8#include "pedigree/kernel/process/Scheduler.h"
9#include "pedigree/kernel/process/Thread.h"
10#include "pedigree/kernel/processor/Processor.h"
11#include "pedigree/kernel/syscallError.h"
13#include "PosixProcess.h"
14#include "PosixSubsystem.h"
15#include "linux-resource-abi.h"
17#include "system-syscalls.h"
18#include "user-namespace.h"
19#include <sys/resource.h>
22bool getRlimitValue(
int resource,
struct rlimit& result) {
26 result.rlim_cur = result.rlim_max = RLIM_INFINITY;
29 result.rlim_cur = result.rlim_max = RLIM_INFINITY;
32 result.rlim_cur = result.rlim_max = RLIM_INFINITY;
35 result.rlim_cur = result.rlim_max = RLIM_INFINITY;
39 result.rlim_max = RLIM_INFINITY;
42 result.rlim_cur = result.rlim_max = 1ULL << 48ULL;
45 result.rlim_cur = result.rlim_max = RLIM_INFINITY;
48 result.rlim_cur = result.rlim_max = 16384;
50 case RLIMIT_MEMLOCK: {
51 GRAB_POSIX_SUBSYSTEM(
false);
53 const auto limit = pSubsystem->memoryLockAccount().limit();
54 result.rlim_cur = limit.current;
55 result.rlim_max = limit.maximum;
59 result.rlim_cur = result.rlim_max = 1ULL << 48ULL;
62 result.rlim_cur = result.rlim_max = 1024;
64 case RLIMIT_SIGPENDING:
65 result.rlim_cur = result.rlim_max = 16;
68 result.rlim_cur = result.rlim_max = 0x100000;
71 result.rlim_cur = result.rlim_max = 1;
74 result.rlim_cur = result.rlim_max = 0;
78 result.rlim_cur = result.rlim_max = RLIM_INFINITY;
82 SYSCALL_ERROR(InvalidArgument);
90 GRAB_POSIX_SUBSYSTEM(-1);
93 auto& account = pSubsystem->memoryLockAccount();
94 const auto old = account.limit();
95 const auto status = account.setLimit(limit, posix_global_capable(PosixCapabilities::SysResource));
96 if (status == PosixMemoryLockAccount::LimitStatus::Invalid) {
97 SYSCALL_ERROR(InvalidArgument);
100 if (status == PosixMemoryLockAccount::LimitStatus::PermissionDenied) {
101 SYSCALL_ERROR(NotEnoughPermissions);
110int posix_getrlimit(
int resource,
struct rlimit* rlim) {
111 SC_NOTICE(
"getrlimit(" <<
Dec << resource <<
")");
113 struct rlimit result = {};
114 if (!getRlimitValue(resource, result)) {
115 SC_NOTICE(
" -> unsupported resource");
120 SYSCALL_ERROR(BadAddress);
124 SC_NOTICE(
" -> cur = " << result.rlim_cur);
125 SC_NOTICE(
" -> max = " << result.rlim_max);
129int posix_setrlimit(
int resource,
const struct rlimit* rlim) {
130 SC_NOTICE(
"setrlimit(" <<
Dec << resource <<
")");
132 if (resource == RLIMIT_MEMLOCK) {
135 SYSCALL_ERROR(BadAddress);
138 return changeMemoryLimit(
139 {
static_cast<uint64_t
>(limit.rlim_cur),
static_cast<uint64_t
>(limit.rlim_max)},
nullptr);
142 struct rlimit current = {};
143 if (!getRlimitValue(resource, current)) {
148 SYSCALL_ERROR(Unimplemented);
153 SC_NOTICE(
"prlimit64(" <<
Dec << pid <<
", " << resource <<
")");
158 SYSCALL_ERROR(NoSuchProcess);
161 if (pid &&
static_cast<size_t>(pid) != current->
getUserspaceId()) {
162 if (!
Scheduler::instance().acquireProcessByUserspaceId(targetLease,
static_cast<size_t>(pid)) ||
163 targetLease->getType() != Process::Posix) {
164 SYSCALL_ERROR(NoSuchProcess);
169 SYSCALL_ERROR(Unimplemented);
173 struct rlimit currentLimit = {};
174 if (!getRlimitValue(resource, currentLimit)) {
178 LinuxRlimit64 previous = {
static_cast<uint64_t
>(currentLimit.rlim_cur),
179 static_cast<uint64_t
>(currentLimit.rlim_max)};
181 if (resource != RLIMIT_MEMLOCK) {
182 SYSCALL_ERROR(Unimplemented);
187 SYSCALL_ERROR(BadAddress);
190 if (changeMemoryLimit(limit, &previous))
197 SYSCALL_ERROR(BadAddress);
Memory-mapped file interface.
static MemoryMapManager & instance()
static bool copyFromUser(void *destination, const void *source, size_t count, size_t elementSize=1)
static bool copyToUser(void *destination, const void *source, size_t count, size_t elementSize=1)
size_t getUserspaceId() const
static ProcessorInformation & information()
static Scheduler & instance()