[Spice-devel] [server PATCH 0/8] use a SAFE version of RING_FOREACH (worker/channel)

Uri Lublin uril at redhat.com
Mon Jul 8 03:32:22 PDT 2013


If in RING_FOREACH (in == somewhere in the callee-tree) there is
a call to read or write, it is not safe, and RING_FOREACH_SAFE
should be used.

A call to such read/write that fails, may lead
to disconnecting from the client, which means
cleaning up things, and possibly removing from the ring
the specific node (channel/client) that is currently
being iterated by the FOREACH loop.

When the FOREACH loop tries to get the next item, spice-server
asserts and aborts in ring_next():
 -- assertion `pos->next != NULL && pos->prev != NULL' failed


For example (first analysis done by Yonit):
In red_worker.c (WORKER_FOREACH_DCC):
  red_pipes_add_drawable
    red_pipe_add_drawable
      red_handle_drawable_surfaces_client_synced
        red_push_surface_image
          red_channel_client_push
            red_channel_client_send
              red_peer_handle_outgoing
                reds_stream_writev (if fails -- EPIPE)
                  handler->cb->on_error = red_channel_client_disconnect()
                    red_channel_remove_client()
                      ring_remove() -- of rcc from channel.clients ring.


In red_channel.c:
Commit 53488f0275d6c8a121af49f7ac817d09ce68090d fixes two cases of
such FOREACH loops.

Since the additional cost of a SAFE loop is insignificant, I replaced
all such FOREACH macros in red_worker.

In most pacthes, of red_worker, a FOREACH macro is modified to be safe.
In the last patch of red_worker, a generic SAFE_FOREACH is introduced.

If people prefer, I can reorder the patches such that generic macro is
introduced in the first patch, and the other patches to use it.

Last, the FOREACH macros can be used outside of red_worker.c.
Maybe in the future we can move it to an h-file and use it e.g. in red_worker.c


Uri Lublin (8):
  red_worker: use only RCC_FOREACH_SAFE
  red_worker: reuse DCC_FOREACH in WORKER_DCC_FOREACH
  red_worker: make WORKER_FOREACH_DCC safe
  red_worker: use only DRAWABLE_FOREACH_GLZ_SAFE
  red_worker: make DRAWABLE_FOREACH_DPI safe
  red_worker: make CCC_FOREACH safe
  red_worker: use a generic SAFE_FOREACH macro
  red_channel: replace RING_FOREACH with RING_FOREACH_SAFE in some
    places

 server/red_channel.c |    8 +-
 server/red_worker.c  |  190 +++++++++++++++++++++++---------------------------
 2 files changed, 90 insertions(+), 108 deletions(-)



More information about the Spice-devel mailing list