Przeglądaj źródła

LibIPC: Make sure FDs survive when passed into a MessageBuffer

Gunnar Beutner 4 lat temu
rodzic
commit
de9b454f89

+ 2 - 2
Userland/Libraries/LibIPC/Connection.h

@@ -65,8 +65,8 @@ public:
         buffer.data.prepend(reinterpret_cast<const u8*>(&message_size), sizeof(message_size));
 
 #ifdef __serenity__
-        for (int fd : buffer.fds) {
-            auto rc = sendfd(m_socket->fd(), fd);
+        for (auto& fd : buffer.fds) {
+            auto rc = sendfd(m_socket->fd(), fd->value());
             if (rc < 0) {
                 perror("sendfd");
                 shutdown();

+ 10 - 1
Userland/Libraries/LibIPC/Encoder.cpp

@@ -148,7 +148,16 @@ Encoder& Encoder::operator<<(const Dictionary& dictionary)
 
 Encoder& Encoder::operator<<(const File& file)
 {
-    m_buffer.fds.append(file.fd());
+    int fd = file.fd();
+    if (fd != -1) {
+        auto result = dup(fd);
+        if (result < 0) {
+            perror("dup");
+            VERIFY_NOT_REACHED();
+        }
+        fd = result;
+    }
+    m_buffer.fds.append(adopt_ref(*new AutoCloseFileDescriptor(fd)));
     return *this;
 }
 

+ 22 - 1
Userland/Libraries/LibIPC/Message.h

@@ -7,13 +7,34 @@
 #pragma once
 
 #include <AK/Function.h>
+#include <AK/RefPtr.h>
 #include <AK/Vector.h>
+#include <unistd.h>
 
 namespace IPC {
 
+class AutoCloseFileDescriptor : public RefCounted<AutoCloseFileDescriptor> {
+public:
+    AutoCloseFileDescriptor(int fd)
+        : m_fd(fd)
+    {
+    }
+
+    ~AutoCloseFileDescriptor()
+    {
+        if (m_fd != -1)
+            close(m_fd);
+    }
+
+    int value() const { return m_fd; }
+
+private:
+    int m_fd;
+};
+
 struct MessageBuffer {
     Vector<u8, 1024> data;
-    Vector<int> fds;
+    Vector<RefPtr<AutoCloseFileDescriptor>> fds;
 };
 
 class Message {