[systemd-devel] [PATCH 2/2] udev: fix another strict aliasing issue

Shawn Paul Landden shawn at churchofgit.com
Tue Dec 23 15:04:37 PST 2014


---
 src/udev/ata_id/ata_id.c | 62 +++++++++++++++++++++++-------------------------
 1 file changed, 30 insertions(+), 32 deletions(-)

diff --git a/src/udev/ata_id/ata_id.c b/src/udev/ata_id/ata_id.c
index 89628c9..fc13819 100644
--- a/src/udev/ata_id/ata_id.c
+++ b/src/udev/ata_id/ata_id.c
@@ -409,7 +409,11 @@ int main(int argc, char *argv[])
 {
         struct udev *udev;
         struct hd_driveid id;
-        uint8_t identify[512];
+        union {
+                uint8_t  byte[512];
+                uint16_t wyde[256];
+                uint64_t octa[64];
+        } identify;
         uint16_t *identify_words;
         char model[41];
         char model_enc[256];
@@ -467,30 +471,30 @@ int main(int argc, char *argv[])
                 goto exit;
         }
 
-        if (disk_identify(udev, fd, identify, &is_packet_device) == 0) {
+        if (disk_identify(udev, fd, identify.byte, &is_packet_device) == 0) {
                 /*
                  * fix up only the fields from the IDENTIFY data that we are going to
                  * use and copy it into the hd_driveid struct for convenience
                  */
-                disk_identify_fixup_string(identify,  10, 20); /* serial */
-                disk_identify_fixup_string(identify,  23,  8); /* fwrev */
-                disk_identify_fixup_string(identify,  27, 40); /* model */
-                disk_identify_fixup_uint16(identify,  0);      /* configuration */
-                disk_identify_fixup_uint16(identify,  75);     /* queue depth */
-                disk_identify_fixup_uint16(identify,  75);     /* SATA capabilities */
-                disk_identify_fixup_uint16(identify,  82);     /* command set supported */
-                disk_identify_fixup_uint16(identify,  83);     /* command set supported */
-                disk_identify_fixup_uint16(identify,  84);     /* command set supported */
-                disk_identify_fixup_uint16(identify,  85);     /* command set supported */
-                disk_identify_fixup_uint16(identify,  86);     /* command set supported */
-                disk_identify_fixup_uint16(identify,  87);     /* command set supported */
-                disk_identify_fixup_uint16(identify,  89);     /* time required for SECURITY ERASE UNIT */
-                disk_identify_fixup_uint16(identify,  90);     /* time required for enhanced SECURITY ERASE UNIT */
-                disk_identify_fixup_uint16(identify,  91);     /* current APM values */
-                disk_identify_fixup_uint16(identify,  94);     /* current AAM value */
-                disk_identify_fixup_uint16(identify, 128);     /* device lock function */
-                disk_identify_fixup_uint16(identify, 217);     /* nominal media rotation rate */
-                memcpy(&id, identify, sizeof id);
+                disk_identify_fixup_string(identify.byte,  10, 20); /* serial */
+                disk_identify_fixup_string(identify.byte,  23,  8); /* fwrev */
+                disk_identify_fixup_string(identify.byte,  27, 40); /* model */
+                disk_identify_fixup_uint16(identify.byte,  0);      /* configuration */
+                disk_identify_fixup_uint16(identify.byte,  75);     /* queue depth */
+                disk_identify_fixup_uint16(identify.byte,  75);     /* SATA capabilities */
+                disk_identify_fixup_uint16(identify.byte,  82);     /* command set supported */
+                disk_identify_fixup_uint16(identify.byte,  83);     /* command set supported */
+                disk_identify_fixup_uint16(identify.byte,  84);     /* command set supported */
+                disk_identify_fixup_uint16(identify.byte,  85);     /* command set supported */
+                disk_identify_fixup_uint16(identify.byte,  86);     /* command set supported */
+                disk_identify_fixup_uint16(identify.byte,  87);     /* command set supported */
+                disk_identify_fixup_uint16(identify.byte,  89);     /* time required for SECURITY ERASE UNIT */
+                disk_identify_fixup_uint16(identify.byte,  90);     /* time required for enhanced SECURITY ERASE UNIT */
+                disk_identify_fixup_uint16(identify.byte,  91);     /* current APM values */
+                disk_identify_fixup_uint16(identify.byte,  94);     /* current AAM value */
+                disk_identify_fixup_uint16(identify.byte, 128);     /* device lock function */
+                disk_identify_fixup_uint16(identify.byte, 217);     /* nominal media rotation rate */
+                memcpy(&id, identify.byte, sizeof id);
         } else {
                 /* If this fails, then try HDIO_GET_IDENTITY */
                 if (ioctl(fd, HDIO_GET_IDENTITY, &id) != 0) {
@@ -499,7 +503,7 @@ int main(int argc, char *argv[])
                         goto close;
                 }
         }
-        identify_words = (uint16_t *) identify;
+        identify_words = &identify.wyde;
 
         memcpy (model, id.model, 40);
         model[40] = '\0';
@@ -613,7 +617,7 @@ int main(int argc, char *argv[])
                  * the device does not claim compliance with the Serial ATA specification and words
                  * 76 through 79 are not valid and shall be ignored.
                  */
-                word = *((uint16_t *) identify + 76);
+                word = identify_words[76];
                 if (word != 0x0000 && word != 0xffff) {
                         printf("ID_ATA_SATA=1\n");
                         /*
@@ -630,7 +634,7 @@ int main(int argc, char *argv[])
                 }
 
                 /* Word 217 indicates the nominal media rotation rate of the device */
-                word = *((uint16_t *) identify + 217);
+                word = identify_words[217];
                 if (word != 0x0000) {
                         if (word == 0x0001) {
                                 printf ("ID_ATA_ROTATION_RATE_RPM=0\n"); /* non-rotating e.g. SSD */
@@ -644,17 +648,11 @@ int main(int argc, char *argv[])
                  * format. Word 108 bits (15:12) shall contain 5h, indicating that the naming authority is IEEE.
                  * All other values are reserved.
                  */
-                word = *((uint16_t *) identify + 108);
+                word = identify_words[108];
                 if ((word & 0xf000) == 0x5000) {
                         uint64_t wwwn;
 
-                        wwwn   = *((uint16_t *) identify + 108);
-                        wwwn <<= 16;
-                        wwwn  |= *((uint16_t *) identify + 109);
-                        wwwn <<= 16;
-                        wwwn  |= *((uint16_t *) identify + 110);
-                        wwwn <<= 16;
-                        wwwn  |= *((uint16_t *) identify + 111);
+                        wwwn = identify.octa[108/4];
                         printf("ID_WWN=0x%llx\n", (unsigned long long int) wwwn);
                         /* ATA devices have no vendor extension */
                         printf("ID_WWN_WITH_EXTENSION=0x%llx\n", (unsigned long long int) wwwn);
-- 
2.1.0



More information about the systemd-devel mailing list