[Spice-devel] [vdagent-linux] udscs: Fix memory ownership issues with udscs_read_callback

Jonathon Jongsma jjongsma at redhat.com
Wed Nov 9 15:41:40 UTC 2016


Looks fine to me.

Acked-by: Jonathon Jongsma <jjongsma at redhat.com>


On Wed, 2016-11-09 at 11:47 +0100, Christophe Fergeau wrote:
> Before this commit, udscs_read_callback is supposed to free the
> 'data'
> buffer unless it calls udscs_destroy_connection(). It's currently not
> doing this, causing a potential double free in error cases. The udscs
> code would also leak the 'data' buffer if no udscs_read_callback is
> set.
> 
> This commit moves ownership of the 'data' buffer to the generic code
> calling the udscs_read_callback and fixes the memory management of
> this
> 'data' buffer. As the only udscs_read_callback currently implemented
> is
> not keeping pointers to 'data' after it returns, this should not
> cause
> any issues.
> ---
>  src/udscs.c             | 2 ++
>  src/udscs.h             | 7 ++++---
>  src/vdagentd/vdagentd.c | 4 ----
>  3 files changed, 6 insertions(+), 7 deletions(-)
> 
> diff --git a/src/udscs.c b/src/udscs.c
> index 427a844..b468e71 100644
> --- a/src/udscs.c
> +++ b/src/udscs.c
> @@ -132,6 +132,7 @@ void udscs_destroy_connection(struct
> udscs_connection **connp)
>      }
>  
>      free(conn->data.buf);
> +    conn->data.buf = NULL;
>  
>      if (conn->next)
>          conn->next->prev = conn->prev;
> @@ -235,6 +236,7 @@ static void udscs_read_complete(struct
> udscs_connection **connp)
>          if (!*connp) /* Was the connection disconnected by the
> callback ? */
>              return;
>      }
> +    free(conn->data.buf);
>  
>      conn->header_read = 0;
>      memset(&conn->data, 0, sizeof(conn->data));
> diff --git a/src/udscs.h b/src/udscs.h
> index d65630d..6e960f8 100644
> --- a/src/udscs.h
> +++ b/src/udscs.h
> @@ -39,9 +39,10 @@ struct udscs_message_header {
>  };
>  
>  /* Callbacks with this type will be called when a complete message
> has been
> - * received. The callback is responsible for free()-ing the data
> buffer. It
> - * may call udscs_destroy_connection, in which case *connp must be
> made NULL
> - * (which udscs_destroy_connection takes care of).
> + * received. The callback does not own the data buffer and should
> not free it.
> + * The data buffer will be freed shortly after the read callback
> returns.
> + * The callback may call udscs_destroy_connection, in which case
> *connp must be
> + * made NULL (which udscs_destroy_connection takes care of).
>   */
>  typedef void (*udscs_read_callback)(struct udscs_connection **connp,
>      struct udscs_message_header *header, uint8_t *data);
> diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
> index 18e82a7..a1faf23 100644
> --- a/src/vdagentd/vdagentd.c
> +++ b/src/vdagentd/vdagentd.c
> @@ -727,7 +727,6 @@ static void agent_read_complete(struct
> udscs_connection **connp,
>          if (header->arg1 == 0 && header->arg2 == 0) {
>              syslog(LOG_INFO, "got old session agent xorg resolution
> message, "
>                               "ignoring");
> -            free(data);
>              return;
>          }
>  
> @@ -735,7 +734,6 @@ static void agent_read_complete(struct
> udscs_connection **connp,
>              syslog(LOG_ERR, "guest xorg resolution message has wrong
> size, "
>                              "disconnecting agent");
>              udscs_destroy_connection(connp);
> -            free(data);
>              return;
>          }
>  
> @@ -760,7 +758,6 @@ static void agent_read_complete(struct
> udscs_connection **connp,
>      case VDAGENTD_CLIPBOARD_RELEASE:
>          if (do_agent_clipboard(*connp, header, data)) {
>              udscs_destroy_connection(connp);
> -            free(data);
>              return;
>          }
>          break;
> @@ -783,7 +780,6 @@ static void agent_read_complete(struct
> udscs_connection **connp,
>          syslog(LOG_ERR, "unknown message from vdagent: %u,
> ignoring",
>                 header->type);
>      }
> -    free(data);
>  }
>  
>  /* main */


More information about the Spice-devel mailing list