mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-27 23:14:38 +00:00
linux: Fix broken process limits implementation
This commit is contained in:
parent
02cf233534
commit
93e8e3f354
@ -451,6 +451,7 @@ namespace Tasking
|
|||||||
bool IsCritical = false;
|
bool IsCritical = false;
|
||||||
bool IsDebugEnabled = false;
|
bool IsDebugEnabled = false;
|
||||||
bool IsKernelDebugEnabled = false;
|
bool IsKernelDebugEnabled = false;
|
||||||
|
bool CanAdjustHardLimits = false;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint16_t UserID = UINT16_MAX;
|
uint16_t UserID = UINT16_MAX;
|
||||||
@ -460,11 +461,17 @@ namespace Tasking
|
|||||||
pid_t SessionID = 0;
|
pid_t SessionID = 0;
|
||||||
} Security{};
|
} Security{};
|
||||||
struct
|
struct
|
||||||
|
{
|
||||||
|
rlim_t OpenFiles = 128;
|
||||||
|
rlim_t Threads = 64;
|
||||||
|
rlim_t Memory = 1073741824; /* 1 GiB */
|
||||||
|
} SoftLimits{};
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
rlim_t OpenFiles = 4096;
|
rlim_t OpenFiles = 4096;
|
||||||
rlim_t Threads = 1024;
|
rlim_t Threads = 1024;
|
||||||
rlim_t Memory = 8589934592; /* 8 GiB */
|
rlim_t Memory = 8589934592; /* 8 GiB */
|
||||||
} Limits{};
|
} HardLimits{};
|
||||||
TaskInfo Info{};
|
TaskInfo Info{};
|
||||||
ThreadLocalStorage TLS{};
|
ThreadLocalStorage TLS{};
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ namespace vfs
|
|||||||
{
|
{
|
||||||
Tasking::PCB *pcb = thisProcess;
|
Tasking::PCB *pcb = thisProcess;
|
||||||
|
|
||||||
for (size_t i = 0; i < pcb->Limits.OpenFiles; i++)
|
for (size_t i = 0; i < pcb->SoftLimits.OpenFiles; i++)
|
||||||
{
|
{
|
||||||
auto it = this->FileMap.find(i);
|
auto it = this->FileMap.find(i);
|
||||||
if (it == this->FileMap.end())
|
if (it == this->FileMap.end())
|
||||||
|
@ -2687,30 +2687,32 @@ static int linux_prlimit64(SysFrm *, pid_t pid, int resource,
|
|||||||
{
|
{
|
||||||
static_assert(sizeof(struct rlimit) < PAGE_SIZE);
|
static_assert(sizeof(struct rlimit) < PAGE_SIZE);
|
||||||
|
|
||||||
PCB *pcb = thisProcess;
|
PCB *pcb = nullptr;
|
||||||
Memory::VirtualMemoryArea *vma = pcb->vma;
|
if (likely(pid == 0))
|
||||||
|
pcb = thisProcess;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pcb = thisProcess->GetContext()->GetProcessByID(pid);
|
||||||
|
if (pcb == nullptr)
|
||||||
|
return -linux_ESRCH;
|
||||||
|
|
||||||
|
fixme("implement CAP_SYS_RESOURCE");
|
||||||
|
return -linux_EPERM;
|
||||||
|
}
|
||||||
|
Memory::VirtualMemoryArea *vma = thisProcess->vma;
|
||||||
|
|
||||||
auto pOldLimit = vma->UserCheckAndGetAddress(old_limit);
|
auto pOldLimit = vma->UserCheckAndGetAddress(old_limit);
|
||||||
auto pNewLimit = vma->UserCheckAndGetAddress(new_limit);
|
auto pNewLimit = vma->UserCheckAndGetAddress(new_limit);
|
||||||
if (pOldLimit == nullptr && old_limit != nullptr)
|
if (pOldLimit == nullptr && old_limit != nullptr)
|
||||||
return -EFAULT;
|
return -linux_EFAULT;
|
||||||
|
|
||||||
if (pNewLimit == nullptr && new_limit != nullptr)
|
if (pNewLimit == nullptr && new_limit != nullptr)
|
||||||
return -EFAULT;
|
return -linux_EFAULT;
|
||||||
|
|
||||||
UNUSED(pOldLimit);
|
|
||||||
UNUSED(pNewLimit);
|
|
||||||
|
|
||||||
if (new_limit)
|
if (new_limit)
|
||||||
{
|
{
|
||||||
debug("new limit: rlim_cur:%lld rlim_max:%lld",
|
if (pNewLimit->rlim_cur > pNewLimit->rlim_max)
|
||||||
pNewLimit->rlim_cur, pNewLimit->rlim_max);
|
return -linux_EINVAL;
|
||||||
}
|
|
||||||
|
|
||||||
if (old_limit)
|
|
||||||
{
|
|
||||||
debug("old limit: rlim_cur:%lld rlim_max:%lld",
|
|
||||||
pOldLimit->rlim_cur, pOldLimit->rlim_max);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (resource)
|
switch (resource)
|
||||||
@ -2724,22 +2726,70 @@ static int linux_prlimit64(SysFrm *, pid_t pid, int resource,
|
|||||||
goto __stub;
|
goto __stub;
|
||||||
case linux_RLIMIT_NPROC:
|
case linux_RLIMIT_NPROC:
|
||||||
{
|
{
|
||||||
|
if (old_limit)
|
||||||
|
{
|
||||||
|
pOldLimit->rlim_cur = pcb->SoftLimits.Threads;
|
||||||
|
pOldLimit->rlim_max = pcb->HardLimits.Threads;
|
||||||
|
debug("read NPROC limit: {%#lx, %#lx}", pOldLimit->rlim_cur, pOldLimit->rlim_max);
|
||||||
|
}
|
||||||
|
|
||||||
if (new_limit)
|
if (new_limit)
|
||||||
pcb->Limits.Threads = pNewLimit->rlim_max;
|
{
|
||||||
|
if (pNewLimit->rlim_max > pcb->HardLimits.Threads && !pcb->Security.CanAdjustHardLimits)
|
||||||
|
return -linux_EPERM;
|
||||||
|
|
||||||
|
debug("setting NPROC limit to {%#lx, %#lx}->{%#lx, %#lx}",
|
||||||
|
pcb->SoftLimits.Threads, pcb->HardLimits.Threads,
|
||||||
|
pNewLimit->rlim_cur, pNewLimit->rlim_max);
|
||||||
|
pcb->SoftLimits.Threads = pNewLimit->rlim_cur;
|
||||||
|
pcb->HardLimits.Threads = pNewLimit->rlim_max;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case linux_RLIMIT_NOFILE:
|
case linux_RLIMIT_NOFILE:
|
||||||
{
|
{
|
||||||
|
if (old_limit)
|
||||||
|
{
|
||||||
|
pOldLimit->rlim_cur = pcb->SoftLimits.OpenFiles;
|
||||||
|
pOldLimit->rlim_max = pcb->HardLimits.OpenFiles;
|
||||||
|
debug("read NOFILE limit: {%#lx, %#lx}", pOldLimit->rlim_cur, pOldLimit->rlim_max);
|
||||||
|
}
|
||||||
|
|
||||||
if (new_limit)
|
if (new_limit)
|
||||||
pcb->Limits.OpenFiles = pNewLimit->rlim_max;
|
{
|
||||||
|
if (pNewLimit->rlim_max > pcb->HardLimits.OpenFiles && !pcb->Security.CanAdjustHardLimits)
|
||||||
|
return -linux_EPERM;
|
||||||
|
|
||||||
|
debug("setting NOFILE limit to {%#lx, %#lx}->{%#lx, %#lx}",
|
||||||
|
pcb->SoftLimits.OpenFiles, pcb->HardLimits.OpenFiles,
|
||||||
|
pNewLimit->rlim_cur, pNewLimit->rlim_max);
|
||||||
|
pcb->SoftLimits.OpenFiles = pNewLimit->rlim_cur;
|
||||||
|
pcb->HardLimits.OpenFiles = pNewLimit->rlim_max;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case linux_RLIMIT_MEMLOCK:
|
case linux_RLIMIT_MEMLOCK:
|
||||||
goto __stub;
|
goto __stub;
|
||||||
case linux_RLIMIT_AS:
|
case linux_RLIMIT_AS:
|
||||||
{
|
{
|
||||||
|
if (old_limit)
|
||||||
|
{
|
||||||
|
pOldLimit->rlim_cur = pcb->SoftLimits.Memory;
|
||||||
|
pOldLimit->rlim_max = pcb->HardLimits.Memory;
|
||||||
|
debug("read AS limit: {%#lx, %#lx}", pOldLimit->rlim_cur, pOldLimit->rlim_max);
|
||||||
|
}
|
||||||
|
|
||||||
if (new_limit)
|
if (new_limit)
|
||||||
pcb->Limits.Memory = pNewLimit->rlim_max;
|
{
|
||||||
|
if (pNewLimit->rlim_max > pcb->HardLimits.Memory && !pcb->Security.CanAdjustHardLimits)
|
||||||
|
return -linux_EPERM;
|
||||||
|
|
||||||
|
debug("setting AS limit to {%#lx, %#lx}->{%#lx, %#lx}",
|
||||||
|
pcb->SoftLimits.Memory, pcb->HardLimits.Memory,
|
||||||
|
pNewLimit->rlim_cur, pNewLimit->rlim_max);
|
||||||
|
pcb->SoftLimits.Memory = pNewLimit->rlim_cur;
|
||||||
|
pcb->HardLimits.Memory = pNewLimit->rlim_max;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
case linux_RLIMIT_LOCKS:
|
case linux_RLIMIT_LOCKS:
|
||||||
@ -2757,11 +2807,9 @@ static int linux_prlimit64(SysFrm *, pid_t pid, int resource,
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
debug("Invalid resource %d", resource);
|
debug("Invalid resource %d", resource);
|
||||||
return -EINVAL;
|
return -linux_EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t linux_getrandom(SysFrm *, void *buf,
|
static ssize_t linux_getrandom(SysFrm *, void *buf,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user