[Spice-devel] [PATCH] reset pointer to RedCharDeviceWriteBuffer calling red_char_device_write_buffer_release

Frediano Ziglio fziglio at redhat.com
Mon May 9 13:21:04 UTC 2016


This code make easier to be sure we don't have dangling pointers
resetting in the function which free the structure.

Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
 server/char-device.c | 21 ++++++++++-----------
 server/char-device.h |  2 +-
 server/reds.c        |  3 ++-
 server/smartcard.c   |  3 +--
 server/spicevmc.c    | 17 ++++++-----------
 5 files changed, 20 insertions(+), 26 deletions(-)

diff --git a/server/char-device.c b/server/char-device.c
index 055b232..b67e192 100644
--- a/server/char-device.c
+++ b/server/char-device.c
@@ -506,9 +506,7 @@ static int red_char_device_write_to_device(RedCharDevice *dev)
         total += n;
         write_len -= n;
         if (!write_len) {
-            RedCharDeviceWriteBuffer *release_buf = dev->priv->cur_write_buf;
-            dev->priv->cur_write_buf = NULL;
-            red_char_device_write_buffer_release(dev, release_buf);
+            red_char_device_write_buffer_release(dev, &dev->priv->cur_write_buf);
             continue;
         }
         dev->priv->cur_write_buf_pos += n;
@@ -650,8 +648,14 @@ void red_char_device_write_buffer_add(RedCharDevice *dev,
 }
 
 void red_char_device_write_buffer_release(RedCharDevice *dev,
-                                          RedCharDeviceWriteBuffer *write_buf)
+                                          RedCharDeviceWriteBuffer **p_write_buf)
 {
+    RedCharDeviceWriteBuffer *write_buf = *p_write_buf;
+    if (!write_buf) {
+        return;
+    }
+    *p_write_buf = NULL;
+
     int buf_origin = write_buf->origin;
     uint32_t buf_token_price = write_buf->token_price;
     RedClient *client = write_buf->client;
@@ -835,14 +839,9 @@ void red_char_device_reset(RedCharDevice *dev)
         ring_remove(item);
         buf = SPICE_CONTAINEROF(item, RedCharDeviceWriteBuffer, link);
         /* tracking the tokens */
-        red_char_device_write_buffer_release(dev, buf);
-    }
-    if (dev->priv->cur_write_buf) {
-        RedCharDeviceWriteBuffer *release_buf = dev->priv->cur_write_buf;
-
-        dev->priv->cur_write_buf = NULL;
-        red_char_device_write_buffer_release(dev, release_buf);
+        red_char_device_write_buffer_release(dev, &buf);
     }
+    red_char_device_write_buffer_release(dev, &dev->priv->cur_write_buf);
 
     RING_FOREACH(client_item, &dev->priv->clients) {
         RedCharDeviceClient *dev_client;
diff --git a/server/char-device.h b/server/char-device.h
index d05b1fd..ff43baa 100644
--- a/server/char-device.h
+++ b/server/char-device.h
@@ -228,7 +228,7 @@ RedCharDeviceWriteBuffer *red_char_device_write_buffer_get_server_no_token(
 void red_char_device_write_buffer_add(RedCharDevice *dev,
                                         RedCharDeviceWriteBuffer *write_buf);
 void red_char_device_write_buffer_release(RedCharDevice *dev,
-                                            RedCharDeviceWriteBuffer *write_buf);
+                                          RedCharDeviceWriteBuffer **p_write_buf);
 
 /* api for specific char devices */
 
diff --git a/server/reds.c b/server/reds.c
index f54534a..f0ebf0c 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -1131,9 +1131,10 @@ void reds_release_agent_data_buffer(RedsState *reds, uint8_t *buf)
     }
 
     spice_assert(buf == dev->priv->recv_from_client_buf->buf + sizeof(VDIChunkHeader));
+    /* if we pushed the buffer the buffer is attached to the channel so don't free it */
     if (!dev->priv->recv_from_client_buf_pushed) {
         red_char_device_write_buffer_release(RED_CHAR_DEVICE(reds->agent_dev),
-                                             dev->priv->recv_from_client_buf);
+                                             &dev->priv->recv_from_client_buf);
     }
     dev->priv->recv_from_client_buf = NULL;
     dev->priv->recv_from_client_buf_pushed = FALSE;
diff --git a/server/smartcard.c b/server/smartcard.c
index a42bcd8..e483eec 100644
--- a/server/smartcard.c
+++ b/server/smartcard.c
@@ -420,8 +420,7 @@ static void smartcard_channel_release_msg_rcv_buf(RedChannelClient *rcc,
     } else {
         if (scc->write_buf) { /* msg hasn't been pushed to the guest */
             spice_assert(scc->write_buf->buf == msg);
-            red_char_device_write_buffer_release(RED_CHAR_DEVICE(scc->smartcard), scc->write_buf);
-            scc->write_buf = NULL;
+            red_char_device_write_buffer_release(RED_CHAR_DEVICE(scc->smartcard), &scc->write_buf);
         }
     }
 }
diff --git a/server/spicevmc.c b/server/spicevmc.c
index 283a8f0..bdaa3c3 100644
--- a/server/spicevmc.c
+++ b/server/spicevmc.c
@@ -224,10 +224,8 @@ static void spicevmc_red_channel_client_on_disconnect(RedChannelClient *rcc)
 
     state = spicevmc_red_channel_client_get_state(rcc);
 
-    if (state->recv_from_client_buf) { /* partial message which wasn't pushed to device */
-        red_char_device_write_buffer_release(state->chardev, state->recv_from_client_buf);
-        state->recv_from_client_buf = NULL;
-    }
+    /* partial message which wasn't pushed to device */
+    red_char_device_write_buffer_release(state->chardev, &state->recv_from_client_buf);
 
     if (state->chardev) {
         if (red_char_device_client_exists(state->chardev, rcc->client)) {
@@ -349,10 +347,8 @@ static void spicevmc_red_channel_release_msg_rcv_buf(RedChannelClient *rcc,
 
     switch (type) {
     case SPICE_MSGC_SPICEVMC_DATA:
-        if (state->recv_from_client_buf) { /* buffer wasn't pushed to device */
-            red_char_device_write_buffer_release(state->chardev, state->recv_from_client_buf);
-            state->recv_from_client_buf = NULL;
-        }
+        /* buffer wasn't pushed to device */
+        red_char_device_write_buffer_release(state->chardev, &state->recv_from_client_buf);
         break;
     default:
         free(msg);
@@ -545,9 +541,8 @@ void spicevmc_device_disconnect(RedsState *reds, SpiceCharDeviceInstance *sin)
     /* FIXME */
     state = (SpiceVmcState *)red_char_device_opaque_get((RedCharDevice*)sin->st);
 
-    if (state->recv_from_client_buf) {
-        red_char_device_write_buffer_release(state->chardev, state->recv_from_client_buf);
-    }
+    red_char_device_write_buffer_release(state->chardev, &state->recv_from_client_buf);
+
     /* FIXME */
     red_char_device_destroy((RedCharDevice*)sin->st);
     state->chardev = NULL;
-- 
2.5.5



More information about the Spice-devel mailing list