diff --git a/docs/src/kernel/linux-compatibility.md b/docs/src/kernel/linux-compatibility.md index a60f0dcc..1146e0e8 100644 --- a/docs/src/kernel/linux-compatibility.md +++ b/docs/src/kernel/linux-compatibility.md @@ -117,7 +117,7 @@ provided by Linux on x86-64 architecture. | 94 | lchown | ✅ | | 95 | umask | ✅ | | 96 | gettimeofday | ✅ | -| 97 | getrlimit | ❌ | +| 97 | getrlimit | ✅ | | 98 | getrusage | ✅ | | 99 | sysinfo | ❌ | | 100 | times | ❌ | @@ -180,7 +180,7 @@ provided by Linux on x86-64 architecture. | 157 | prctl | ✅ | | 158 | arch_prctl | ✅ | | 159 | adjtimex | ❌ | -| 160 | setrlimit | ❌ | +| 160 | setrlimit | ✅ | | 161 | chroot | ✅ | | 162 | sync | ✅ | | 163 | acct | ❌ | diff --git a/kernel/src/syscall/arch/riscv.rs b/kernel/src/syscall/arch/riscv.rs index 313d2387..0a3d1c94 100644 --- a/kernel/src/syscall/arch/riscv.rs +++ b/kernel/src/syscall/arch/riscv.rs @@ -66,7 +66,7 @@ use crate::syscall::{ prctl::sys_prctl, pread64::sys_pread64, preadv::{sys_preadv, sys_preadv2, sys_readv}, - prlimit64::sys_prlimit64, + prlimit64::{sys_getrlimit, sys_prlimit64, sys_setrlimit}, pselect6::sys_pselect6, pwrite64::sys_pwrite64, pwritev::{sys_pwritev, sys_pwritev2, sys_writev}, @@ -220,6 +220,8 @@ impl_syscall_nums_and_dispatch_fn! { SYS_GETGROUPS = 158 => sys_getgroups(args[..2]); SYS_SETGROUPS = 159 => sys_setgroups(args[..2]); SYS_NEWUNAME = 160 => sys_uname(args[..1]); + SYS_GETRLIMIT = 163 => sys_getrlimit(args[..2]); + SYS_SETRLIMIT = 164 => sys_setrlimit(args[..2]); SYS_GETRUSAGE = 165 => sys_getrusage(args[..2]); SYS_UMASK = 166 => sys_umask(args[..1]); SYS_PRCTL = 167 => sys_prctl(args[..5]); @@ -264,6 +266,7 @@ impl_syscall_nums_and_dispatch_fn! { SYS_EXECVEAT = 281 => sys_execveat(args[..5], &mut user_ctx); SYS_PREADV2 = 286 => sys_preadv2(args[..5]); SYS_PWRITEV2 = 287 => sys_pwritev2(args[..5]); + SYS_PRLIMIT64 = 302 => sys_prlimit64(args[..4]); SYS_CLOCK_GETTIME = 403 => sys_clock_gettime(args[..2]); SYS_CLOCK_NANOSLEEP = 407 => sys_clock_nanosleep(args[..4]); SYS_TIMER_GETTIME = 408 => sys_timer_gettime(args[..2]); diff --git a/kernel/src/syscall/arch/x86.rs b/kernel/src/syscall/arch/x86.rs index 03915d69..6c847473 100644 --- a/kernel/src/syscall/arch/x86.rs +++ b/kernel/src/syscall/arch/x86.rs @@ -71,7 +71,7 @@ use crate::syscall::{ prctl::sys_prctl, pread64::sys_pread64, preadv::{sys_preadv, sys_preadv2, sys_readv}, - prlimit64::sys_prlimit64, + prlimit64::{sys_getrlimit, sys_prlimit64, sys_setrlimit}, pselect6::sys_pselect6, pwrite64::sys_pwrite64, pwritev::{sys_pwritev, sys_pwritev2, sys_writev}, @@ -221,6 +221,7 @@ impl_syscall_nums_and_dispatch_fn! { SYS_LCHOWN = 94 => sys_lchown(args[..3]); SYS_UMASK = 95 => sys_umask(args[..1]); SYS_GETTIMEOFDAY = 96 => sys_gettimeofday(args[..1]); + SYS_GETRLIMIT = 97 => sys_getrlimit(args[..2]); SYS_GETRUSAGE = 98 => sys_getrusage(args[..2]); SYS_GETUID = 102 => sys_getuid(args[..0]); SYS_GETGID = 104 => sys_getgid(args[..0]); @@ -256,6 +257,7 @@ impl_syscall_nums_and_dispatch_fn! { SYS_SET_PRIORITY = 141 => sys_set_priority(args[..3]); SYS_PRCTL = 157 => sys_prctl(args[..5]); SYS_ARCH_PRCTL = 158 => sys_arch_prctl(args[..2], &mut user_ctx); + SYS_SETRLIMIT = 160 => sys_setrlimit(args[..2]); SYS_CHROOT = 161 => sys_chroot(args[..1]); SYS_SYNC = 162 => sys_sync(args[..0]); SYS_MOUNT = 165 => sys_mount(args[..5]); diff --git a/kernel/src/syscall/prlimit64.rs b/kernel/src/syscall/prlimit64.rs index 62c02082..d4f7ca32 100644 --- a/kernel/src/syscall/prlimit64.rs +++ b/kernel/src/syscall/prlimit64.rs @@ -6,6 +6,27 @@ use crate::{ process::{Pid, ResourceType}, }; +pub fn sys_getrlimit(resource: u32, rlim_addr: Vaddr, ctx: &Context) -> Result { + let resource = ResourceType::try_from(resource)?; + debug!("resource = {:?}, rlim_addr = 0x{:x}", resource, rlim_addr); + let resource_limits = ctx.process.resource_limits().lock(); + let rlimit = resource_limits.get_rlimit(resource); + ctx.get_user_space().write_val(rlim_addr, rlimit)?; + Ok(SyscallReturn::Return(0)) +} + +pub fn sys_setrlimit(resource: u32, new_rlim_addr: Vaddr, ctx: &Context) -> Result { + let resource = ResourceType::try_from(resource)?; + debug!( + "resource = {:?}, new_rlim_addr = 0x{:x}", + resource, new_rlim_addr + ); + let new_rlimit = ctx.get_user_space().read_val(new_rlim_addr)?; + let mut resource_limits = ctx.process.resource_limits().lock(); + *resource_limits.get_rlimit_mut(resource) = new_rlimit; + Ok(SyscallReturn::Return(0)) +} + pub fn sys_prlimit64( pid: Pid, resource: u32, diff --git a/test/syscall_test/Makefile b/test/syscall_test/Makefile index c39d0c5d..98d577fb 100644 --- a/test/syscall_test/Makefile +++ b/test/syscall_test/Makefile @@ -38,6 +38,7 @@ TESTS ?= \ read_test \ readv_test \ rename_test \ + rlimits_test \ semaphore_test \ sendfile_test \ sigaltstack_test \ diff --git a/test/syscall_test/blocklists/rlimits_test b/test/syscall_test/blocklists/rlimits_test new file mode 100644 index 00000000..1fd5c09a --- /dev/null +++ b/test/syscall_test/blocklists/rlimits_test @@ -0,0 +1 @@ +RlimitTest.UnprivilegedSetRlimit \ No newline at end of file