mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-10 03:16:17 +01:00
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
This commit is contained in:
parent
8f7cc8cb75
commit
d8fe926ba4
@ -47,7 +47,10 @@
|
|||||||
struct _GNativeSocketAddressPrivate
|
struct _GNativeSocketAddressPrivate
|
||||||
{
|
{
|
||||||
struct sockaddr *sockaddr;
|
struct sockaddr *sockaddr;
|
||||||
|
union {
|
||||||
struct sockaddr_storage storage;
|
struct sockaddr_storage storage;
|
||||||
|
struct sockaddr sa;
|
||||||
|
} storage;
|
||||||
gsize sockaddr_len;
|
gsize sockaddr_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -58,7 +61,7 @@ g_native_socket_address_dispose (GObject *object)
|
|||||||
{
|
{
|
||||||
GNativeSocketAddress *address = G_NATIVE_SOCKET_ADDRESS (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_free (address->priv->sockaddr);
|
||||||
|
|
||||||
G_OBJECT_CLASS (g_native_socket_address_parent_class)->dispose (object);
|
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);
|
addr = g_object_new (G_TYPE_NATIVE_SOCKET_ADDRESS, NULL);
|
||||||
|
|
||||||
if (len <= sizeof(addr->priv->storage))
|
if (len <= sizeof(addr->priv->storage))
|
||||||
addr->priv->sockaddr = (struct sockaddr*)&addr->priv->storage;
|
addr->priv->sockaddr = &addr->priv->storage.sa;
|
||||||
else
|
else
|
||||||
addr->priv->sockaddr = g_malloc (len);
|
addr->priv->sockaddr = g_malloc (len);
|
||||||
|
|
||||||
|
@ -421,7 +421,10 @@ check_timeout (GSocket *socket,
|
|||||||
static void
|
static void
|
||||||
g_socket_details_from_fd (GSocket *socket)
|
g_socket_details_from_fd (GSocket *socket)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage address;
|
union {
|
||||||
|
struct sockaddr_storage storage;
|
||||||
|
struct sockaddr sa;
|
||||||
|
} address;
|
||||||
gint fd;
|
gint fd;
|
||||||
guint addrlen;
|
guint addrlen;
|
||||||
int value, family;
|
int value, family;
|
||||||
@ -454,7 +457,7 @@ g_socket_details_from_fd (GSocket *socket)
|
|||||||
}
|
}
|
||||||
|
|
||||||
addrlen = sizeof address;
|
addrlen = sizeof address;
|
||||||
if (getsockname (fd, (struct sockaddr *) &address, &addrlen) != 0)
|
if (getsockname (fd, &address.sa, &addrlen) != 0)
|
||||||
{
|
{
|
||||||
errsv = get_socket_errno ();
|
errsv = get_socket_errno ();
|
||||||
goto err;
|
goto err;
|
||||||
@ -463,8 +466,8 @@ g_socket_details_from_fd (GSocket *socket)
|
|||||||
if (addrlen > 0)
|
if (addrlen > 0)
|
||||||
{
|
{
|
||||||
g_assert (G_STRUCT_OFFSET (struct sockaddr, sa_family) +
|
g_assert (G_STRUCT_OFFSET (struct sockaddr, sa_family) +
|
||||||
sizeof address.ss_family <= addrlen);
|
sizeof address.storage.ss_family <= addrlen);
|
||||||
family = address.ss_family;
|
family = address.storage.ss_family;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -488,7 +491,7 @@ g_socket_details_from_fd (GSocket *socket)
|
|||||||
{
|
{
|
||||||
case G_SOCKET_FAMILY_IPV4:
|
case G_SOCKET_FAMILY_IPV4:
|
||||||
case G_SOCKET_FAMILY_IPV6:
|
case G_SOCKET_FAMILY_IPV6:
|
||||||
socket->priv->family = address.ss_family;
|
socket->priv->family = address.storage.ss_family;
|
||||||
switch (socket->priv->type)
|
switch (socket->priv->type)
|
||||||
{
|
{
|
||||||
case G_SOCKET_TYPE_STREAM:
|
case G_SOCKET_TYPE_STREAM:
|
||||||
@ -521,7 +524,7 @@ g_socket_details_from_fd (GSocket *socket)
|
|||||||
if (socket->priv->family != G_SOCKET_FAMILY_INVALID)
|
if (socket->priv->family != G_SOCKET_FAMILY_INVALID)
|
||||||
{
|
{
|
||||||
addrlen = sizeof address;
|
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_read = TRUE;
|
||||||
socket->priv->connected_write = TRUE;
|
socket->priv->connected_write = TRUE;
|
||||||
@ -1936,12 +1939,15 @@ GSocketAddress *
|
|||||||
g_socket_get_local_address (GSocket *socket,
|
g_socket_get_local_address (GSocket *socket,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage buffer;
|
union {
|
||||||
|
struct sockaddr_storage storage;
|
||||||
|
struct sockaddr sa;
|
||||||
|
} buffer;
|
||||||
guint len = sizeof (buffer);
|
guint len = sizeof (buffer);
|
||||||
|
|
||||||
g_return_val_if_fail (G_IS_SOCKET (socket), NULL);
|
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 ();
|
int errsv = get_socket_errno ();
|
||||||
g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv),
|
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 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,
|
g_socket_get_remote_address (GSocket *socket,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage buffer;
|
union {
|
||||||
|
struct sockaddr_storage storage;
|
||||||
|
struct sockaddr sa;
|
||||||
|
} buffer;
|
||||||
guint len = sizeof (buffer);
|
guint len = sizeof (buffer);
|
||||||
|
|
||||||
g_return_val_if_fail (G_IS_SOCKET (socket), NULL);
|
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 (!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 ();
|
int errsv = get_socket_errno ();
|
||||||
g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv),
|
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;
|
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);
|
return g_object_ref (socket->priv->remote_address);
|
||||||
@ -2104,7 +2113,10 @@ g_socket_bind (GSocket *socket,
|
|||||||
gboolean reuse_address,
|
gboolean reuse_address,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage addr;
|
union {
|
||||||
|
struct sockaddr_storage storage;
|
||||||
|
struct sockaddr sa;
|
||||||
|
} addr;
|
||||||
gboolean so_reuseaddr;
|
gboolean so_reuseaddr;
|
||||||
#ifdef SO_REUSEPORT
|
#ifdef SO_REUSEPORT
|
||||||
gboolean so_reuseport;
|
gboolean so_reuseport;
|
||||||
@ -2115,7 +2127,7 @@ g_socket_bind (GSocket *socket,
|
|||||||
if (!check_socket (socket, error))
|
if (!check_socket (socket, error))
|
||||||
return FALSE;
|
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;
|
return FALSE;
|
||||||
|
|
||||||
/* On Windows, SO_REUSEADDR has the semantics we want for UDP
|
/* 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);
|
g_socket_set_option (socket, SOL_SOCKET, SO_REUSEPORT, so_reuseport, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (bind (socket->priv->fd, (struct sockaddr *) &addr,
|
if (bind (socket->priv->fd, &addr.sa,
|
||||||
g_socket_address_get_native_size (address)) < 0)
|
g_socket_address_get_native_size (address)) < 0)
|
||||||
{
|
{
|
||||||
int errsv = get_socket_errno ();
|
int errsv = get_socket_errno ();
|
||||||
@ -2793,14 +2805,17 @@ g_socket_connect (GSocket *socket,
|
|||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
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);
|
g_return_val_if_fail (G_IS_SOCKET (socket) && G_IS_SOCKET_ADDRESS (address), FALSE);
|
||||||
|
|
||||||
if (!check_socket (socket, error))
|
if (!check_socket (socket, error))
|
||||||
return FALSE;
|
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;
|
return FALSE;
|
||||||
|
|
||||||
if (socket->priv->remote_address)
|
if (socket->priv->remote_address)
|
||||||
@ -2811,7 +2826,7 @@ g_socket_connect (GSocket *socket,
|
|||||||
{
|
{
|
||||||
win32_unset_event_mask (socket, FD_CONNECT);
|
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)
|
g_socket_address_get_native_size (address)) < 0)
|
||||||
{
|
{
|
||||||
int errsv = get_socket_errno ();
|
int errsv = get_socket_errno ();
|
||||||
|
@ -2167,12 +2167,15 @@ g_log_writer_is_journald (gint output_fd)
|
|||||||
|
|
||||||
if (g_once_init_enter (&initialized))
|
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);
|
socklen_t addr_len = sizeof(addr);
|
||||||
int err = getpeername (output_fd, (struct sockaddr *) &addr, &addr_len);
|
int err = getpeername (output_fd, &addr.sa, &addr_len);
|
||||||
if (err == 0 && addr.ss_family == AF_UNIX)
|
if (err == 0 && addr.storage.ss_family == AF_UNIX)
|
||||||
fd_is_journal = g_str_has_prefix (((struct sockaddr_un *)&addr)->sun_path,
|
fd_is_journal = g_str_has_prefix (addr.un.sun_path, "/run/systemd/journal/");
|
||||||
"/run/systemd/journal/");
|
|
||||||
|
|
||||||
g_once_init_leave (&initialized, TRUE);
|
g_once_init_leave (&initialized, TRUE);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user