SerenityOS / serenity

The Serenity Operating System 🐞
https://serenityos.org
BSD 2-Clause "Simplified" License
30.67k stars 3.19k forks source link

Kernel: Toying with unix domain socket causes panic #22701

Closed hanaa12G closed 8 months ago

hanaa12G commented 10 months ago

I'm not sure whether or not my code is correct.

Stack trace:

[test-crash-client(50:50)]: ASSERTION FAILED: !m_bound
[test-crash-client(50:50)]: ./Kernel/Net/LocalSocket.cpp:165 in virtual AK::ErrorOr<void> Kernel::LocalSocket::connect(const Kernel::Credentials&, Kernel::OpenFileDescription&, AK::Userspace<const sockaddr*>, socklen_t)
[test-crash-client(50:50)]: KERNEL PANIC! :^(
[test-crash-client(50:50)]: Aborted
[test-crash-client(50:50)]: at ./Kernel/Arch/x86_64/CPU.cpp:35 in void abort()
[test-crash-client(50:50)]: Kernel + 0x0000000000d28571  Kernel::__panic(char const*, unsigned int, char const*) +0xd1
[test-crash-client(50:50)]: Kernel + 0x00000000014d22c3  abort +0x38f
[test-crash-client(50:50)]: Kernel + 0x00000000014d1e1f  __assertion_failed(char const*, char const*, unsigned int, char const*) +0xbf
[test-crash-client(50:50)]: Kernel + 0x0000000000ddae46  Kernel::LocalSocket::connect(Kernel::Credentials const&, Kernel::OpenFileDescription&, AK::Userspace<sockaddr const*>, unsigned int) +0x876
[test-crash-client(50:50)]: Kernel + 0x00000000011a7d38  Kernel::Process::sys$connect(int, AK::Userspace<sockaddr const*>, unsigned int) +0x308
[test-crash-client(50:50)]: Kernel + 0x00000000011d84bc  Kernel::Syscall::handle(Kernel::RegisterState&, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) +0xa6c
[test-crash-client(50:50)]: Kernel + 0x00000000011db2ba  syscall_handler +0x93a
[test-crash-client(50:50)]: Kernel + 0x000000000153a4a1  syscall_entry +0x51

Test code:

#include <LibMain/Main.h>
#include <sys/socket.h>
#include <AK/Format.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

ErrorOr<int> serenity_main(Main::Arguments /* arguments */)
{
  int fd = socket(AF_UNIX, SOCK_STREAM, 0);
  if (fd == -1) {
    return 1;
  }
  struct sockaddr_un addr {};
  addr.sun_family = AF_UNIX;
  unlink("tmp-client.test");
  strcpy(addr.sun_path, "tmp-client.test");
  if (-1 == bind(fd, (struct sockaddr*) &addr, sizeof(addr))) {
    close(fd);
    return 1;
  }

  struct sockaddr_un server_sockaddr {};
  server_sockaddr.sun_family = AF_UNIX;
  strcpy(server_sockaddr.sun_path, "tmp.test");
  if (-1 == connect(fd, (struct sockaddr*) &server_sockaddr, sizeof(server_sockaddr))) {
    close(fd);
    return 1;
  }

  close(fd);
  return 0;
}
ADKaster commented 10 months ago

We certainly shouldn't panic the kernel, no matter what userspace does. So that's already a kernel bug. As far as whether this is supposed to "work", I would recommend testing the program on some other unixes (Linux, macOS, etc) and seeing what kind of errors are returned from the socket calls.