[PATCH] add utsname_set_field to reuse code in setdomainname and sethostname

From: Laurijssen

Date: Wed Nov 11 2026 - 02:39:15 EST


Changes after review, cleanup of duplicated code in sethostname and
setdomainname.

- add static utsname_set_field sys.c
- call utsname_set_field from sethostname/setdomainname
- code compiles now when CONFIG_SYSCTL is not defined

Signed-off-by: Laurijssen <laurijssen@xxxxxxxxxxxxxx>
---
kernel/sys.c | 53 ++++++++++++++++++++++++++--------------------------
1 file changed, 27 insertions(+), 26 deletions(-)

diff --git a/kernel/sys.c b/kernel/sys.c
index 755bfa5ccd92..77fedd127a3f 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1419,7 +1419,7 @@ SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
}
#endif

-SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
+static int utsname_set_field(char __user *name, int len, enum uts_proc proc)
{
int errno;
char tmp[__NEW_UTS_LEN];
@@ -1432,19 +1432,41 @@ SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
errno = -EFAULT;
if (!copy_from_user(tmp, name, len)) {
struct new_utsname *u;
+ char *field;

add_device_randomness(tmp, len);
down_write(&uts_sem);
+
u = utsname();
- memcpy(u->nodename, tmp, len);
- memset(u->nodename + len, 0, sizeof(u->nodename) - len);
+
+ switch (proc) {
+ case UTS_PROC_HOSTNAME:
+ field = u->nodename;
+ break;
+ case UTS_PROC_DOMAINNAME:
+ field = u->domainname;
+ break;
+ default:
+ WARN_ON_ONCE(1);
+ field = u->domainname;
+ break;
+ }
+
+ memcpy(field, tmp, len);
+ memset(field + len, 0, sizeof_field(struct new_utsname, nodename) - len);
+
errno = 0;
- uts_proc_notify(UTS_PROC_HOSTNAME);
+ uts_proc_notify(proc);
up_write(&uts_sem);
}
return errno;
}

+SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
+{
+ return utsname_set_field(name, len, UTS_PROC_HOSTNAME);
+}
+
#ifdef __ARCH_WANT_SYS_GETHOSTNAME

SYSCALL_DEFINE2(gethostname, char __user *, name, int, len)
@@ -1475,28 +1497,7 @@ SYSCALL_DEFINE2(gethostname, char __user *, name, int, len)
*/
SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len)
{
- int errno;
- char tmp[__NEW_UTS_LEN];
-
- if (!ns_capable(current->nsproxy->uts_ns->user_ns, CAP_SYS_ADMIN))
- return -EPERM;
- if (len < 0 || len > __NEW_UTS_LEN)
- return -EINVAL;
-
- errno = -EFAULT;
- if (!copy_from_user(tmp, name, len)) {
- struct new_utsname *u;
-
- add_device_randomness(tmp, len);
- down_write(&uts_sem);
- u = utsname();
- memcpy(u->domainname, tmp, len);
- memset(u->domainname + len, 0, sizeof(u->domainname) - len);
- errno = 0;
- uts_proc_notify(UTS_PROC_DOMAINNAME);
- up_write(&uts_sem);
- }
- return errno;
+ return utsname_set_field(name, len, UTS_PROC_DOMAINNAME);
}

/* make sure you are allowed to change @tsk limits before calling this */
--
2.53.0