[Spice-devel] [PATCH v2 2/7] spice-ppc: fixing endianess for channel startup negotiation

Erlon Cruz erlon.cruz at br.flextronics.com
Mon Aug 13 07:14:28 PDT 2012


Signed-off-by: Erlon R. Cruz <erlon.cruz at br.flextronics.com>
Signed-off-by: Rafael F. Santos <fonsecasantos.rafael at gmail.com>
Signed-off-by: Fabiano Fidêncio <Fabiano.Fidêncio at fit-tecnologia.org.br>
---
 server/reds.c |   86 +++++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 71 insertions(+), 15 deletions(-)

diff --git a/server/reds.c b/server/reds.c
index e3ea154..25bea45 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -36,6 +36,7 @@
 #include <errno.h>
 #include <ctype.h>
 #include <stdbool.h>
+#include <endian.h>
 
 #include <openssl/bio.h>
 #include <openssl/pem.h>
@@ -1216,6 +1217,26 @@ static void reds_channel_init_auth_caps(RedLinkInfo *link, RedChannel *channel)
     red_channel_set_common_cap(channel, SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION);
 }
 
+
+#ifdef WORDS_BIGENDIAN
+static inline void buf_swap_htole32(void *buf, size_t len){
+
+    uint32_t *pos = buf;
+
+    if(len%4)
+        spice_warning("error swapping unaligned 32 bits word: len %d\n",(int)len);
+
+    while(len > 0){
+        *pos = htole32(*pos);
+        pos++;
+        len -= 4;
+    }
+}
+#else
+static inline void buf_swap_htole32(void *buf, size_t len){
+}
+#endif
+
 static int reds_send_link_ack(RedLinkInfo *link)
 {
     SpiceLinkHeader header;
@@ -1224,12 +1245,12 @@ static int reds_send_link_ack(RedLinkInfo *link)
     RedChannelCapabilities *channel_caps;
     BUF_MEM *bmBuf;
     BIO *bio;
-    int ret = FALSE;
+    int ret = FALSE, *common_caps = NULL, *caps = NULL;
 
     header.magic = SPICE_MAGIC;
     header.size = sizeof(ack);
-    header.major_version = SPICE_VERSION_MAJOR;
-    header.minor_version = SPICE_VERSION_MINOR;
+    header.major_version = htole32(SPICE_VERSION_MAJOR);
+    header.minor_version = htole32(SPICE_VERSION_MINOR);
 
     ack.error = SPICE_LINK_ERR_OK;
 
@@ -1243,10 +1264,12 @@ static int reds_send_link_ack(RedLinkInfo *link)
     reds_channel_init_auth_caps(link, channel); /* make sure common caps are set */
 
     channel_caps = &channel->local_caps;
-    ack.num_common_caps = channel_caps->num_common_caps;
-    ack.num_channel_caps = channel_caps->num_caps;
-    header.size += (ack.num_common_caps + ack.num_channel_caps) * sizeof(uint32_t);
-    ack.caps_offset = sizeof(SpiceLinkReply);
+    ack.num_common_caps = htole32(channel_caps->num_common_caps);
+    ack.num_channel_caps = htole32(channel_caps->num_caps);
+    header.size += (channel_caps->num_common_caps + channel_caps->num_caps) * sizeof(uint32_t);
+    ack.caps_offset = htole32(sizeof(SpiceLinkReply));
+
+    header.size = htole32(header.size);
 
     if (!(link->tiTicketing.rsa = RSA_new())) {
         spice_warning("RSA nes failed");
@@ -1264,17 +1287,32 @@ static int reds_send_link_ack(RedLinkInfo *link)
 
     i2d_RSA_PUBKEY_bio(bio, link->tiTicketing.rsa);
     BIO_get_mem_ptr(bio, &bmBuf);
+
     memcpy(ack.pub_key, bmBuf->data, sizeof(ack.pub_key));
 
+    common_caps = spice_memdup(channel_caps->common_caps,
+                    channel_caps->num_common_caps * sizeof(uint32_t));
+    buf_swap_htole32(common_caps,
+                    channel_caps->num_common_caps * sizeof(uint32_t));
+
+    caps = spice_memdup(channel_caps->caps,
+                    channel_caps->num_caps * sizeof(uint32_t));
+
+    buf_swap_htole32(common_caps,
+                    channel_caps->num_caps * sizeof(uint32_t));
+
     if (!sync_write(link->stream, &header, sizeof(header)))
         goto end;
     if (!sync_write(link->stream, &ack, sizeof(ack)))
         goto end;
-    if (!sync_write(link->stream, channel_caps->common_caps, channel_caps->num_common_caps * sizeof(uint32_t)))
+    if (!sync_write(link->stream, common_caps, channel_caps->num_common_caps * sizeof(uint32_t)))
         goto end;
-    if (!sync_write(link->stream, channel_caps->caps, channel_caps->num_caps * sizeof(uint32_t)))
+    if (!sync_write(link->stream, caps, channel_caps->num_caps * sizeof(uint32_t)))
         goto end;
 
+    free(common_caps);
+    free(caps);
+
     ret = TRUE;
 
 end:
@@ -1288,11 +1326,12 @@ static int reds_send_link_error(RedLinkInfo *link, uint32_t error)
     SpiceLinkReply reply;
 
     header.magic = SPICE_MAGIC;
-    header.size = sizeof(reply);
-    header.major_version = SPICE_VERSION_MAJOR;
-    header.minor_version = SPICE_VERSION_MINOR;
+    header.size = htole32(sizeof(reply));
+    header.major_version = htole32(SPICE_VERSION_MAJOR);
+    header.minor_version = htole32(SPICE_VERSION_MINOR);
     memset(&reply, 0, sizeof(reply));
-    reply.error = error;
+    reply.error = htole32(error);
+
     return sync_write(link->stream, &header, sizeof(header)) && sync_write(link->stream, &reply,
                                                                          sizeof(reply));
 }
@@ -1315,7 +1354,9 @@ static void reds_info_new_channel(RedLinkInfo *link, int connection_id)
 
 static void reds_send_link_result(RedLinkInfo *link, uint32_t error)
 {
-    sync_write(link->stream, &error, sizeof(error));
+    uint32_t serror;
+    serror = htole32(error);
+    sync_write(link->stream, &serror, sizeof(serror));
 }
 
 int reds_expects_link_id(uint32_t connection_id)
@@ -2337,6 +2378,8 @@ static void reds_handle_auth_mechanism(void *opaque)
 {
     RedLinkInfo *link = (RedLinkInfo *)opaque;
 
+    link->auth_mechanism.auth_mechanism = le32toh(link->auth_mechanism.auth_mechanism);
+
     spice_info("Auth method: %d", link->auth_mechanism.auth_mechanism);
 
     if (link->auth_mechanism.auth_mechanism == SPICE_COMMON_CAP_AUTH_SPICE
@@ -2371,9 +2414,15 @@ static void reds_handle_read_link_done(void *opaque)
     RedLinkInfo *link = (RedLinkInfo *)opaque;
     SpiceLinkMess *link_mess = link->link_mess;
     AsyncRead *obj = &link->asyc_read;
+
+    link_mess->caps_offset = le32toh(link_mess->caps_offset);
+    link_mess->connection_id = le32toh(link_mess->connection_id);
+    link_mess->num_channel_caps = le32toh(link_mess->num_channel_caps);
+    link_mess->num_common_caps = le32toh(link_mess->num_common_caps);
+
     uint32_t num_caps = link_mess->num_common_caps + link_mess->num_channel_caps;
     uint32_t *caps = (uint32_t *)((uint8_t *)link_mess + link_mess->caps_offset);
-    int auth_selection;
+    int auth_selection,i;
 
     if (num_caps && (num_caps * sizeof(uint32_t) + link_mess->caps_offset >
                      link->link_header.size ||
@@ -2383,6 +2432,9 @@ static void reds_handle_read_link_done(void *opaque)
         return;
     }
 
+    for(i = 0; i < num_caps;i++)
+        caps[i] = le32toh(caps[i]);
+
     auth_selection = test_capabilty(caps, link_mess->num_common_caps,
                                     SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION);
 
@@ -2439,6 +2491,10 @@ static void reds_handle_read_header_done(void *opaque)
     SpiceLinkHeader *header = &link->link_header;
     AsyncRead *obj = &link->asyc_read;
 
+    header->major_version = le32toh(header->major_version);
+    header->minor_version = le32toh(header->minor_version);
+    header->size = le32toh(header->size);
+
     if (header->magic != SPICE_MAGIC) {
         reds_send_link_error(link, SPICE_LINK_ERR_INVALID_MAGIC);
         reds_link_free(link);
-- 
1.7.4.1



More information about the Spice-devel mailing list