From 291a4844bcfb613949618bddadcf21927e0765c1 Mon Sep 17 00:00:00 2001 From: patrick96 Date: Sun, 23 Oct 2022 14:11:31 +0200 Subject: [PATCH] fix(ipc): Crash when sending to multiple instances In polybar-msg, the connection handle was captured as a reference to a shared_ptr, but the shared_ptr went out of scope right after. This probably always caused UB, but was only noticeable for two or more instances. --- include/ipc/ipc.hpp | 4 ++-- src/ipc/ipc.cpp | 16 ++++++++-------- src/polybar-msg.cpp | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/ipc/ipc.hpp b/include/ipc/ipc.hpp index fb642ac8..37e5812c 100644 --- a/include/ipc/ipc.hpp +++ b/include/ipc/ipc.hpp @@ -42,7 +42,7 @@ namespace ipc { const logger& m_log; eventloop::loop& m_loop; - eventloop::pipe_handle_t socket; + eventloop::pipe_handle_t m_socket; class connection : public non_copyable_mixin, public non_movable_mixin { public: @@ -89,7 +89,7 @@ namespace ipc { * Buffer for the currently received IPC message over the named pipe */ string m_pipe_buffer{}; - void receive_data(string buf); + void receive_data(const string& buf); void receive_eof(); }; } // namespace ipc diff --git a/src/ipc/ipc.cpp b/src/ipc/ipc.cpp index df75490c..7aa2e6de 100644 --- a/src/ipc/ipc.cpp +++ b/src/ipc/ipc.cpp @@ -40,7 +40,7 @@ namespace ipc { * Construct ipc handler */ ipc::ipc(signal_emitter& emitter, const logger& logger, loop& loop) - : m_sig(emitter), m_log(logger), m_loop(loop), socket(loop.handle()) { + : m_sig(emitter), m_log(logger), m_loop(loop), m_socket(loop.handle()) { m_pipe_path = string_util::replace(PATH_MESSAGING_FIFO, "%pid%", to_string(getpid())); if (file_util::exists(m_pipe_path) && unlink(m_pipe_path.c_str()) == -1) { @@ -57,12 +57,12 @@ namespace ipc { m_log.info("Opening ipc socket at '%s'", sock_path); m_log.notice("Listening for IPC messages (PID: %d)", getpid()); - socket->bind(sock_path); - socket->listen( + m_socket->bind(sock_path); + m_socket->listen( 4, [this]() { on_connection(); }, [this](const auto& e) { m_log.err("libuv error while listening to IPC socket: %s", uv_strerror(e.status)); - socket->close(); + m_socket->close(); }); } @@ -133,12 +133,12 @@ namespace ipc { }); auto& c = *connection; - socket->accept(*c.client_pipe); + m_socket->accept(*c.client_pipe); c.client_pipe->read_start( [this, &c](const auto& e) { try { - c.dec.on_read((const uint8_t*)e.data, e.len); + c.dec.on_read(reinterpret_cast(e.data), e.len); } catch (const decoder::error& e) { m_log.err("ipc: Failed to decode IPC message (reason: %s)", e.what()); @@ -175,7 +175,7 @@ namespace ipc { } ipc::fifo::fifo(loop& loop, ipc& ipc, const string& path) : pipe_handle(loop.handle()) { - int fd; + int fd{}; if ((fd = open(path.c_str(), O_RDONLY | O_NONBLOCK)) == -1) { throw system_error("Failed to open pipe '" + path + "'"); } @@ -196,7 +196,7 @@ namespace ipc { /** * Receive parts of an IPC message */ - void ipc::receive_data(string buf) { + void ipc::receive_data(const string& buf) { m_pipe_buffer += buf; m_log.warn("Using the named pipe at '%s' for ipc is deprecated, always use 'polybar-msg'", m_pipe_path); diff --git a/src/polybar-msg.cpp b/src/polybar-msg.cpp index 7cc5d81a..1d856ec1 100644 --- a/src/polybar-msg.cpp +++ b/src/polybar-msg.cpp @@ -260,13 +260,13 @@ int run(int argc, char** argv) { /* * Index to decoder is captured because reference can be invalidated due to the vector being modified. */ - int idx = decoders.size() - 1; + auto idx = decoders.size() - 1; auto conn = loop.handle(); conn->connect( channel, - [&conn, &decoders, pid, type, payload, channel, idx]() { - on_connection(*conn, decoders[idx], pid, type, payload); + [&handle = *conn, &decoders, pid, type, payload, channel, idx]() { + on_connection(handle, decoders[idx], pid, type, payload); }, [&](const auto& e) { fprintf(stderr, "%s: Failed to connect to '%s' (err: '%s')\n", exec, channel.c_str(), uv_strerror(e.status));