[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