Fix rlimits_test

This commit is contained in:
Fabing Li
2024-12-11 11:43:20 +00:00
committed by Tate, Hongliang Tian
parent 4316247d82
commit fc45592a28
3 changed files with 66 additions and 18 deletions

View File

@ -11,7 +11,7 @@ mod process_filter;
pub mod process_table; pub mod process_table;
mod process_vm; mod process_vm;
mod program_loader; mod program_loader;
mod rlimit; pub mod rlimit;
pub mod signal; pub mod signal;
mod status; mod status;
pub mod sync; pub mod sync;

View File

@ -1,19 +1,37 @@
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
// FIXME: The resource limits should be respected by the corresponding subsystems of the kernel.
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
use super::process_vm::{INIT_STACK_SIZE, USER_HEAP_SIZE_LIMIT}; use super::process_vm::{INIT_STACK_SIZE, USER_HEAP_SIZE_LIMIT};
use crate::prelude::*; use crate::prelude::*;
// Constants for the boot-time rlimit defaults
// See https://github.com/torvalds/linux/blob/fac04efc5c793dccbd07e2d59af9f90b7fc0dca4/include/asm-generic/resource.h#L11
const RLIM_INFINITY: u64 = u64::MAX;
const INIT_RLIMIT_NPROC: u64 = 0;
const INIT_RLIMIT_NICE: u64 = 0;
const INIT_RLIMIT_SIGPENDING: u64 = 0;
const INIT_RLIMIT_RTPRIO: u64 = 0;
// https://github.com/torvalds/linux/blob/fac04efc5c793dccbd07e2d59af9f90b7fc0dca4/include/uapi/linux/fs.h#L37
const INIT_RLIMIT_NOFILE_CUR: u64 = 1024;
const INIT_RLIMIT_NOFILE_MAX: u64 = 4096;
// https://github.com/torvalds/linux/blob/fac04efc5c793dccbd07e2d59af9f90b7fc0dca4/include/uapi/linux/resource.h#L79
const INIT_RLIMIT_MEMLOCK: u64 = 8 * 1024 * 1024;
// https://github.com/torvalds/linux/blob/fac04efc5c793dccbd07e2d59af9f90b7fc0dca4/include/uapi/linux/mqueue.h#L26
const INIT_RLIMIT_MSGQUEUE: u64 = 819200;
pub struct ResourceLimits { pub struct ResourceLimits {
rlimits: [RLimit64; RLIMIT_COUNT], rlimits: [RLimit64; RLIMIT_COUNT],
} }
impl ResourceLimits { impl ResourceLimits {
// Get a reference to a specific resource limit
pub fn get_rlimit(&self, resource: ResourceType) -> &RLimit64 { pub fn get_rlimit(&self, resource: ResourceType) -> &RLimit64 {
&self.rlimits[resource as usize] &self.rlimits[resource as usize]
} }
// Get a mutable reference to a specific resource limit
pub fn get_rlimit_mut(&mut self, resource: ResourceType) -> &mut RLimit64 { pub fn get_rlimit_mut(&mut self, resource: ResourceType) -> &mut RLimit64 {
&mut self.rlimits[resource as usize] &mut self.rlimits[resource as usize]
} }
@ -21,17 +39,36 @@ impl ResourceLimits {
impl Default for ResourceLimits { impl Default for ResourceLimits {
fn default() -> Self { fn default() -> Self {
let stack_size = RLimit64::new(INIT_STACK_SIZE as u64); let mut rlimits = [RLimit64::default(); RLIMIT_COUNT];
let heap_size = RLimit64::new(USER_HEAP_SIZE_LIMIT as u64);
let open_files = RLimit64::new(1024);
let mut rlimits = Self { // Setting the resource limits with predefined values
rlimits: [RLimit64::default(); RLIMIT_COUNT], rlimits[ResourceType::RLIMIT_CPU as usize] = RLimit64::new(RLIM_INFINITY, RLIM_INFINITY);
}; rlimits[ResourceType::RLIMIT_FSIZE as usize] = RLimit64::new(RLIM_INFINITY, RLIM_INFINITY);
*rlimits.get_rlimit_mut(ResourceType::RLIMIT_STACK) = stack_size; rlimits[ResourceType::RLIMIT_DATA as usize] =
*rlimits.get_rlimit_mut(ResourceType::RLIMIT_DATA) = heap_size; RLimit64::new(USER_HEAP_SIZE_LIMIT as u64, RLIM_INFINITY);
*rlimits.get_rlimit_mut(ResourceType::RLIMIT_NOFILE) = open_files; rlimits[ResourceType::RLIMIT_STACK as usize] =
rlimits RLimit64::new(INIT_STACK_SIZE as u64, RLIM_INFINITY);
rlimits[ResourceType::RLIMIT_CORE as usize] = RLimit64::new(0, RLIM_INFINITY);
rlimits[ResourceType::RLIMIT_RSS as usize] = RLimit64::new(RLIM_INFINITY, RLIM_INFINITY);
rlimits[ResourceType::RLIMIT_NPROC as usize] =
RLimit64::new(INIT_RLIMIT_NPROC, INIT_RLIMIT_NPROC);
rlimits[ResourceType::RLIMIT_NOFILE as usize] =
RLimit64::new(INIT_RLIMIT_NOFILE_CUR, INIT_RLIMIT_NOFILE_MAX);
rlimits[ResourceType::RLIMIT_MEMLOCK as usize] =
RLimit64::new(INIT_RLIMIT_MEMLOCK, INIT_RLIMIT_MEMLOCK);
rlimits[ResourceType::RLIMIT_AS as usize] = RLimit64::new(RLIM_INFINITY, RLIM_INFINITY);
rlimits[ResourceType::RLIMIT_LOCKS as usize] = RLimit64::new(RLIM_INFINITY, RLIM_INFINITY);
rlimits[ResourceType::RLIMIT_SIGPENDING as usize] =
RLimit64::new(INIT_RLIMIT_SIGPENDING, INIT_RLIMIT_SIGPENDING);
rlimits[ResourceType::RLIMIT_MSGQUEUE as usize] =
RLimit64::new(INIT_RLIMIT_MSGQUEUE, INIT_RLIMIT_MSGQUEUE);
rlimits[ResourceType::RLIMIT_NICE as usize] =
RLimit64::new(INIT_RLIMIT_NICE, INIT_RLIMIT_NICE);
rlimits[ResourceType::RLIMIT_RTPRIO as usize] =
RLimit64::new(INIT_RLIMIT_RTPRIO, INIT_RLIMIT_RTPRIO);
rlimits[ResourceType::RLIMIT_RTTIME as usize] = RLimit64::new(RLIM_INFINITY, RLIM_INFINITY);
ResourceLimits { rlimits }
} }
} }
@ -66,8 +103,8 @@ pub struct RLimit64 {
} }
impl RLimit64 { impl RLimit64 {
pub fn new(cur: u64) -> Self { pub fn new(cur: u64, max: u64) -> Self {
Self { cur, max: u64::MAX } Self { cur, max }
} }
pub fn get_cur(&self) -> u64 { pub fn get_cur(&self) -> u64 {
@ -77,13 +114,17 @@ impl RLimit64 {
pub fn get_max(&self) -> u64 { pub fn get_max(&self) -> u64 {
self.max self.max
} }
pub fn is_valid(&self) -> bool {
self.cur <= self.max
}
} }
impl Default for RLimit64 { impl Default for RLimit64 {
fn default() -> Self { fn default() -> Self {
Self { Self {
cur: u64::MAX, cur: RLIM_INFINITY,
max: u64::MAX, max: RLIM_INFINITY,
} }
} }
} }

View File

@ -3,7 +3,7 @@
use super::SyscallReturn; use super::SyscallReturn;
use crate::{ use crate::{
prelude::*, prelude::*,
process::{Pid, ResourceType}, process::{rlimit::RLimit64, Pid, ResourceType},
}; };
pub fn sys_getrlimit(resource: u32, rlim_addr: Vaddr, ctx: &Context) -> Result<SyscallReturn> { pub fn sys_getrlimit(resource: u32, rlim_addr: Vaddr, ctx: &Context) -> Result<SyscallReturn> {
@ -21,7 +21,10 @@ pub fn sys_setrlimit(resource: u32, new_rlim_addr: Vaddr, ctx: &Context) -> Resu
"resource = {:?}, new_rlim_addr = 0x{:x}", "resource = {:?}, new_rlim_addr = 0x{:x}",
resource, new_rlim_addr resource, new_rlim_addr
); );
let new_rlimit = ctx.user_space().read_val(new_rlim_addr)?; let new_rlimit: RLimit64 = ctx.user_space().read_val(new_rlim_addr)?;
if !new_rlimit.is_valid() {
return_errno_with_message!(Errno::EINVAL, "invalid rlimit");
}
let mut resource_limits = ctx.process.resource_limits().lock(); let mut resource_limits = ctx.process.resource_limits().lock();
*resource_limits.get_rlimit_mut(resource) = new_rlimit; *resource_limits.get_rlimit_mut(resource) = new_rlimit;
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))
@ -45,7 +48,11 @@ pub fn sys_prlimit64(
ctx.user_space().write_val(old_rlim_addr, rlimit)?; ctx.user_space().write_val(old_rlim_addr, rlimit)?;
} }
if new_rlim_addr != 0 { if new_rlim_addr != 0 {
let new_rlimit = ctx.user_space().read_val(new_rlim_addr)?; let new_rlimit: RLimit64 = ctx.user_space().read_val(new_rlim_addr)?;
debug!("new_rlimit = {:?}", new_rlimit);
if !new_rlimit.is_valid() {
return_errno_with_message!(Errno::EINVAL, "invalid rlimit");
}
*resource_limits.get_rlimit_mut(resource) = new_rlimit; *resource_limits.get_rlimit_mut(resource) = new_rlimit;
} }
Ok(SyscallReturn::Return(0)) Ok(SyscallReturn::Return(0))