[zeromq-dev] zmq and abstract unix domain sockets

Dhammika Pathirana dhammika at gmail.com
Fri Dec 10 08:14:34 CET 2010


Hi Moritz,

On Wed, Dec 8, 2010 at 12:07 AM, Moritz Rosenthal <mr at m2mgermany.de> wrote:
> Hi,
>
> I posted an issue at github:
> https://github.com/zeromq/zeromq2/issues#issue/134
>
> The only reply was that this topic should be discussed in the mailing
> list. As there hasn't started any discussion about it yet I'll start one.
>
> The problem is that abstract unix domain sockets of the style
> "\0mysocketname" are accepted, but not handled correctly. I posted some
> example here: http://paste.pocoo.org/show/300124/
>


It's probably creating a socket as "\0", check in /proc/net/unix.
Second bind with "\0anothersock" will also try to bind to "\0" and it
should fail
with EADDRINUSE. But unlink() in close() is clobbering errno, I've attached a
patch below.

We'd also want to double check following unlink() call, think it allows another
process to hijack listening socket.

215     else if (strcmp (protocol_, "ipc") == 0) {
216
217         //  Get rid of the file associated with the UNIX domain socket that
218         //  may have been left behind by the previous run of the
application.
219         ::unlink (addr_);
220



>From 79b05df46e454106fa63fbda435e8ca396a09063 Mon Sep 17 00:00:00 2001
From: Dhammika Pathirana <dhammika at gmail.com>
Date: Thu, 9 Dec 2010 22:35:40 -0800
Subject: [PATCH] fix unix domain socket addrlen


Signed-off-by: Dhammika Pathirana <dhammika at gmail.com>
---
 src/ip.cpp           |    2 +-
 src/tcp_listener.cpp |    8 ++++----
 src/tcp_listener.hpp |    2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/ip.cpp b/src/ip.cpp
index eb05aec..14744ab 100644
--- a/src/ip.cpp
+++ b/src/ip.cpp
@@ -324,7 +324,7 @@ int zmq::resolve_local_path (sockaddr_storage
*addr_, socklen_t *addr_len_,
     }
     strcpy (un->sun_path, path_);
     un->sun_family = AF_UNIX;
-    *addr_len_ = sizeof (sockaddr_un);
+    *addr_len_ = sizeof (un->sun_family) + strlen (path_) + 1;
     return 0;
 }

diff --git a/src/tcp_listener.cpp b/src/tcp_listener.cpp
index 6d41069..0693b01 100644
--- a/src/tcp_listener.cpp
+++ b/src/tcp_listener.cpp
@@ -236,9 +236,9 @@ int zmq::tcp_listener_t::set_address (const char
*protocol_, const char *addr_,
         errno_assert (rc != -1);

         //  Bind the socket to the file path.
-        rc = bind (s, (struct sockaddr*) &addr, sizeof (sockaddr_un));
+        rc = bind (s, (struct sockaddr*) &addr, addr_len);
         if (rc != 0) {
-            close ();
+            close (false);
             return -1;
         }

@@ -258,7 +258,7 @@ int zmq::tcp_listener_t::set_address (const char
*protocol_, const char *addr_,
     }
 }

-int zmq::tcp_listener_t::close ()
+int zmq::tcp_listener_t::close (bool unlink)
 {
     zmq_assert (s != retired_fd);
     int rc = ::close (s);
@@ -270,7 +270,7 @@ int zmq::tcp_listener_t::close ()
     //  If there's an underlying UNIX domain socket, get rid of the file it
     //  is associated with.
     struct sockaddr_un *su = (struct sockaddr_un*) &addr;
-    if (AF_UNIX == su->sun_family) {
+    if (AF_UNIX == su->sun_family && unlink) {
         rc = ::unlink(su->sun_path);
         if (rc != 0)
             return -1;
diff --git a/src/tcp_listener.hpp b/src/tcp_listener.hpp
index 1490a56..9107f10 100644
--- a/src/tcp_listener.hpp
+++ b/src/tcp_listener.hpp
@@ -40,7 +40,7 @@ namespace zmq
             int backlog_);

         //  Close the listening socket.
-        int close ();
+        int close (bool unlink = true);

         //  Get the file descriptor to poll on to get notified about
         //  newly created connections.
-- 
1.7.0.4



Dhammika



More information about the zeromq-dev mailing list