diff --git a/Kernel/Process.h b/Kernel/Process.h index a709c3c0fe..6e17e72e2b 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -252,7 +252,7 @@ public: int sys$clock_nanosleep(Userspace); int sys$gethostname(Userspace, ssize_t); int sys$sethostname(Userspace, ssize_t); - int sys$uname(utsname*); + int sys$uname(Userspace); int sys$readlink(Userspace); int sys$ttyname(int fd, Userspace, size_t); int sys$ptsname(int fd, Userspace, size_t); diff --git a/Kernel/Syscalls/uname.cpp b/Kernel/Syscalls/uname.cpp index 140e084b37..33172798dd 100644 --- a/Kernel/Syscalls/uname.cpp +++ b/Kernel/Syscalls/uname.cpp @@ -28,7 +28,7 @@ namespace Kernel { -int Process::sys$uname(utsname* buf) +int Process::sys$uname(Userspace buf) { extern String* g_hostname; extern Lock* g_hostname_lock; @@ -36,14 +36,20 @@ int Process::sys$uname(utsname* buf) REQUIRE_PROMISE(stdio); if (!validate_write_typed(buf)) return -EFAULT; + + LOCKER(*g_hostname_lock, Lock::Mode::Shared); if (g_hostname->length() + 1 > sizeof(utsname::nodename)) return -ENAMETOOLONG; - copy_to_user(buf->sysname, "SerenityOS", 11); - copy_to_user(buf->release, "1.0-dev", 8); - copy_to_user(buf->version, "FIXME", 6); - copy_to_user(buf->machine, "i686", 5); - copy_to_user(buf->nodename, g_hostname->characters(), g_hostname->length() + 1); + + // We have already validated the entire utsname struct at this + // point, there is no need to re-validate every write to the struct. + utsname* user_buf = buf.unsafe_userspace_ptr(); + copy_to_user(user_buf->sysname, "SerenityOS", 11); + copy_to_user(user_buf->release, "1.0-dev", 8); + copy_to_user(user_buf->version, "FIXME", 6); + copy_to_user(user_buf->machine, "i686", 5); + copy_to_user(user_buf->nodename, g_hostname->characters(), g_hostname->length() + 1); return 0; }