Commit 5932e16a authored by Dan Winship's avatar Dan Winship

GNetworkMonitorNetlink: make the netlink socket cloexec

Use the same code GSocket does, to try SOCK_CLOEXEC first, and then
fall back to FD_CLOEXEC if it fails. (And fix that code to not call
fcntl if SOCK_CLOEXEC worked.)

https://bugzilla.gnome.org/show_bug.cgi?id=692332
parent 2476dd24
......@@ -34,6 +34,11 @@ gchar * _g_uri_from_authority (const gchar *protocol,
guint port,
const gchar *userinfo);
gint g_socket (gint domain,
gint type,
gint protocol,
GError **error);
G_END_DECLS
#endif /* __G_NETWORKINGPRIVATE_H__ */
......@@ -89,7 +89,7 @@ g_network_monitor_netlink_initable_init (GInitable *initable,
/* We create the socket the old-school way because sockaddr_netlink
* can't be represented as a GSocketAddress
*/
sockfd = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
sockfd = g_socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE, NULL);
if (sockfd == -1)
{
int errsv = errno;
......
......@@ -59,7 +59,7 @@
#include "gioerror.h"
#include "gioenums.h"
#include "gioerror.h"
#include "gnetworking.h"
#include "gnetworkingprivate.h"
#include "gsocketaddress.h"
#include "gsocketcontrolmessage.h"
#include "gcredentials.h"
......@@ -482,6 +482,55 @@ g_socket_details_from_fd (GSocket *socket)
socket_strerror (errsv));
}
/* Wrapper around socket() that is shared with gnetworkmonitornetlink.c */
gint
g_socket (gint domain,
gint type,
gint protocol,
GError **error)
{
int fd;
#ifdef SOCK_CLOEXEC
fd = socket (domain, type | SOCK_CLOEXEC, protocol);
if (fd != -1)
return fd;
/* It's possible that libc has SOCK_CLOEXEC but the kernel does not */
if (fd < 0 && errno == EINVAL)
#endif
fd = socket (domain, type, protocol);
if (fd < 0)
{
int errsv = get_socket_errno ();
g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv),
_("Unable to create socket: %s"), socket_strerror (errsv));
errno = errsv;
return -1;
}
#ifndef G_OS_WIN32
{
int flags;
/* We always want to set close-on-exec to protect users. If you
need to so some weird inheritance to exec you can re-enable this
using lower level hacks with g_socket_get_fd(). */
flags = fcntl (fd, F_GETFD, 0);
if (flags != -1 &&
(flags & FD_CLOEXEC) == 0)
{
flags |= FD_CLOEXEC;
fcntl (fd, F_SETFD, flags);
}
}
#endif
return fd;
}
static gint
g_socket_create_socket (GSocketFamily family,
GSocketType type,
......@@ -489,7 +538,6 @@ g_socket_create_socket (GSocketFamily family,
GError **error)
{
gint native_type;
gint fd;
switch (type)
{
......@@ -523,39 +571,7 @@ g_socket_create_socket (GSocketFamily family,
return -1;
}
#ifdef SOCK_CLOEXEC
fd = socket (family, native_type | SOCK_CLOEXEC, protocol);
/* It's possible that libc has SOCK_CLOEXEC but the kernel does not */
if (fd < 0 && errno == EINVAL)
#endif
fd = socket (family, native_type, protocol);
if (fd < 0)
{
int errsv = get_socket_errno ();
g_set_error (error, G_IO_ERROR, socket_io_error_from_errno (errsv),
_("Unable to create socket: %s"), socket_strerror (errsv));
}
#ifndef G_OS_WIN32
{
int flags;
/* We always want to set close-on-exec to protect users. If you
need to so some weird inheritance to exec you can re-enable this
using lower level hacks with g_socket_get_fd(). */
flags = fcntl (fd, F_GETFD, 0);
if (flags != -1 &&
(flags & FD_CLOEXEC) == 0)
{
flags |= FD_CLOEXEC;
fcntl (fd, F_SETFD, flags);
}
}
#endif
return fd;
return g_socket (family, native_type, protocol, error);
}
static void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment