[vlc-commits] [Git][videolan/vlc][master] 4 commits: udp: use union to avoid bad cast

Rémi Denis-Courmont (@Courmisch) gitlab at videolan.org
Tue Sep 28 16:37:13 UTC 2021



Rémi Denis-Courmont pushed to branch master at VideoLAN / VLC


Commits:
82b4cb12 by Rémi Denis-Courmont at 2021-09-28T16:20:44+00:00
udp: use union to avoid bad cast

- - - - -
b9413a68 by Rémi Denis-Courmont at 2021-09-28T16:20:44+00:00
sap: use union to avoid one bad and two ugly casts

- - - - -
f03dabe2 by Rémi Denis-Courmont at 2021-09-28T16:20:44+00:00
udp: use memcpy() to alias socket address types

...without breaking strict aliasing rules.

- - - - -
2dd4eb2d by Rémi Denis-Courmont at 2021-09-28T16:20:44+00:00
tcp: use memcpy() to alias socket address types

...without breaking strict aliasing rules.

- - - - -


3 changed files:

- src/network/tcp.c
- src/network/udp.c
- src/stream_output/sap.c


Changes:

=====================================
src/network/tcp.c
=====================================
@@ -177,8 +177,8 @@ static int SocksHandshakeTCP( vlc_object_t *p_obj,
         buffer[0] = i_socks_version;
         buffer[1] = 0x01;               /* CONNECT */
         SetWBE( &buffer[2], i_port );   /* Port */
-        memcpy (&buffer[4],             /* Address */
-                &((struct sockaddr_in *)(res->ai_addr))->sin_addr, 4);
+        memcpy(&buffer[4], ((unsigned char *)res->ai_addr) /* Address */
+                           + offsetof (struct sockaddr_in, sin_addr), 4);
         freeaddrinfo (res);
 
         buffer[8] = 0;                  /* Empty user id */


=====================================
src/network/udp.c
=====================================
@@ -116,17 +116,23 @@ static int net_SetupDgramSocket (vlc_object_t *p_obj, int fd,
         FreeLibrary( h_Network );
 #endif
 
-    if (net_SockAddrIsMulticast (ptr->ai_addr, ptr->ai_addrlen)
-     && (sizeof (struct sockaddr_storage) >= ptr->ai_addrlen))
+    if (net_SockAddrIsMulticast (ptr->ai_addr, ptr->ai_addrlen))
     {
-        // This works for IPv4 too - don't worry!
-        struct sockaddr_in6 dumb =
+        union
         {
-            .sin6_family = ptr->ai_addr->sa_family,
-            .sin6_port =  ((struct sockaddr_in *)(ptr->ai_addr))->sin_port
+            struct sockaddr a;
+            struct sockaddr_in in;
+            struct sockaddr_in6 in6;
+        } dumb = {
+            { .sa_family = ptr->ai_addr->sa_family, },
         };
 
-        bind (fd, (struct sockaddr *)&dumb, ptr->ai_addrlen);
+        static_assert (offsetof (struct sockaddr_in, sin_port) ==
+                       offsetof (struct sockaddr_in6, sin6_port), "Mismatch");
+        assert(ptr->ai_addrlen <= sizeof (dumb));
+        memcpy(&dumb.in6.sin6_port, ((unsigned char *)ptr->ai_addr)
+                               + offsetof (struct sockaddr_in, sin_port), 2);
+        bind(fd, &dumb.a, ptr->ai_addrlen);
     }
     else
 #endif
@@ -332,15 +338,8 @@ net_SourceSubscribe (vlc_object_t *obj, int fd,
     {
 #ifdef AF_INET6
         case AF_INET6:
-        {
-            const struct sockaddr_in6 *g6 = (const struct sockaddr_in6 *)grp;
-
             level = SOL_IPV6;
-            assert(grplen >= (socklen_t)sizeof (struct sockaddr_in6));
-            if (g6->sin6_scope_id != 0)
-                gsr.gsr_interface = g6->sin6_scope_id;
             break;
-        }
 #endif
         case AF_INET:
             level = SOL_IP;
@@ -354,6 +353,20 @@ net_SourceSubscribe (vlc_object_t *obj, int fd,
     memcpy (&gsr.gsr_source, src, srclen);
     assert(srclen <= (socklen_t)sizeof (gsr.gsr_source));
     memcpy (&gsr.gsr_group,  grp, grplen);
+
+#ifdef AF_INET6
+    if (grp->sa_family == AF_INET6)
+    {
+        uint32_t scope_id;
+
+        assert(grplen >= (socklen_t)sizeof (struct sockaddr_in6));
+        memcpy(&scope_id, ((unsigned char *)grp)
+                          + offsetof (struct sockaddr_in6, sin6_scope_id), 4);
+        if (scope_id != 0)
+            gsr.gsr_interface = scope_id;
+    }
+#endif
+
     if (setsockopt (fd, level, MCAST_JOIN_SOURCE_GROUP,
                     &gsr, sizeof (gsr)) == 0)
         return 0;
@@ -413,15 +426,8 @@ static int net_Subscribe(vlc_object_t *obj, int fd,
     {
 #ifdef AF_INET6
         case AF_INET6:
-        {
-            const struct sockaddr_in6 *g6 = (const struct sockaddr_in6 *)grp;
-
             level = SOL_IPV6;
-            assert(grplen >= (socklen_t)sizeof (struct sockaddr_in6));
-            if (g6->sin6_scope_id != 0)
-                gr.gr_interface = g6->sin6_scope_id;
             break;
-        }
 #endif
         case AF_INET:
             level = SOL_IP;
@@ -433,6 +439,20 @@ static int net_Subscribe(vlc_object_t *obj, int fd,
 
     assert(grplen <= (socklen_t)sizeof (gr.gr_group));
     memcpy (&gr.gr_group, grp, grplen);
+
+#ifdef AF_INET6
+    if (grp->sa_family == AF_INET6)
+    {
+        uint32_t scope_id;
+
+        assert(grplen >= (socklen_t)sizeof (struct sockaddr_in6));
+        memcpy(&scope_id, ((unsigned char *)grp)
+                          + offsetof (struct sockaddr_in6, sin6_scope_id), 4);
+        if (scope_id != 0)
+            gr.gr_interface = scope_id;
+    }
+#endif
+
     if (setsockopt (fd, level, MCAST_JOIN_GROUP, &gr, sizeof (gr)) == 0)
         return 0;
 
@@ -482,13 +502,20 @@ static int net_Subscribe(vlc_object_t *obj, int fd,
 
 static int net_SetDSCP( int fd, uint8_t dscp )
 {
-    struct sockaddr_storage addr;
-    if( getsockname( fd, (struct sockaddr *)&addr, &(socklen_t){ sizeof (addr) }) )
+    union {
+        struct sockaddr a;
+        struct sockaddr_in in;
+#ifdef IPV6_TCLASS
+        struct sockaddr_in in6;
+#endif
+    } addr;
+
+    if (getsockname(fd, &addr.a, &(socklen_t){ sizeof (addr) }))
         return -1;
 
     int level, cmd;
 
-    switch( addr.ss_family )
+    switch (addr.a.sa_family)
     {
 #ifdef IPV6_TCLASS
         case AF_INET6:


=====================================
src/stream_output/sap.c
=====================================
@@ -63,7 +63,11 @@ typedef struct sap_address_t
     vlc_cond_t              wait;
 
     char                    group[NI_MAXNUMERICHOST];
-    struct sockaddr_storage orig;
+    union {
+        struct sockaddr     a;
+        struct sockaddr_in  in;
+        struct sockaddr_in6 in6;
+    } orig;
     socklen_t               origlen;
     int                     fd;
     unsigned                interval;
@@ -97,7 +101,7 @@ static sap_address_t *AddressCreate (vlc_object_t *obj, const char *group)
     strlcpy (addr->group, group, sizeof (addr->group));
     addr->fd = fd;
     addr->origlen = sizeof (addr->orig);
-    getsockname (fd, (struct sockaddr *)&addr->orig, &addr->origlen);
+    getsockname(fd, &addr->orig.a, &addr->origlen);
 
     addr->interval = var_CreateGetInteger (obj, "sap-interval");
     vlc_cond_init (&addr->wait);
@@ -283,29 +287,27 @@ matched:
     /* SAPv1, not encrypted, not compressed */
     uint8_t flags = 0x20;
 #ifdef AF_INET6
-    if (sap_addr->orig.ss_family == AF_INET6)
+    if (sap_addr->orig.a.sa_family == AF_INET6)
         flags |= 0x10;
 #endif
     vlc_memstream_putc(&stream, flags);
     vlc_memstream_putc(&stream, 0x00); /* No authentication length */
     vlc_memstream_write(&stream, &(uint16_t){ vlc_tick_now() }, 2); /* ID hash */
 
-    switch (sap_addr->orig.ss_family)
+    switch (sap_addr->orig.a.sa_family)
     {
 #ifdef AF_INET6
         case AF_INET6:
         {
-            const struct in6_addr *a6 =
-                &((const struct sockaddr_in6 *)&sap_addr->orig)->sin6_addr;
-            vlc_memstream_write(&stream, &a6, 16);
+            const struct in6_addr *a6 = &sap_addr->orig.in6.sin6_addr;
+            vlc_memstream_write(&stream, a6, 16);
             break;
         }
 #endif
         case AF_INET:
         {
-            const struct in_addr *a4 =
-                &((const struct sockaddr_in *)&sap_addr->orig)->sin_addr;
-            vlc_memstream_write(&stream, &a4, 4);
+            const struct in_addr *a4 = &sap_addr->orig.in.sin_addr;
+            vlc_memstream_write(&stream, a4, 4);
             break;
         }
         default:



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/ff6e1d6443bef54d96ced7b94824d21fbced1d5b...2dd4eb2d834906a99a36d1a27c7044b85d9ed2f4

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/ff6e1d6443bef54d96ced7b94824d21fbced1d5b...2dd4eb2d834906a99a36d1a27c7044b85d9ed2f4
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list