[libvirt] [PATCH] util: use union for sockaddr structs to avoid aliasing

Daniel P. Berrangé berrange at redhat.com
Wed Jan 31 17:37:12 UTC 2018


From: "Daniel P. Berrange" <berrange at redhat.com>

Some platforms/toolchains will complain about casting
sockaddr_storage to sockaddr_un because it breaks strict
aliasing rule

../../src/util/virutil.c: In function 'virGetUNIXSocketPath':
../../src/util/virutil.c:2005: error: dereferencing pointer 'un' does break strict-aliasing rules [-Wstrict-aliasing]

Change the code to use a union, in the same way that the
virsocketaddr.h header does.

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---

Pushed as (yet another) CI build fix

 src/util/virutil.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/src/util/virutil.c b/src/util/virutil.c
index c23fa8f92e..cd6fbf2f30 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -1985,30 +1985,33 @@ virGetListenFDs(void)
 #ifdef HAVE_SYS_UN_H
 char *virGetUNIXSocketPath(int fd)
 {
-    struct sockaddr_storage ss = { 0 };
-    struct sockaddr_un *un = (struct sockaddr_un *)&ss;
-    socklen_t len = sizeof(ss);
+    union {
+        struct sockaddr sa;
+        struct sockaddr_storage ss;
+        struct sockaddr_un un;
+    } addr = { .ss = { 0 } };
+    socklen_t len = sizeof(addr.ss);
     char *path;
 
-    if (getsockname(fd, (struct sockaddr *)&ss, &len) < 0) {
+    if (getsockname(fd, &addr.sa, &len) < 0) {
         virReportSystemError(errno, _("Unable to get address of FD %d"), fd);
         return NULL;
     }
 
-    if (ss.ss_family != AF_UNIX) {
+    if (addr.ss.ss_family != AF_UNIX) {
         virReportSystemError(EINVAL, _("FD %d is not a UNIX socket, has af=%d"),
-                             fd, ss.ss_family);
+                             fd, addr.ss.ss_family);
         return NULL;
     }
 
-    if (un->sun_path[0] == '\0')
-        un->sun_path[0] = '@';
+    if (addr.un.sun_path[0] == '\0')
+        addr.un.sun_path[0] = '@';
 
-    if (VIR_ALLOC_N(path, sizeof(un->sun_path) + 1) < 0)
+    if (VIR_ALLOC_N(path, sizeof(addr.un.sun_path) + 1) < 0)
         return NULL;
 
-    memcpy(path, un->sun_path, sizeof(un->sun_path));
-    path[sizeof(un->sun_path)] = '\0';
+    memcpy(path, addr.un.sun_path, sizeof(addr.un.sun_path));
+    path[sizeof(addr.un.sun_path)] = '\0';
     return path;
 }
 
-- 
2.14.3




More information about the libvir-list mailing list