Skip to content

zsock_resolve test case #2298

Open
Open
@calvin2021y

Description

in zsock.c test function:

    SOCKET fd = zsock_fd (reader);
    assert (zsock_resolve ((void *) &fd) == NULL);

get this error:

==25857==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ff7bfefe430 at pc 0x0001003198e8 bp 0x7ff7bfefdbd0 sp 0x7ff7bfefdbc8
READ of size 4 at 0x7ff7bfefe430 thread T0
    #0 0x1003198e7 in zmq::socket_base_t::check_tag() const+0x57 (tests_zmq.exe:x86_64+0x1003198e7)
    #1 0x10035ad57 in as_socket_base_t(void*)+0x27 (tests_zmq.exe:x86_64+0x10035ad57)
    #2 0x10035ae7f in zmq_getsockopt+0x1f (tests_zmq.exe:x86_64+0x10035ae7f)
    #3 0x10014faa1 in zsock_resolve+0x231 (tests_zmq.exe:x86_64+0x10014faa1)
    #4 0x1001858d6 in zsock_test+0x10b6 (tests_zmq.exe:x86_64+0x1001858d6)
    #5 0x10006fa45 in main+0xb5 (tests_zmq.exe:x86_64+0x10006fa45)
    #6 0x7ff8117e141e in start+0x76e (dyld:x86_64+0xfffffffffff6e41e)

the zsock_resolve call zmq_getsockopt first then call getsockopt:

void *
zsock_resolve (void *self)
{
    assert (self);
    if (zactor_is (self))
        return zactor_resolve (self);

    if (zsock_is (self))
        return ((zsock_t *) self)->handle;

    //  Check if we have a valid ZMQ socket by probing the socket type
    int type;
    size_t option_len = sizeof (int);
    if (zmq_getsockopt (self, ZMQ_TYPE, &type, &option_len) == 0)
        return self;

    //  Check if self is a valid FD or socket FD
    //  TODO: this code should move to zsys_isfd () as we don't like
    //  non-portable code outside of that class.
    int sock_type = -1;
#if defined (__WINDOWS__)
    int sock_type_size = sizeof (int);
    int rc = getsockopt (*(SOCKET *) self, SOL_SOCKET, SO_TYPE, (char *) &sock_type, &sock_type_size);
    if (rc == 0)
        return NULL;        //  It's a socket descriptor
#else
    socklen_t sock_type_size = sizeof (socklen_t);
    int rc = getsockopt (*(SOCKET *) self, SOL_SOCKET, SO_TYPE, (char *) &sock_type, &sock_type_size);
    if (rc == 0 || (rc == -1 && errno == ENOTSOCK))
        return NULL;        //  It's a socket FD or FD
#endif
    //  Socket appears to be something else, return it as-is
    return self;
}

the zmq_getsockopt use fd pointer as zmq::socket_base_t pointer, fd is 4 byte stack memory, so stack-use-after-scope to use as zmq::socket_base_t ( you can not guarantee the fd pointer offset is not tag value 0xbaddecaf ).

int zmq_getsockopt (void *s_, int option_, void *optval_, size_t *optvallen_)
{
    zmq::socket_base_t *s = as_socket_base_t (s_);
    if (!s)
        return -1;
    return s->getsockopt (option_, optval_, optvallen_);
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions