tevent_poll: Fix a crash in the poll backend
authorVolker Lendecke <vl@samba.org>
Thu, 31 Jan 2013 13:33:15 +0000 (14:33 +0100)
committerJeremy Allison <jra@samba.org>
Sun, 3 Feb 2013 03:52:09 +0000 (19:52 -0800)
If tevent_add_fd is immediately followed by tevent_fd_set_flags, the poll
backend crashes. This was introduced when the poll backend was prepared
for the multi-threaded python extension.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
lib/tevent/tevent_poll.c

index 44e108f8e3030f339b459e76adfbd365b67aa2af..fcf97c4649fdd54313e32165b7951c0de1872387 100644 (file)
@@ -256,7 +256,7 @@ static struct tevent_fd *poll_event_add_fd(struct tevent_context *ev,
        fde->private_data       = private_data;
        fde->handler_name       = handler_name;
        fde->location           = location;
-       fde->additional_flags   = 0;
+       fde->additional_flags   = UINT64_MAX;
        fde->additional_data    = NULL;
 
        DLIST_ADD(poll_ev->fresh, fde);
@@ -278,7 +278,20 @@ static void poll_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags)
        struct poll_event_context *poll_ev = talloc_get_type_abort(
                fde->event_ctx->additional_data, struct poll_event_context);
        uint64_t idx = fde->additional_flags;
-       uint16_t pollflags = 0;
+       uint16_t pollflags;
+
+       fde->flags = flags;
+
+       if (idx == UINT64_MAX) {
+               /*
+                * poll_event_setup_fresh not yet called after this fde was
+                * added. We don't have to do anything to transfer the changed
+                * flags to the array passed to poll(2)
+                */
+               return;
+       }
+
+       pollflags = 0;
 
        if (flags & TEVENT_FD_READ) {
                pollflags |= (POLLIN|POLLHUP);
@@ -286,10 +299,8 @@ static void poll_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags)
        if (flags & TEVENT_FD_WRITE) {
                pollflags |= (POLLOUT);
        }
-
        poll_ev->fds[idx].events = pollflags;
 
-       fde->flags = flags;
        poll_event_wake_pollthread(poll_ev);
 }