diff options
author | Yonit Halperin <yhalperi@redhat.com> | 2012-01-05 17:31:34 +0200 |
---|---|---|
committer | Yonit Halperin <yhalperi@redhat.com> | 2012-01-12 16:17:02 +0200 |
commit | 8b64b95c4339c145867e42f71b3206378bc7c83b (patch) | |
tree | 1c1ade429b293ce64fb75eae56831a61a4c4fd6b | |
parent | a54f26d04e9a391977a8030d609b52e50243ba52 (diff) | |
download | spice-8b64b95c4339c145867e42f71b3206378bc7c83b.tar.gz spice-8b64b95c4339c145867e42f71b3206378bc7c83b.tar.xz spice-8b64b95c4339c145867e42f71b3206378bc7c83b.zip |
server: Limit the access to SpiceDataHeader of messages - only via red_channel.
-rw-r--r-- | server/inputs_channel.c | 10 | ||||
-rw-r--r-- | server/main_channel.c | 8 | ||||
-rw-r--r-- | server/red_channel.c | 34 | ||||
-rw-r--r-- | server/red_channel.h | 24 | ||||
-rw-r--r-- | server/red_tunnel_worker.c | 43 | ||||
-rw-r--r-- | server/red_worker.c | 9 | ||||
-rw-r--r-- | server/smartcard.c | 18 | ||||
-rw-r--r-- | server/spicevmc.c | 24 |
8 files changed, 99 insertions, 71 deletions
diff --git a/server/inputs_channel.c b/server/inputs_channel.c index 0fa41629..4fe36b8e 100644 --- a/server/inputs_channel.c +++ b/server/inputs_channel.c @@ -168,18 +168,22 @@ const VDAgentMouseState *inputs_get_mouse_state(void) return &g_inputs_channel->mouse_state; } -static uint8_t *inputs_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, SpiceDataHeader *msg_header) +static uint8_t *inputs_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, + uint16_t type, + uint32_t size) { InputsChannel *inputs_channel = SPICE_CONTAINEROF(rcc->channel, InputsChannel, base); - if (msg_header->size > RECEIVE_BUF_SIZE) { + if (size > RECEIVE_BUF_SIZE) { red_printf("error: too large incoming message"); return NULL; } return inputs_channel->recv_buf; } -static void inputs_channel_release_msg_rcv_buf(RedChannelClient *rcc, SpiceDataHeader *msg_header, +static void inputs_channel_release_msg_rcv_buf(RedChannelClient *rcc, + uint16_t type, + uint32_t size, uint8_t *msg) { } diff --git a/server/main_channel.c b/server/main_channel.c index 4b5b6698..b55bf002 100644 --- a/server/main_channel.c +++ b/server/main_channel.c @@ -852,14 +852,18 @@ static int main_channel_handle_parsed(RedChannelClient *rcc, uint32_t size, uint return TRUE; } -static uint8_t *main_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, SpiceDataHeader *msg_header) +static uint8_t *main_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, + uint16_t type, + uint32_t size) { MainChannel *main_chan = SPICE_CONTAINEROF(rcc->channel, MainChannel, base); return main_chan->recv_buf; } -static void main_channel_release_msg_rcv_buf(RedChannelClient *rcc, SpiceDataHeader *msg_header, +static void main_channel_release_msg_rcv_buf(RedChannelClient *rcc, + uint16_t type, + uint32_t size, uint8_t *msg) { } diff --git a/server/red_channel.c b/server/red_channel.c index 671bcf58..06b4ef0f 100644 --- a/server/red_channel.c +++ b/server/red_channel.c @@ -103,7 +103,9 @@ static void red_peer_handle_incoming(RedsStream *stream, IncomingHandler *handle if (handler->msg_pos < handler->header.size) { if (!handler->msg) { - handler->msg = handler->cb->alloc_msg_buf(handler->opaque, &handler->header); + handler->msg = handler->cb->alloc_msg_buf(handler->opaque, + handler->header.type, + handler->header.size); if (handler->msg == NULL) { red_printf("ERROR: channel refused to allocate buffer."); handler->cb->on_error(handler->opaque); @@ -115,7 +117,10 @@ static void red_peer_handle_incoming(RedsStream *stream, IncomingHandler *handle handler->msg + handler->msg_pos, handler->header.size - handler->msg_pos); if (bytes_read == -1) { - handler->cb->release_msg_buf(handler->opaque, &handler->header, handler->msg); + handler->cb->release_msg_buf(handler->opaque, + handler->header.type, + handler->header.size, + handler->msg); handler->cb->on_error(handler->opaque); return; } @@ -131,7 +136,9 @@ static void red_peer_handle_incoming(RedsStream *stream, IncomingHandler *handle SPICE_VERSION_MINOR, &parsed_size, &parsed_free); if (parsed == NULL) { red_printf("failed to parse message type %d", handler->header.type); - handler->cb->release_msg_buf(handler->opaque, &handler->header, handler->msg); + handler->cb->release_msg_buf(handler->opaque, handler->header.type, + handler->header.size, + handler->msg); handler->cb->on_error(handler->opaque); return; } @@ -139,11 +146,16 @@ static void red_peer_handle_incoming(RedsStream *stream, IncomingHandler *handle handler->header.type, parsed); parsed_free(parsed); } else { - ret_handle = handler->cb->handle_message(handler->opaque, &handler->header, - handler->msg); + ret_handle = handler->cb->handle_message(handler->opaque, + handler->header.type, + handler->header.size, + handler->msg); } handler->msg_pos = 0; - handler->cb->release_msg_buf(handler->opaque, &handler->header, handler->msg); + handler->cb->release_msg_buf(handler->opaque, + handler->header.type, + handler->header.size, + handler->msg); handler->msg = NULL; handler->header_pos = 0; @@ -586,7 +598,10 @@ RedChannel *red_channel_create_dummy(int size, uint32_t type, uint32_t id) return channel; } -static int do_nothing_handle_message(RedChannelClient *rcc, SpiceDataHeader *header, uint8_t *msg) +static int do_nothing_handle_message(RedChannelClient *rcc, + uint16_t type, + uint32_t size, + uint8_t *msg) { return TRUE; } @@ -1204,10 +1219,11 @@ RedClient *red_channel_client_get_client(RedChannelClient *rcc) return rcc->client; } -SpiceDataHeader *red_channel_client_get_header(RedChannelClient *rcc) +void red_channel_client_set_header_sub_list(RedChannelClient *rcc, uint32_t sub_list) { - return rcc->send_data.header; + rcc->send_data.header->sub_list = sub_list; } + /* end of accessors */ int red_channel_get_first_socket(RedChannel *channel) diff --git a/server/red_channel.h b/server/red_channel.h index cb80100e..40792c1b 100644 --- a/server/red_channel.h +++ b/server/red_channel.h @@ -38,11 +38,11 @@ At the final stage, this interface shouldn't be exposed. Only RedChannel will use it. */ typedef int (*handle_message_proc)(void *opaque, - SpiceDataHeader *header, uint8_t *msg); + uint16_t type, uint32_t size, uint8_t *msg); typedef int (*handle_parsed_proc)(void *opaque, uint32_t size, uint16_t type, void *message); -typedef uint8_t *(*alloc_msg_recv_buf_proc)(void *opaque, SpiceDataHeader *msg_header); +typedef uint8_t *(*alloc_msg_recv_buf_proc)(void *opaque, uint16_t type, uint32_t size); typedef void (*release_msg_recv_buf_proc)(void *opaque, - SpiceDataHeader *msg_header, uint8_t *msg); + uint16_t type, uint32_t size, uint8_t *msg); typedef void (*on_incoming_error_proc)(void *opaque); typedef struct IncomingHandlerInterface { @@ -119,13 +119,13 @@ typedef struct PipeItem { } PipeItem; typedef uint8_t *(*channel_alloc_msg_recv_buf_proc)(RedChannelClient *channel, - SpiceDataHeader *msg_header); + uint16_t type, uint32_t size); typedef int (*channel_handle_parsed_proc)(RedChannelClient *rcc, uint32_t size, uint16_t type, void *message); typedef int (*channel_handle_message_proc)(RedChannelClient *rcc, - SpiceDataHeader *header, uint8_t *msg); + uint16_t type, uint32_t size, uint8_t *msg); typedef void (*channel_release_msg_recv_buf_proc)(RedChannelClient *channel, - SpiceDataHeader *msg_header, uint8_t *msg); + uint16_t type, uint32_t size, uint8_t *msg); typedef void (*channel_disconnect_proc)(RedChannelClient *rcc); typedef int (*channel_configure_socket_proc)(RedChannelClient *rcc); typedef void (*channel_send_pipe_item_proc)(RedChannelClient *rcc, PipeItem *item); @@ -334,7 +334,7 @@ void red_channel_init_outgoing_messages_window(RedChannel *channel); /* handles general channel msgs from the client */ int red_channel_client_handle_message(RedChannelClient *rcc, uint32_t size, - uint16_t type, void *message); + uint16_t type, void *message); /* when preparing send_data: should call init and then use marshaller */ void red_channel_client_init_send_data(RedChannelClient *rcc, uint16_t msg_type, PipeItem *item); @@ -444,13 +444,9 @@ SpiceMarshaller *red_channel_client_get_marshaller(RedChannelClient *rcc); RedsStream *red_channel_client_get_stream(RedChannelClient *rcc); RedClient *red_channel_client_get_client(RedChannelClient *rcc); -/* this is a convenience function for sending messages, sometimes (migration only?) - * the serial from the header needs to be available for sending. Note that the header - * pointer retrieved is not valid except between red_channel_reset_send_data and - * red_channel_begin_send_message. red_channel_init_send_data changes the header (sets - * the type in it) as a convenience function. It is preffered to do that through it and - * not via the below accessor and direct header manipulation. */ -SpiceDataHeader *red_channel_client_get_header(RedChannelClient *rcc); +/* Note that the header is valid only between red_channel_reset_send_data and + * red_channel_begin_send_message.*/ +void red_channel_client_set_header_sub_list(RedChannelClient *rcc, uint32_t sub_list); /* return the sum of all the rcc pipe size */ uint32_t red_channel_max_pipe_size(RedChannel *channel); diff --git a/server/red_tunnel_worker.c b/server/red_tunnel_worker.c index 1e8267e8..250e8b3e 100644 --- a/server/red_tunnel_worker.c +++ b/server/red_tunnel_worker.c @@ -1644,27 +1644,27 @@ static int tunnel_channel_handle_socket_token(TunnelChannelClient *channel, RedS } static uint8_t *tunnel_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, - SpiceDataHeader *msg_header) + uint16_t type, uint32_t size) { TunnelChannelClient *tunnel_channel = (TunnelChannelClient *)rcc->channel; - if (msg_header->type == SPICE_MSGC_TUNNEL_SOCKET_DATA) { + if (type == SPICE_MSGC_TUNNEL_SOCKET_DATA) { return (__tunnel_worker_alloc_socket_rcv_buf(tunnel_channel->worker)->buf); - } else if ((msg_header->type == SPICE_MSGC_MIGRATE_DATA) || - (msg_header->type == SPICE_MSGC_TUNNEL_SERVICE_ADD)) { - return spice_malloc(msg_header->size); + } else if ((type == SPICE_MSGC_MIGRATE_DATA) || + (type == SPICE_MSGC_TUNNEL_SERVICE_ADD)) { + return spice_malloc(size); } else { return (tunnel_channel->control_rcv_buf); } } // called by the receive routine of the channel, before the buffer was assigned to a socket -static void tunnel_channel_release_msg_rcv_buf(RedChannelClient *rcc, SpiceDataHeader *msg_header, +static void tunnel_channel_release_msg_rcv_buf(RedChannelClient *rcc, uint16_t type, uint32_t size, uint8_t *msg) { TunnelChannelClient *tunnel_channel = (TunnelChannelClient *)rcc->channel; - if (msg_header->type == SPICE_MSGC_TUNNEL_SOCKET_DATA) { + if (type == SPICE_MSGC_TUNNEL_SOCKET_DATA) { ASSERT(!(SPICE_CONTAINEROF(msg, RedSocketRawRcvBuf, buf)->base.usr_opaque)); __tunnel_worker_free_socket_rcv_buf(tunnel_channel->worker, SPICE_CONTAINEROF(msg, RedSocketRawRcvBuf, buf)); @@ -2243,12 +2243,13 @@ error: } // msg was allocated by tunnel_channel_alloc_msg_rcv_buf -static int tunnel_channel_handle_message(RedChannelClient *rcc, SpiceDataHeader *header, uint8_t *msg) +static int tunnel_channel_handle_message(RedChannelClient *rcc, uint16_t type, + uint32_t size, uint8_t *msg) { TunnelChannelClient *tunnel_channel = (TunnelChannelClient *)rcc->channel; RedSocket *sckt = NULL; // retrieve the sckt - switch (header->type) { + switch (type) { case SPICE_MSGC_MIGRATE_FLUSH_MARK: case SPICE_MSGC_MIGRATE_DATA: case SPICE_MSGC_TUNNEL_SERVICE_ADD: @@ -2269,12 +2270,12 @@ static int tunnel_channel_handle_message(RedChannelClient *rcc, SpiceDataHeader } break; default: - return red_channel_client_handle_message(rcc, header->size, header->type, msg); + return red_channel_client_handle_message(rcc, size, type, msg); } - switch (header->type) { + switch (type) { case SPICE_MSGC_TUNNEL_SERVICE_ADD: - if (header->size < sizeof(SpiceMsgcTunnelAddGenericService)) { + if (size < sizeof(SpiceMsgcTunnelAddGenericService)) { red_printf("bad message size"); free(msg); return FALSE; @@ -2285,7 +2286,7 @@ static int tunnel_channel_handle_message(RedChannelClient *rcc, SpiceDataHeader red_printf("REDC_TUNNEL_REMOVE_SERVICE not supported yet"); return FALSE; case SPICE_MSGC_TUNNEL_SOCKET_OPEN_ACK: - if (header->size != sizeof(SpiceMsgcTunnelSocketOpenAck)) { + if (size != sizeof(SpiceMsgcTunnelSocketOpenAck)) { red_printf("bad message size"); return FALSE; } @@ -2294,7 +2295,7 @@ static int tunnel_channel_handle_message(RedChannelClient *rcc, SpiceDataHeader ((SpiceMsgcTunnelSocketOpenAck *)msg)->tokens); case SPICE_MSGC_TUNNEL_SOCKET_OPEN_NACK: - if (header->size != sizeof(SpiceMsgcTunnelSocketOpenNack)) { + if (size != sizeof(SpiceMsgcTunnelSocketOpenNack)) { red_printf("bad message size"); return FALSE; } @@ -2302,35 +2303,35 @@ static int tunnel_channel_handle_message(RedChannelClient *rcc, SpiceDataHeader return tunnel_channel_handle_socket_connect_nack(tunnel_channel, sckt); case SPICE_MSGC_TUNNEL_SOCKET_DATA: { - if (header->size < sizeof(SpiceMsgcTunnelSocketData)) { + if (size < sizeof(SpiceMsgcTunnelSocketData)) { red_printf("bad message size"); return FALSE; } return tunnel_channel_handle_socket_receive_data(tunnel_channel, sckt, SPICE_CONTAINEROF(msg, RedSocketRawRcvBuf, buf), - header->size - sizeof(SpiceMsgcTunnelSocketData)); + size - sizeof(SpiceMsgcTunnelSocketData)); } case SPICE_MSGC_TUNNEL_SOCKET_FIN: - if (header->size != sizeof(SpiceMsgcTunnelSocketFin)) { + if (size != sizeof(SpiceMsgcTunnelSocketFin)) { red_printf("bad message size"); return FALSE; } return tunnel_channel_handle_socket_fin(tunnel_channel, sckt); case SPICE_MSGC_TUNNEL_SOCKET_CLOSED: - if (header->size != sizeof(SpiceMsgcTunnelSocketClosed)) { + if (size != sizeof(SpiceMsgcTunnelSocketClosed)) { red_printf("bad message size"); return FALSE; } return tunnel_channel_handle_socket_closed(tunnel_channel, sckt); case SPICE_MSGC_TUNNEL_SOCKET_CLOSED_ACK: - if (header->size != sizeof(SpiceMsgcTunnelSocketClosedAck)) { + if (size != sizeof(SpiceMsgcTunnelSocketClosedAck)) { red_printf("bad message size"); return FALSE; } return tunnel_channel_handle_socket_closed_ack(tunnel_channel, sckt); case SPICE_MSGC_TUNNEL_SOCKET_TOKEN: - if (header->size != sizeof(SpiceMsgcTunnelSocketTokens)) { + if (size != sizeof(SpiceMsgcTunnelSocketTokens)) { red_printf("bad message size"); return FALSE; } @@ -2338,7 +2339,7 @@ static int tunnel_channel_handle_message(RedChannelClient *rcc, SpiceDataHeader return tunnel_channel_handle_socket_token(tunnel_channel, sckt, (SpiceMsgcTunnelSocketTokens *)msg); default: - return red_channel_client_handle_message(rcc, header->size, header->type, msg); + return red_channel_client_handle_message(rcc, size, type, msg); } return TRUE; } diff --git a/server/red_worker.c b/server/red_worker.c index d82c84ef..f454302a 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -1517,15 +1517,15 @@ static void release_upgrade_item(RedWorker* worker, UpgradeItem *item) } } -static uint8_t *common_alloc_recv_buf(RedChannelClient *rcc, SpiceDataHeader *msg_header) +static uint8_t *common_alloc_recv_buf(RedChannelClient *rcc, uint16_t type, uint32_t size) { CommonChannel *common = SPICE_CONTAINEROF(rcc->channel, CommonChannel, base); return common->recv_buf; } -static void common_release_recv_buf(RedChannelClient *rcc, - SpiceDataHeader *msg_header, uint8_t* msg) +static void common_release_recv_buf(RedChannelClient *rcc, uint16_t type, uint32_t size, + uint8_t* msg) { } @@ -7785,7 +7785,6 @@ static inline void display_begin_send_message(RedChannelClient *rcc, { DisplayChannelClient *dcc = RCC_TO_DCC(rcc); FreeList *free_list = &dcc->send_data.free_list; - SpiceDataHeader *header = red_channel_client_get_header(rcc); if (free_list->res->count) { int sub_list_len = 1; @@ -7828,7 +7827,7 @@ static inline void display_begin_send_message(RedChannelClient *rcc, spice_marshaller_add_uint32(sub_list_m, spice_marshaller_get_offset(wait_m)); } spice_marshaller_add_uint32(sub_list_m, spice_marshaller_get_offset(inval_m)); - header->sub_list = spice_marshaller_get_offset(sub_list_m); + red_channel_client_set_header_sub_list(rcc, spice_marshaller_get_offset(sub_list_m)); } red_channel_client_begin_send_message(rcc); } diff --git a/server/smartcard.c b/server/smartcard.c index f9cafdfa..08ba3da8 100644 --- a/server/smartcard.c +++ b/server/smartcard.c @@ -273,15 +273,18 @@ static int smartcard_channel_client_config_socket(RedChannelClient *rcc) } static uint8_t *smartcard_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, - SpiceDataHeader *msg_header) + uint16_t type, + uint32_t size) { - return spice_malloc(msg_header->size); + return spice_malloc(size); } static void smartcard_channel_release_msg_rcv_buf(RedChannelClient *rcc, - SpiceDataHeader *msg_header, uint8_t *msg) + uint16_t type, + uint32_t size, + uint8_t *msg) { - red_printf("freeing %d bytes", msg_header->size); + red_printf("freeing %d bytes", size); free(msg); } @@ -439,14 +442,15 @@ static void smartcard_channel_write_to_reader(VSCMsgHeader *vheader) } static int smartcard_channel_handle_message(RedChannelClient *rcc, - SpiceDataHeader *header, + uint16_t type, + uint32_t size, uint8_t *msg) { VSCMsgHeader* vheader = (VSCMsgHeader*)msg; - if (header->type != SPICE_MSGC_SMARTCARD_DATA) { + if (type != SPICE_MSGC_SMARTCARD_DATA) { /* handle ack's, spicy sends them while spicec does not */ - return red_channel_client_handle_message(rcc, header->size, header->type, msg); + return red_channel_client_handle_message(rcc, size, type, msg); } ASSERT(header->size == vheader->length + sizeof(VSCMsgHeader)); diff --git a/server/spicevmc.c b/server/spicevmc.c index bed84887..c2e249c1 100644 --- a/server/spicevmc.c +++ b/server/spicevmc.c @@ -126,7 +126,9 @@ static void spicevmc_red_channel_client_on_disconnect(RedChannelClient *rcc) } static int spicevmc_red_channel_client_handle_message(RedChannelClient *rcc, - SpiceDataHeader *header, uint8_t *msg) + uint16_t type, + uint32_t size, + uint8_t *msg) { SpiceVmcState *state; SpiceCharDeviceInstance *sin; @@ -136,22 +138,22 @@ static int spicevmc_red_channel_client_handle_message(RedChannelClient *rcc, sin = state->chardev_sin; sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base); - if (header->type != SPICE_MSGC_SPICEVMC_DATA) { - return red_channel_client_handle_message(rcc, header->size, - header->type, msg); + if (type != SPICE_MSGC_SPICEVMC_DATA) { + return red_channel_client_handle_message(rcc, size, type, msg); } /* * qemu spicevmc will consume everything we give it, no need for * flow control checks (or to use a pipe). */ - sif->write(sin, msg, header->size); + sif->write(sin, msg, size); return TRUE; } static uint8_t *spicevmc_red_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, - SpiceDataHeader *msg_header) + uint16_t type, + uint32_t size) { SpiceVmcState *state; @@ -159,9 +161,9 @@ static uint8_t *spicevmc_red_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, assert(!state->rcv_buf_in_use); - if (msg_header->size > state->rcv_buf_size) { - state->rcv_buf = spice_realloc(state->rcv_buf, msg_header->size); - state->rcv_buf_size = msg_header->size; + if (size > state->rcv_buf_size) { + state->rcv_buf = spice_realloc(state->rcv_buf, size); + state->rcv_buf_size = size; } state->rcv_buf_in_use = 1; @@ -170,7 +172,9 @@ static uint8_t *spicevmc_red_channel_alloc_msg_rcv_buf(RedChannelClient *rcc, } static void spicevmc_red_channel_release_msg_rcv_buf(RedChannelClient *rcc, - SpiceDataHeader *msg_header, uint8_t *msg) + uint16_t type, + uint32_t size, + uint8_t *msg) { SpiceVmcState *state; |