From 403b0f6b94d8bc268c50b4f56066beaa3a0e8c97 Mon Sep 17 00:00:00 2001 From: apio Date: Mon, 24 Apr 2023 21:20:44 +0200 Subject: [PATCH] kernel+libc+init: Add a way to modify the system hostname --- apps/init.cpp | 16 +++++++++++++++ initrd/etc/hostname | 1 + kernel/src/main.cpp | 5 +++++ kernel/src/sys/uname.cpp | 36 +++++++++++++++++++++++++++++++--- libc/include/unistd.h | 6 ++++++ libc/src/unistd.cpp | 17 ++++++++++++++++ libluna/include/luna/Syscall.h | 2 +- 7 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 initrd/etc/hostname diff --git a/apps/init.cpp b/apps/init.cpp index 024b615f..65bac481 100644 --- a/apps/init.cpp +++ b/apps/init.cpp @@ -199,6 +199,20 @@ static Result start_services() return {}; } +static Result set_hostname() +{ + auto file = TRY(os::File::open("/etc/hostname", os::File::ReadOnly)); + + auto hostname = TRY(file->read_line()); + hostname.trim("\n"); + + if (sethostname(hostname.chars(), hostname.length()) < 0) return {}; + + fprintf(g_init_log, "[init] successfully set system hostname to '%s'\n", hostname.chars()); + + return {}; +} + int main() { if (getpid() != 1) @@ -218,6 +232,8 @@ int main() g_init_log = fopen("/init.log", "w+"); fcntl(fileno(g_init_log), F_SETFD, FD_CLOEXEC); + set_hostname(); + start_services(); while (1) diff --git a/initrd/etc/hostname b/initrd/etc/hostname new file mode 100644 index 00000000..faad4428 --- /dev/null +++ b/initrd/etc/hostname @@ -0,0 +1 @@ +lunar diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index a8357ca4..1e10fd4e 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -19,6 +19,8 @@ #include #include +extern void set_host_name(StringView); + void reap_thread() { while (true) @@ -37,6 +39,9 @@ Result init() { kinfoln("Starting Moon %s, built on %s at %s", MOON_VERSION, __DATE__, __TIME__); + // Default hostname if nobody from userspace changes it + set_host_name("moon"_sv); + kinfoln("Current platform: %s", CPU::platform_string()); kinfoln("Current processor: %s", CPU::identify().value_or("(unknown)")); diff --git a/kernel/src/sys/uname.cpp b/kernel/src/sys/uname.cpp index 2d9288d9..138665ab 100644 --- a/kernel/src/sys/uname.cpp +++ b/kernel/src/sys/uname.cpp @@ -1,8 +1,18 @@ #include "arch/CPU.h" +#include "config.h" #include "memory/MemoryManager.h" #include "sys/Syscall.h" +#include "thread/Scheduler.h" #include #include +#include + +StaticString<_UTSNAME_LENGTH - 1> s_hostname; + +void set_host_name(StringView hostname) +{ + s_hostname.adopt(hostname.chars()); +} Result sys_uname(Registers*, SyscallArgs args) { @@ -11,10 +21,10 @@ Result sys_uname(Registers*, SyscallArgs args) utsname result; strncpy(result.sysname, "moon", _UTSNAME_LENGTH); - strncpy(result.nodename, "lunar", _UTSNAME_LENGTH); + strncpy(result.nodename, s_hostname.chars(), _UTSNAME_LENGTH); - // FIXME: Hardcode these at build time instead of in code. - strncpy(result.release, "0.1", _UTSNAME_LENGTH); + strncpy(result.release, MOON_VERSION, _UTSNAME_LENGTH); + // FIXME: Hardcode this at build time instead of in code (should be the short commit hash). strncpy(result.version, "alpha", _UTSNAME_LENGTH); strncpy(result.machine, CPU::platform_string(), _UTSNAME_LENGTH); @@ -23,3 +33,23 @@ Result sys_uname(Registers*, SyscallArgs args) return 0; } + +Result sys_sethostname(Registers*, SyscallArgs args) +{ + const char* buf = (const char*)args[0]; + usize length = (usize)args[1]; + + Thread* current = Scheduler::current(); + if (current->auth.euid != 0) return err(EPERM); + + if (length >= _UTSNAME_LENGTH) return err(EINVAL); + + char new_hostname[_UTSNAME_LENGTH]; + memset(new_hostname, 0, _UTSNAME_LENGTH); + + if (!MemoryManager::copy_from_user(buf, new_hostname, length)) return err(EFAULT); + + s_hostname.adopt(new_hostname); + + return 0; +} diff --git a/libc/include/unistd.h b/libc/include/unistd.h index cc699a89..bf985d82 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -109,6 +109,12 @@ extern "C" /* Remove a directory from the filesystem. */ int rmdir(const char* path); + /* Get the current network hostname. */ + int gethostname(char* buf, size_t len); + + /* Set the current network hostname. */ + int sethostname(const char* buf, size_t len); + #ifdef __cplusplus } #endif diff --git a/libc/src/unistd.cpp b/libc/src/unistd.cpp index a6c61ead..5f0d1fa1 100644 --- a/libc/src/unistd.cpp +++ b/libc/src/unistd.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include extern "C" long arch_invoke_syscall(long, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t); @@ -313,4 +314,20 @@ extern "C" long rc = syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR); __errno_return(rc, int); } + + int gethostname(char* buf, size_t len) + { + struct utsname info; + if (uname(&info) < 0) return -1; + + strlcpy(buf, info.nodename, len); + + return 0; + } + + int sethostname(const char* buf, size_t len) + { + long rc = syscall(SYS_sethostname, buf, len); + __errno_return(rc, int); + } } diff --git a/libluna/include/luna/Syscall.h b/libluna/include/luna/Syscall.h index 60299092..3201dfc9 100644 --- a/libluna/include/luna/Syscall.h +++ b/libluna/include/luna/Syscall.h @@ -4,7 +4,7 @@ _e(exit) _e(clock_gettime) _e(mmap) _e(munmap) _e(usleep) _e(openat) _e(close) _e(read) _e(getpid) _e(write) \ _e(lseek) _e(mkdir) _e(execve) _e(mknod) _e(fork) _e(waitpid) _e(getppid) _e(fcntl) _e(getdents) _e(getuid) \ _e(geteuid) _e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(chmod) _e(chown) \ - _e(ioctl) _e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) + _e(ioctl) _e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) enum Syscalls {