From b74c0c1ebcb6062cac53a8716cfabf7d94420dc4 Mon Sep 17 00:00:00 2001 From: Tad Glines Date: Wed, 17 Nov 2021 13:24:57 -0800 Subject: [PATCH] Add support for abstract UDS addresses (#90) --- OutputInputTests.cpp | 6 +++--- UnixDomainListener.cpp | 26 ++++++++++++++++++++------ UnixDomainWriter.cpp | 10 ++++++++++ 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/OutputInputTests.cpp b/OutputInputTests.cpp index 45e3542..e46b04e 100644 --- a/OutputInputTests.cpp +++ b/OutputInputTests.cpp @@ -61,7 +61,7 @@ int GetEventSeq(const Event& event) { BOOST_AUTO_TEST_CASE( basic_test ) { TempDir dir("/tmp/OutputInputTests"); - std::string socket_path = dir.Path() + "/input.socket"; + std::string socket_path = "@input.socket@@@@"; std::string status_socket_path = dir.Path() + "/status.socket"; std::mutex log_mutex; @@ -160,7 +160,7 @@ BOOST_AUTO_TEST_CASE( basic_test ) { BOOST_AUTO_TEST_CASE( same_event_id_test ) { TempDir dir("/tmp/OutputInputTests"); - std::string socket_path = dir.Path() + "/input.socket"; + std::string socket_path = "@input.socket@@@@@@"; std::string status_socket_path = dir.Path() + "/status.socket"; std::mutex log_mutex; @@ -260,7 +260,7 @@ BOOST_AUTO_TEST_CASE( same_event_id_test ) { BOOST_AUTO_TEST_CASE( dropped_acks_test ) { TempDir dir("/tmp/OutputInputTests"); - std::string socket_path = dir.Path() + "/input.socket"; + std::string socket_path = "@input.socket@@@@@@"; std::string status_socket_path = dir.Path() + "/status.socket"; std::mutex log_mutex; diff --git a/UnixDomainListener.cpp b/UnixDomainListener.cpp index fda7b4d..730d604 100644 --- a/UnixDomainListener.cpp +++ b/UnixDomainListener.cpp @@ -46,7 +46,19 @@ bool UnixDomainListener::Open() { addr.sun_family = AF_UNIX; _socket_path.copy(addr.sun_path, sizeof(addr.sun_path)); - unlink(_socket_path.c_str()); + // If the first character is a '@', then this is an abstract socket address + // Replace all '@' bytes with null bytes. + if (addr.sun_path[0] == '@') { + for (int i = 0; i < sizeof(addr.sun_path); i++) { + if (addr.sun_path[i] == '@') { + addr.sun_path[i] = 0; + } + } + } + + if (addr.sun_path[0] != 0) { + unlink(_socket_path.c_str()); + } if (bind(lfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { @@ -55,11 +67,13 @@ bool UnixDomainListener::Open() { return false; } - // Only allow process uid access to the socket file - if (chmod(_socket_path.c_str(), _socket_file_mode) < 0) { - close(lfd); - Logger::Error("Inputs: chmod('%s', 0%03o) failed: %s", _socket_path.c_str(), _socket_file_mode, std::strerror(errno)); - return false; + if (addr.sun_path[0] != 0) { + // Only allow process uid access to the socket file + if (chmod(_socket_path.c_str(), _socket_file_mode) < 0) { + close(lfd); + Logger::Error("Inputs: chmod('%s', 0%03o) failed: %s", _socket_path.c_str(), _socket_file_mode, std::strerror(errno)); + return false; + } } if (listen(lfd, 5) != 0) { diff --git a/UnixDomainWriter.cpp b/UnixDomainWriter.cpp index 1b86e5b..eb1c384 100644 --- a/UnixDomainWriter.cpp +++ b/UnixDomainWriter.cpp @@ -36,6 +36,16 @@ bool UnixDomainWriter::Open() unaddr.sun_family = AF_UNIX; _addr.copy(unaddr.sun_path, sizeof(unaddr.sun_path)); + // If the first character is a '@', then this is an abstract socket address + // Replace all '@' bytes with null bytes. + if (unaddr.sun_path[0] == '@') { + for (int i = 0; i < sizeof(unaddr.sun_path); i++) { + if (unaddr.sun_path[i] == '@') { + unaddr.sun_path[i] = 0; + } + } + } + int fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0); if (-1 == fd) { throw std::system_error(errno, std::system_category(), "socket() failed");