From 882dea6125a052bf155f8243fac068631ee8950b Mon Sep 17 00:00:00 2001 From: jiangjianfeng Date: Fri, 19 Sep 2025 03:03:25 +0000 Subject: [PATCH] Add syscall setdomainname --- book/src/kernel/linux-compatibility/README.md | 2 +- kernel/src/net/uts_ns.rs | 16 ++++++++++++++++ kernel/src/syscall/arch/loongarch.rs | 2 ++ kernel/src/syscall/arch/riscv.rs | 2 ++ kernel/src/syscall/arch/x86.rs | 2 ++ kernel/src/syscall/mod.rs | 1 + kernel/src/syscall/setdomainname.rs | 10 ++++++++++ test/src/syscall/ltp/testcases/all.txt | 5 +++-- 8 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 kernel/src/syscall/setdomainname.rs diff --git a/book/src/kernel/linux-compatibility/README.md b/book/src/kernel/linux-compatibility/README.md index cfb7ad274..4971da538 100644 --- a/book/src/kernel/linux-compatibility/README.md +++ b/book/src/kernel/linux-compatibility/README.md @@ -191,7 +191,7 @@ provided by Linux on x86-64 architecture. | 168 | swapoff | ❌ | | | 169 | reboot | ❌ | | | 170 | sethostname | ✅ | | -| 171 | setdomainname | ❌ | | +| 171 | setdomainname | ✅ | | | 172 | iopl | ❌ | | | 173 | ioperm | ❌ | | | 174 | create_module | ❌ | | diff --git a/kernel/src/net/uts_ns.rs b/kernel/src/net/uts_ns.rs index 620beb577..e28d16f36 100644 --- a/kernel/src/net/uts_ns.rs +++ b/kernel/src/net/uts_ns.rs @@ -80,6 +80,22 @@ impl UtsNamespace { self.uts_name.write().nodename = new_host_name; Ok(()) } + + /// Sets a new domain name for the UTS namespace. + /// + /// This method will fail with `EPERM` if the caller does not have the SYS_ADMIN capability + /// in the owner user namespace. + pub fn set_domainname(&self, addr: Vaddr, len: usize, ctx: &Context) -> Result<()> { + self.owner.check_cap(CapSet::SYS_ADMIN, ctx.posix_thread)?; + + let new_domain_name = copy_uts_field_from_user(addr, len as _, ctx)?; + debug!( + "set domain name: {:?}", + CStr::from_bytes_until_nul(new_domain_name.as_bytes()).unwrap() + ); + self.uts_name.write().domainname = new_domain_name; + Ok(()) + } } const UTS_FIELD_LEN: usize = 65; diff --git a/kernel/src/syscall/arch/loongarch.rs b/kernel/src/syscall/arch/loongarch.rs index d40d5f75b..8d11390f0 100644 --- a/kernel/src/syscall/arch/loongarch.rs +++ b/kernel/src/syscall/arch/loongarch.rs @@ -113,6 +113,7 @@ use super::{ set_priority::sys_set_priority, set_robust_list::sys_set_robust_list, set_tid_address::sys_set_tid_address, + setdomainname::sys_setdomainname, setfsgid::sys_setfsgid, setfsuid::sys_setfsuid, setgid::sys_setgid, @@ -285,6 +286,7 @@ impl_syscall_nums_and_dispatch_fn! { SYS_SETGROUPS = 159 => sys_setgroups(args[..2]); SYS_NEWUNAME = 160 => sys_uname(args[..1]); SYS_SETHOSTNAME = 161 => sys_sethostname(args[..2]); + SYS_SETDOMAINNAME = 162 => sys_setdomainname(args[..2]); SYS_GETRUSAGE = 165 => sys_getrusage(args[..2]); SYS_UMASK = 166 => sys_umask(args[..1]); SYS_PRCTL = 167 => sys_prctl(args[..5]); diff --git a/kernel/src/syscall/arch/riscv.rs b/kernel/src/syscall/arch/riscv.rs index 493e9d972..268ed4824 100644 --- a/kernel/src/syscall/arch/riscv.rs +++ b/kernel/src/syscall/arch/riscv.rs @@ -113,6 +113,7 @@ use super::{ set_priority::sys_set_priority, set_robust_list::sys_set_robust_list, set_tid_address::sys_set_tid_address, + setdomainname::sys_setdomainname, setfsgid::sys_setfsgid, setfsuid::sys_setfsuid, setgid::sys_setgid, @@ -285,6 +286,7 @@ impl_syscall_nums_and_dispatch_fn! { SYS_SETGROUPS = 159 => sys_setgroups(args[..2]); SYS_NEWUNAME = 160 => sys_uname(args[..1]); SYS_SETHOSTNAME = 161 => sys_sethostname(args[..2]); + SYS_SETDOMAINNAME = 162 => sys_setdomainname(args[..2]); SYS_GETRLIMIT = 163 => sys_getrlimit(args[..2]); SYS_SETRLIMIT = 164 => sys_setrlimit(args[..2]); SYS_GETRUSAGE = 165 => sys_getrusage(args[..2]); diff --git a/kernel/src/syscall/arch/x86.rs b/kernel/src/syscall/arch/x86.rs index c76e48368..b6a88b7d8 100644 --- a/kernel/src/syscall/arch/x86.rs +++ b/kernel/src/syscall/arch/x86.rs @@ -124,6 +124,7 @@ use super::{ set_priority::sys_set_priority, set_robust_list::sys_set_robust_list, set_tid_address::sys_set_tid_address, + setdomainname::sys_setdomainname, setfsgid::sys_setfsgid, setfsuid::sys_setfsuid, setgid::sys_setgid, @@ -309,6 +310,7 @@ impl_syscall_nums_and_dispatch_fn! { SYS_MOUNT = 165 => sys_mount(args[..5]); SYS_UMOUNT2 = 166 => sys_umount(args[..2]); SYS_SETHOSTNAME = 170 => sys_sethostname(args[..2]); + SYS_SETDOMAINNAME = 171 => sys_setdomainname(args[..2]); SYS_GETTID = 186 => sys_gettid(args[..0]); SYS_SETXATTR = 188 => sys_setxattr(args[..5]); SYS_LSETXATTR = 189 => sys_lsetxattr(args[..5]); diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index d54bb4516..d998a4e57 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -140,6 +140,7 @@ mod set_ioprio; mod set_priority; mod set_robust_list; mod set_tid_address; +mod setdomainname; mod setfsgid; mod setfsuid; mod setgid; diff --git a/kernel/src/syscall/setdomainname.rs b/kernel/src/syscall/setdomainname.rs new file mode 100644 index 000000000..12c80bb5f --- /dev/null +++ b/kernel/src/syscall/setdomainname.rs @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MPL-2.0 + +use crate::{prelude::*, syscall::SyscallReturn}; + +pub fn sys_setdomainname(addr: Vaddr, len: usize, ctx: &Context) -> Result { + let ns_proxy_ref = ctx.thread_local.borrow_ns_proxy(); + let ns_proxy = ns_proxy_ref.unwrap(); + ns_proxy.uts_ns().set_domainname(addr, len, ctx)?; + Ok(SyscallReturn::Return(0)) +} diff --git a/test/src/syscall/ltp/testcases/all.txt b/test/src/syscall/ltp/testcases/all.txt index 31e85d353..b80671631 100644 --- a/test/src/syscall/ltp/testcases/all.txt +++ b/test/src/syscall/ltp/testcases/all.txt @@ -1340,8 +1340,9 @@ set_robust_list01 # set_thread_area01 # set_tid_address01 -# setdomainname01 -# setdomainname02 +setdomainname01 +setdomainname02 +# TODO: Drop capabilities on UID changes, so that setdomainname() will fail with EPERM. # setdomainname03 # setfsgid01