[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH] nwfilter: fix an bug appearing on big endian machines



Either one of the following patches fixes a bug appearing on big endian machines where the returned XML is not the one that is expected (see test/nwfilterxml2xmltest). The problem is due to for example the casting of a pointers to unsigned integers to void * and then back to 16 bit integers.

I have prepared 2 different solutions for the problem. I think the one with the union is the better one, which I am posting before the shorted solution. Both solutions make the nwfilterxml2xmltest pass on a ppc64 machine.

Signed-off-by: Stefan Berger <stefanb us ibm com>

Index: libvirt-acl/src/conf/nwfilter_conf.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.c
+++ libvirt-acl/src/conf/nwfilter_conf.c
@@ -379,9 +379,14 @@ virNWFilterPoolObjRemove(virNWFilterPool
     }
 }

+union data {
+    void *v;
+    char *c;
+    unsigned char *uc;
+    unsigned int ui;
+};

-
-typedef bool (*valueValidator)(enum attrDatatype datatype, void *valptr,
+typedef bool (*valueValidator)(enum attrDatatype datatype, union data *valptr,
                                virNWFilterRuleDefPtr nwf);
 typedef bool (*valueFormatter)(virBufferPtr buf,
                                virNWFilterRuleDefPtr nwf);
@@ -407,18 +412,18 @@ static const struct int_map macProtoMap[


 static bool
-checkMacProtocolID(enum attrDatatype datatype, void *value,
+checkMacProtocolID(enum attrDatatype datatype, union data *value,
                    virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED)
 {
     int32_t res = -1;

     if (datatype == DATATYPE_STRING) {
-        if (intMapGetByString(macProtoMap, (char *)value, 1, &res) == 0)
+        if (intMapGetByString(macProtoMap, value->c, 1, &res) == 0)
             res = -1;
         datatype = DATATYPE_UINT16;
     } else if (datatype == DATATYPE_UINT16 ||
                datatype == DATATYPE_UINT16_HEX) {
-        res = (uint32_t)*(uint16_t *)value;
+        res = value->ui;
         if (res < 0x600)
             res = -1;
     }
@@ -485,10 +490,10 @@ checkValidMask(unsigned char *data, int

 static bool
 checkMACMask(enum attrDatatype datatype ATTRIBUTE_UNUSED,
-             void *macMask,
+             union data *macMask,
              virNWFilterRuleDefPtr nwf ATTRIBUTE_UNUSED)
 {
-    return checkValidMask((unsigned char *)macMask, 6);
+    return checkValidMask(macMask->uc, 6);
 }


@@ -511,18 +516,18 @@ static const struct int_map arpOpcodeMap

 static bool
 arpOpcodeValidator(enum attrDatatype datatype,
-                   void *value,
+                   union data *value,
                    virNWFilterRuleDefPtr nwf)
 {
     int32_t res = -1;

     if (datatype == DATATYPE_STRING) {
-        if (intMapGetByString(arpOpcodeMap, (char *)value, 1, &res) == 0)
+        if (intMapGetByString(arpOpcodeMap, value->c, 1, &res) == 0)
             res = -1;
         datatype = DATATYPE_UINT16;
     } else if (datatype == DATATYPE_UINT16 ||
                datatype == DATATYPE_UINT16_HEX) {
-        res = (uint32_t)*(uint16_t *)value;
+        res = (uint32_t)value->ui;
     }

     if (res != -1) {
@@ -570,18 +575,18 @@ static const struct int_map ipProtoMap[]


 static bool checkIPProtocolID(enum attrDatatype datatype,
-                              void *value,
+                              union data *value,
                               virNWFilterRuleDefPtr nwf)
 {
     int32_t res = -1;

     if (datatype == DATATYPE_STRING) {
-        if (intMapGetByString(ipProtoMap, (char *)value, 1, &res) == 0)
+        if (intMapGetByString(ipProtoMap, value->c, 1, &res) == 0)
             res = -1;
         datatype = DATATYPE_UINT8_HEX;
     } else if (datatype == DATATYPE_UINT8 ||
                datatype == DATATYPE_UINT8_HEX) {
-        res = (uint32_t)*(uint16_t *)value;
+        res = (uint32_t)value->ui;
     }

     if (res != -1) {
@@ -615,10 +620,10 @@ formatIPProtocolID(virBufferPtr buf,


 static bool
-dscpValidator(enum attrDatatype datatype, void *val,
+dscpValidator(enum attrDatatype datatype, union data *val,
               virNWFilterRuleDefPtr nwf)
 {
-    uint8_t dscp = *(uint16_t *)val;
+    uint8_t dscp = val->ui;
     if (dscp > 63)
         return 0;

@@ -1150,7 +1155,8 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
     nwItemDesc *item;
     int int_val;
     unsigned int uint_val;
-    void *data_ptr = NULL, *storage_ptr;
+    void *storage_ptr;
+    union data data;
     valueValidator validator;
     char *match = virXMLPropString(node, "match");
     nwIPAddress ipaddr;
@@ -1206,7 +1212,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
                                 if (uint_val <= 0xff) {
                                     *(uint8_t *)storage_ptr = uint_val;
                                     found = 1;
-                                    data_ptr = &uint_val;
+                                    data.ui = uint_val;
                                 } else
                                     rc = -1;
                             } else
@@ -1221,7 +1227,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
                                 if (uint_val <= 0xffff) {
                                     *(uint16_t *)storage_ptr = uint_val;
                                     found = 1;
-                                    data_ptr = &uint_val;
+                                    data.ui = uint_val;
                                 } else
                                     rc = -1;
                             } else
@@ -1245,7 +1251,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
                                         *(uint8_t *)storage_ptr =
                                                (uint8_t)uint_val;
                                     found = 1;
-                                    data_ptr = &uint_val;
+                                    data.ui = uint_val;
                                 } else
                                     rc = -1;
                             } else {
@@ -1278,7 +1284,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
                                         (nwMACAddressPtr)storage_ptr)) {
                                 rc = -1;
                             }
-                            data_ptr = storage_ptr;
+                            data.v = storage_ptr;
                             found = 1;
                         break;

@@ -1299,7 +1305,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
                                         *(uint8_t *)storage_ptr =
                                                (uint8_t)uint_val;
                                     found = 1;
-                                    data_ptr = &uint_val;
+                                    data.ui = uint_val;
                                 } else
                                     rc = -1;
                             } else {
@@ -1322,7 +1328,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
                                 rc = -1;
                                 break;
                             }
-                            data_ptr = prop;
+                            data.c = prop;
                             found = 1;
                         break;

@@ -1344,7 +1350,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
                 *flags = NWFILTER_ENTRY_ITEM_FLAG_EXISTS | flags_set;
                 item->datatype = datatype >> 1;
                 if (validator) {
-                    if (!validator(datatype >> 1, data_ptr, nwf)) {
+                    if (!validator(datatype >> 1, &data, nwf)) {
                         rc = -1;
                         *flags = 0;
                     }




=============== 2nd solution =================





Index: libvirt-acl/src/conf/nwfilter_conf.c
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.c
+++ libvirt-acl/src/conf/nwfilter_conf.c
@@ -181,6 +181,8 @@ static const char dscp_str[]         = "
 #define DSCP          dscp_str


+#define PARSED_INT_TYPE  unsigned int
+
 /**
  * intMapGetByInt:
  * @intmap: Pointer to int-to-string map
@@ -418,7 +420,7 @@ checkMacProtocolID(enum attrDatatype dat
         datatype = DATATYPE_UINT16;
     } else if (datatype == DATATYPE_UINT16 ||
                datatype == DATATYPE_UINT16_HEX) {
-        res = (uint32_t)*(uint16_t *)value;
+        res = (uint32_t)*(PARSED_INT_TYPE *)value;
         if (res < 0x600)
             res = -1;
     }
@@ -522,7 +524,7 @@ arpOpcodeValidator(enum attrDatatype dat
         datatype = DATATYPE_UINT16;
     } else if (datatype == DATATYPE_UINT16 ||
                datatype == DATATYPE_UINT16_HEX) {
-        res = (uint32_t)*(uint16_t *)value;
+        res = (uint32_t)*(PARSED_INT_TYPE *)value;
     }

     if (res != -1) {
@@ -581,7 +583,7 @@ static bool checkIPProtocolID(enum attrD
         datatype = DATATYPE_UINT8_HEX;
     } else if (datatype == DATATYPE_UINT8 ||
                datatype == DATATYPE_UINT8_HEX) {
-        res = (uint32_t)*(uint16_t *)value;
+        res = (uint32_t)*(PARSED_INT_TYPE *)value;
     }

     if (res != -1) {
@@ -618,7 +620,7 @@ static bool
 dscpValidator(enum attrDatatype datatype, void *val,
               virNWFilterRuleDefPtr nwf)
 {
-    uint8_t dscp = *(uint16_t *)val;
+    uint8_t dscp = *(PARSED_INT_TYPE *)val;
     if (dscp > 63)
         return 0;

@@ -1149,7 +1151,7 @@ virNWFilterRuleDetailsParse(xmlNodePtr n
     enum virNWFilterEntryItemFlags *flags ,match_flag = 0, flags_set = 0;
     nwItemDesc *item;
     int int_val;
-    unsigned int uint_val;
+    PARSED_INT_TYPE uint_val;
     void *data_ptr = NULL, *storage_ptr;
     valueValidator validator;
     char *match = virXMLPropString(node, "match");


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]