浏览代码

Kernel: Remove SmapDisabler in bind()

Andreas Kling 5 年之前
父节点
当前提交
1434f30f92
共有 3 个文件被更改,包括 18 次插入14 次删除
  1. 8 6
      Kernel/Net/IPv4Socket.cpp
  2. 10 7
      Kernel/Net/LocalSocket.cpp
  3. 0 1
      Kernel/Process.cpp

+ 8 - 6
Kernel/Net/IPv4Socket.cpp

@@ -80,17 +80,19 @@ bool IPv4Socket::get_peer_address(sockaddr* address, socklen_t* address_size)
     return true;
     return true;
 }
 }
 
 
-KResult IPv4Socket::bind(const sockaddr* address, socklen_t address_size)
+KResult IPv4Socket::bind(const sockaddr* user_address, socklen_t address_size)
 {
 {
     ASSERT(setup_state() == SetupState::Unstarted);
     ASSERT(setup_state() == SetupState::Unstarted);
     if (address_size != sizeof(sockaddr_in))
     if (address_size != sizeof(sockaddr_in))
         return KResult(-EINVAL);
         return KResult(-EINVAL);
-    if (address->sa_family != AF_INET)
-        return KResult(-EINVAL);
 
 
-    auto& ia = *(const sockaddr_in*)address;
+    sockaddr_in address;
+    copy_from_user(&address, user_address, sizeof(sockaddr_in));
+
+    if (address.sin_family != AF_INET)
+        return KResult(-EINVAL);
 
 
-    auto requested_local_port = ntohs(ia.sin_port);
+    auto requested_local_port = ntohs(address.sin_port);
     if (!current->process().is_superuser()) {
     if (!current->process().is_superuser()) {
         if (requested_local_port < 1024) {
         if (requested_local_port < 1024) {
             dbg() << current->process() << " (uid " << current->process().uid() << ") attempted to bind " << class_name() << " to port " << requested_local_port;
             dbg() << current->process() << " (uid " << current->process().uid() << ") attempted to bind " << class_name() << " to port " << requested_local_port;
@@ -98,7 +100,7 @@ KResult IPv4Socket::bind(const sockaddr* address, socklen_t address_size)
         }
         }
     }
     }
 
 
-    m_local_address = IPv4Address((const u8*)&ia.sin_addr.s_addr);
+    m_local_address = IPv4Address((const u8*)&address.sin_addr.s_addr);
     m_local_port = requested_local_port;
     m_local_port = requested_local_port;
 
 
 #ifdef IPV4_SOCKET_DEBUG
 #ifdef IPV4_SOCKET_DEBUG

+ 10 - 7
Kernel/Net/LocalSocket.cpp

@@ -3,6 +3,7 @@
 #include <Kernel/FileSystem/VirtualFileSystem.h>
 #include <Kernel/FileSystem/VirtualFileSystem.h>
 #include <Kernel/Net/LocalSocket.h>
 #include <Kernel/Net/LocalSocket.h>
 #include <Kernel/Process.h>
 #include <Kernel/Process.h>
+#include <Kernel/StdLib.h>
 #include <Kernel/UnixTypes.h>
 #include <Kernel/UnixTypes.h>
 #include <LibC/errno_numbers.h>
 #include <LibC/errno_numbers.h>
 
 
@@ -64,17 +65,19 @@ bool LocalSocket::get_peer_address(sockaddr* address, socklen_t* address_size)
     return get_local_address(address, address_size);
     return get_local_address(address, address_size);
 }
 }
 
 
-KResult LocalSocket::bind(const sockaddr* address, socklen_t address_size)
+KResult LocalSocket::bind(const sockaddr* user_address, socklen_t address_size)
 {
 {
     ASSERT(setup_state() == SetupState::Unstarted);
     ASSERT(setup_state() == SetupState::Unstarted);
     if (address_size != sizeof(sockaddr_un))
     if (address_size != sizeof(sockaddr_un))
         return KResult(-EINVAL);
         return KResult(-EINVAL);
-    if (address->sa_family != AF_LOCAL)
+
+    sockaddr_un address;
+    copy_from_user(&address, user_address, sizeof(sockaddr_un));
+
+    if (address.sun_family != AF_LOCAL)
         return KResult(-EINVAL);
         return KResult(-EINVAL);
 
 
-    const sockaddr_un& local_address = *reinterpret_cast<const sockaddr_un*>(address);
-    char safe_address[sizeof(local_address.sun_path) + 1] = { 0 };
-    memcpy(safe_address, local_address.sun_path, sizeof(local_address.sun_path));
+    auto path = String(address.sun_path, strnlen(address.sun_path, sizeof(address.sun_path)));
 
 
 #ifdef DEBUG_LOCAL_SOCKET
 #ifdef DEBUG_LOCAL_SOCKET
     kprintf("%s(%u) LocalSocket{%p} bind(%s)\n", current->process().name().characters(), current->pid(), this, safe_address);
     kprintf("%s(%u) LocalSocket{%p} bind(%s)\n", current->process().name().characters(), current->pid(), this, safe_address);
@@ -82,7 +85,7 @@ KResult LocalSocket::bind(const sockaddr* address, socklen_t address_size)
 
 
     mode_t mode = S_IFSOCK | (m_prebind_mode & 04777);
     mode_t mode = S_IFSOCK | (m_prebind_mode & 04777);
     UidAndGid owner { m_prebind_uid, m_prebind_gid };
     UidAndGid owner { m_prebind_uid, m_prebind_gid };
-    auto result = VFS::the().open( safe_address, O_CREAT | O_EXCL, mode, current->process().current_directory(), owner);
+    auto result = VFS::the().open(path, O_CREAT | O_EXCL, mode, current->process().current_directory(), owner);
     if (result.is_error()) {
     if (result.is_error()) {
         if (result.error() == -EEXIST)
         if (result.error() == -EEXIST)
             return KResult(-EADDRINUSE);
             return KResult(-EADDRINUSE);
@@ -93,7 +96,7 @@ KResult LocalSocket::bind(const sockaddr* address, socklen_t address_size)
     ASSERT(m_file->inode());
     ASSERT(m_file->inode());
     m_file->inode()->bind_socket(*this);
     m_file->inode()->bind_socket(*this);
 
 
-    m_address = local_address;
+    m_address = address;
     m_bound = true;
     m_bound = true;
     return KSuccess;
     return KSuccess;
 }
 }

+ 0 - 1
Kernel/Process.cpp

@@ -2808,7 +2808,6 @@ int Process::sys$bind(int sockfd, const sockaddr* address, socklen_t address_len
         return -EBADF;
         return -EBADF;
     if (!description->is_socket())
     if (!description->is_socket())
         return -ENOTSOCK;
         return -ENOTSOCK;
-    SmapDisabler disabler;
     auto& socket = *description->socket();
     auto& socket = *description->socket();
     return socket.bind(address, address_length);
     return socket.bind(address, address_length);
 }
 }