Skip to content

Commit 8e4f37d

Browse files
committed
zsock: Check native socket in zsock_resolve before ZMQ socket
Especially in Windows (at least on builds using MSVC), `zsock_resolve` randomly (but quite often) segfaults if the passed pointer is actually pointing to a native `SOCKET` instead of zactor, zsock, or a ZMQ socket. This happens because `zmq_getsockopt` tries to check if, after casting, the pointer points to an object with specific tag (`check_tag()`). Unfortunately, reading this area of memory is often an access violation if the pointer actually pointed to a `SOCKET` (which is a smaller data type). It seems that checking if the pointer is to a native socket first before checking if it is a ZMQ socket fixes this, so these checks were reordered. Resolves #2300
1 parent 2955e21 commit 8e4f37d

1 file changed

Lines changed: 10 additions & 6 deletions

File tree

src/zsock.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,13 +1845,10 @@ zsock_resolve (void *self)
18451845
if (zsock_is (self))
18461846
return ((zsock_t *) self)->handle;
18471847

1848-
// Check if we have a valid ZMQ socket by probing the socket type
1849-
int type;
1850-
size_t option_len = sizeof (int);
1851-
if (zmq_getsockopt (self, ZMQ_TYPE, &type, &option_len) == 0)
1852-
return self;
1853-
18541848
// Check if self is a valid FD or socket FD
1849+
// We need to check this before zmq_getsockopt, because tag check may
1850+
// cause a segfault if we are checking a native SOCKET (since the data
1851+
// type is smaller than the full object).
18551852
// TODO: this code should move to zsys_isfd () as we don't like
18561853
// non-portable code outside of that class.
18571854
int sock_type = -1;
@@ -1866,6 +1863,13 @@ zsock_resolve (void *self)
18661863
if (rc == 0 || (rc == -1 && errno == ENOTSOCK))
18671864
return NULL; // It's a socket FD or FD
18681865
#endif
1866+
1867+
// Check if we have a valid ZMQ socket by probing the socket type
1868+
int type;
1869+
size_t option_len = sizeof (int);
1870+
if (zmq_getsockopt (self, ZMQ_TYPE, &type, &option_len) == 0)
1871+
return self;
1872+
18691873
// Socket appears to be something else, return it as-is
18701874
return self;
18711875
}

0 commit comments

Comments
 (0)