[glib] Fix various strict aliasing problems with sockaddr
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] Fix various strict aliasing problems with sockaddr
- Date: Mon, 8 Jan 2018 11:55:19 +0000 (UTC)
commit d8fe926ba4e799f7b1bd6b0b4464920443bedea9
Author: Philip Withnall <withnall endlessm com>
Date: Thu Dec 21 17:46:24 2017 +0000
Fix various strict aliasing problems with sockaddr
Fix various strict aliasing problems caused by casting between (struct
sockaddr *) and (struct sockaddr_storage *): the correct code here is to
keep the two in a union.
Signed-off-by: Philip Withnall <withnall endlessm com>
https://bugzilla.gnome.org/show_bug.cgi?id=791622
gio/gnativesocketaddress.c | 9 +++++--
gio/gsocket.c | 51 ++++++++++++++++++++++++++++---------------
glib/gmessages.c | 13 +++++++----
3 files changed, 47 insertions(+), 26 deletions(-)
---
diff --git a/gio/gnativesocketaddress.c b/gio/gnativesocketaddress.c
index 60d81e6..2110634 100644
--- a/gio/gnativesocketaddress.c
+++ b/gio/gnativesocketaddress.c
@@ -47,7 +47,10 @@
struct _GNativeSocketAddressPrivate
{
struct sockaddr *sockaddr;
- struct sockaddr_storage storage;
+ union {
+ struct sockaddr_storage storage;
+ struct sockaddr sa;
+ } storage;
gsize sockaddr_len;
};
@@ -58,7 +61,7 @@ g_native_socket_address_dispose (GObject *object)
{
GNativeSocketAddress *address = G_NATIVE_SOCKET_ADDRESS (object);
- if (address->priv->sockaddr != (struct sockaddr *)&address->priv->storage)
+ if (address->priv->sockaddr != &address->priv->storage.sa)
g_free (address->priv->sockaddr);
G_OBJECT_CLASS (g_native_socket_address_parent_class)->dispose (object);
@@ -150,7 +153,7 @@ g_native_socket_address_new (gpointer native,
addr = g_object_new (G_TYPE_NATIVE_SOCKET_ADDRESS, NULL);
if (len <= sizeof(addr->priv->storage))
- addr->priv->sockaddr = (struct sockaddr*)&addr->priv->storage;
+ addr->priv->sockaddr = &addr->priv->storage.sa;
else
addr->priv->sockaddr = g_malloc (len);
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 567b480..06042d8 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -421,7 +421,10 @@ check_timeout (GSocket *socket,
static void
g_socket_details_from_fd (GSocket *socket)
{
- struct sockaddr_storage address;
+ union {
+ struct sockaddr_storage storage;
+ struct sockaddr sa;
+ } address;
gint fd;
guint addrlen;
int value, family;
@@ -454,7 +457,7 @@ g_socket_details_from_fd (GSocket *socket)
}
addrlen = sizeof address;
- if (getsockname (fd, (struct sockaddr *) &address, &addrlen) != 0)
+ if (getsockname (fd, &address.sa, &addrlen) != 0)
{
errsv = get_socket_errno ();
goto err;
@@ -463,8 +466,8 @@ g_socket_details_from_fd (GSocket *socket)
if (addrlen > 0)
{
g_assert (G_STRUCT_OFFSET (struct sockaddr, sa_family) +
- sizeof address.ss_family <= addrlen);
- family = address.ss_family;
+ sizeof address.storage.ss_family <= addrlen);
+ family = address.storage.ss_family;
}
else
{
@@ -488,7 +491,7 @@ g_socket_details_from_fd (GSocket *socket)
{
case G_SOCKET_FAMILY_IPV4:
case G_SOCKET_FAMILY_IPV6:
- socket->priv->family = address.ss_family;
+ socket->priv->family = address.storage.ss_family;
switch (socket->priv->type)
{
case G_SOCKET_TYPE_STREAM:
@@ -521,7 +524,7 @@ g_socket_details_from_fd (GSocket *socket)
if (socket->priv->family != G_SOCKET_FAMILY_INVALID)
{
addrlen = sizeof address;
- if (getpeername (fd, (struct sockaddr *) &address, &addrlen) >= 0)
+ if (getpeername (fd, &address.sa, &addrlen) >= 0)
{
socket->priv->connected_read = TRUE;
socket->priv->connected_write = TRUE;
@@ -1936,12 +1939,15 @@ GSocketAddress *
g_socket_get_local_address (GSocket *socket,
GError **error)
{
- struct sockaddr_storage buffer;
+ union {
+ struct sockaddr_storage storage;
+ struct sockaddr sa;
+ } buffer;
guint len = sizeof (buffer);
g_return_val_if_fail (G_IS_SOCKET (socket), NULL);
- if (getsockname (socket->priv->fd, (struct sockaddr *) &buffer, &len) < 0)
+ if (getsockname (socket->priv->fd, &buffer.sa, &len) < 0)
{
int errsv = get_socket_errno ();
g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv),
@@ -1949,7 +1955,7 @@ g_socket_get_local_address (GSocket *socket,
return NULL;
}
- return g_socket_address_new_from_native (&buffer, len);
+ return g_socket_address_new_from_native (&buffer.storage, len);
}
/**
@@ -1969,7 +1975,10 @@ GSocketAddress *
g_socket_get_remote_address (GSocket *socket,
GError **error)
{
- struct sockaddr_storage buffer;
+ union {
+ struct sockaddr_storage storage;
+ struct sockaddr sa;
+ } buffer;
guint len = sizeof (buffer);
g_return_val_if_fail (G_IS_SOCKET (socket), NULL);
@@ -1984,7 +1993,7 @@ g_socket_get_remote_address (GSocket *socket,
if (!socket->priv->remote_address)
{
- if (getpeername (socket->priv->fd, (struct sockaddr *) &buffer, &len) < 0)
+ if (getpeername (socket->priv->fd, &buffer.sa, &len) < 0)
{
int errsv = get_socket_errno ();
g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv),
@@ -1992,7 +2001,7 @@ g_socket_get_remote_address (GSocket *socket,
return NULL;
}
- socket->priv->remote_address = g_socket_address_new_from_native (&buffer, len);
+ socket->priv->remote_address = g_socket_address_new_from_native (&buffer.storage, len);
}
return g_object_ref (socket->priv->remote_address);
@@ -2104,7 +2113,10 @@ g_socket_bind (GSocket *socket,
gboolean reuse_address,
GError **error)
{
- struct sockaddr_storage addr;
+ union {
+ struct sockaddr_storage storage;
+ struct sockaddr sa;
+ } addr;
gboolean so_reuseaddr;
#ifdef SO_REUSEPORT
gboolean so_reuseport;
@@ -2115,7 +2127,7 @@ g_socket_bind (GSocket *socket,
if (!check_socket (socket, error))
return FALSE;
- if (!g_socket_address_to_native (address, &addr, sizeof addr, error))
+ if (!g_socket_address_to_native (address, &addr.storage, sizeof addr, error))
return FALSE;
/* On Windows, SO_REUSEADDR has the semantics we want for UDP
@@ -2147,7 +2159,7 @@ g_socket_bind (GSocket *socket,
g_socket_set_option (socket, SOL_SOCKET, SO_REUSEPORT, so_reuseport, NULL);
#endif
- if (bind (socket->priv->fd, (struct sockaddr *) &addr,
+ if (bind (socket->priv->fd, &addr.sa,
g_socket_address_get_native_size (address)) < 0)
{
int errsv = get_socket_errno ();
@@ -2793,14 +2805,17 @@ g_socket_connect (GSocket *socket,
GCancellable *cancellable,
GError **error)
{
- struct sockaddr_storage buffer;
+ union {
+ struct sockaddr_storage storage;
+ struct sockaddr sa;
+ } buffer;
g_return_val_if_fail (G_IS_SOCKET (socket) && G_IS_SOCKET_ADDRESS (address), FALSE);
if (!check_socket (socket, error))
return FALSE;
- if (!g_socket_address_to_native (address, &buffer, sizeof buffer, error))
+ if (!g_socket_address_to_native (address, &buffer.storage, sizeof buffer, error))
return FALSE;
if (socket->priv->remote_address)
@@ -2811,7 +2826,7 @@ g_socket_connect (GSocket *socket,
{
win32_unset_event_mask (socket, FD_CONNECT);
- if (connect (socket->priv->fd, (struct sockaddr *) &buffer,
+ if (connect (socket->priv->fd, &buffer.sa,
g_socket_address_get_native_size (address)) < 0)
{
int errsv = get_socket_errno ();
diff --git a/glib/gmessages.c b/glib/gmessages.c
index cb2abd5..8c78568 100644
--- a/glib/gmessages.c
+++ b/glib/gmessages.c
@@ -2167,12 +2167,15 @@ g_log_writer_is_journald (gint output_fd)
if (g_once_init_enter (&initialized))
{
- struct sockaddr_storage addr;
+ union {
+ struct sockaddr_storage storage;
+ struct sockaddr sa;
+ struct sockaddr_un un;
+ } addr;
socklen_t addr_len = sizeof(addr);
- int err = getpeername (output_fd, (struct sockaddr *) &addr, &addr_len);
- if (err == 0 && addr.ss_family == AF_UNIX)
- fd_is_journal = g_str_has_prefix (((struct sockaddr_un *)&addr)->sun_path,
- "/run/systemd/journal/");
+ int err = getpeername (output_fd, &addr.sa, &addr_len);
+ if (err == 0 && addr.storage.ss_family == AF_UNIX)
+ fd_is_journal = g_str_has_prefix (addr.un.sun_path, "/run/systemd/journal/");
g_once_init_leave (&initialized, TRUE);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]