mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-24 21:16:15 +01:00
GNetworkMonitorNetlink: Fix check for non-kernel messages
This code used to look at the SCM_CREDENTIALS and ignore every message not from uid 0. However, when user namespaces are in use this does not work, as if uid 0 is not mapped you get overflowuid instead. Right now this means we ignore all messages in such user namespaces and glib apps hang on startup. We can't look at pids either, as pid 0 is returned for processes outside your pid namespace. Instead the correct approach is to look at the sending sockaddr and if the port id (nl_pid) is zero, then its from the kernel. Source: http://lists.linuxfoundation.org/pipermail/containers/2015-May/036032.html https://bugzilla.gnome.org/show_bug.cgi?id=750203
This commit is contained in:
parent
f8273f39a1
commit
7cba800a84
@ -293,14 +293,13 @@ read_netlink_messages (GSocket *socket,
|
||||
GNetworkMonitorNetlink *nl = user_data;
|
||||
GInputVector iv;
|
||||
gssize len;
|
||||
GSocketControlMessage **cmsgs = NULL;
|
||||
gint num_cmsgs = 0, i, flags;
|
||||
gint flags;
|
||||
GError *error = NULL;
|
||||
GCredentials *creds;
|
||||
uid_t sender;
|
||||
GSocketAddress *addr;
|
||||
struct nlmsghdr *msg;
|
||||
struct rtmsg *rtmsg;
|
||||
struct rtattr *attr;
|
||||
struct sockaddr_nl source_sockaddr;
|
||||
gsize attrlen;
|
||||
guint8 *dest, *gateway, *oif;
|
||||
gboolean retval = TRUE;
|
||||
@ -322,8 +321,8 @@ read_netlink_messages (GSocket *socket,
|
||||
|
||||
iv.buffer = g_malloc (len);
|
||||
iv.size = len;
|
||||
len = g_socket_receive_message (nl->priv->sock, NULL, &iv, 1,
|
||||
&cmsgs, &num_cmsgs, NULL, NULL, &error);
|
||||
len = g_socket_receive_message (nl->priv->sock, &addr, &iv, 1,
|
||||
NULL, NULL, NULL, NULL, &error);
|
||||
if (len < 0)
|
||||
{
|
||||
g_warning ("Error on netlink socket: %s", error->message);
|
||||
@ -333,12 +332,17 @@ read_netlink_messages (GSocket *socket,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (num_cmsgs != 1 || !G_IS_UNIX_CREDENTIALS_MESSAGE (cmsgs[0]))
|
||||
goto done;
|
||||
if (!g_socket_address_to_native (addr, &source_sockaddr, sizeof (source_sockaddr), &error))
|
||||
{
|
||||
g_warning ("Error on netlink socket: %s", error->message);
|
||||
g_error_free (error);
|
||||
if (nl->priv->dump_networks)
|
||||
finish_dump (nl);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
creds = g_unix_credentials_message_get_credentials (G_UNIX_CREDENTIALS_MESSAGE (cmsgs[0]));
|
||||
sender = g_credentials_get_unix_user (creds, NULL);
|
||||
if (sender != 0)
|
||||
/* If the sender port id is 0 (not fakeable) then the message is from the kernel */
|
||||
if (source_sockaddr.nl_pid != 0)
|
||||
goto done;
|
||||
|
||||
msg = (struct nlmsghdr *) iv.buffer;
|
||||
@ -420,10 +424,6 @@ read_netlink_messages (GSocket *socket,
|
||||
}
|
||||
|
||||
done:
|
||||
for (i = 0; i < num_cmsgs; i++)
|
||||
g_object_unref (cmsgs[i]);
|
||||
g_free (cmsgs);
|
||||
|
||||
g_free (iv.buffer);
|
||||
|
||||
if (!retval && nl->priv->dump_networks)
|
||||
|
Loading…
Reference in New Issue
Block a user