diff options
| author | Aron Xu <happyaron@ubuntu.com> | 2017-01-18 10:05:21 (GMT) |
|---|---|---|
| committer | Aron Xu <happyaron@ubuntu.com> | 2017-01-18 10:05:21 (GMT) |
| commit | 3727a844980a677bc66c4549eb38c1a545c3130d (patch) | |
| tree | 9b8c3695241967ec1b89241b66d8e0dd5d01cedb | |
| parent | b744b33359ac8f61dc37b3ae05e468559f45e63d (diff) | |
Backport patches from master branch for LP: #1647283xenial-1647283
9 files changed, 1179 insertions, 0 deletions
diff --git a/debian/patches/all-use-O_CLOEXEC-for-file-descriptors.patch b/debian/patches/all-use-O_CLOEXEC-for-file-descriptors.patch new file mode 100644 index 0000000..35c121c --- /dev/null +++ b/debian/patches/all-use-O_CLOEXEC-for-file-descriptors.patch @@ -0,0 +1,392 @@ +From: Thomas Haller <thaller@redhat.com> +Date: Sat, 10 Dec 2016 15:28:15 +0100 +Subject: all: use O_CLOEXEC for file descriptors + +(cherry picked from commit 4bdee37771ae741f4f9548b52c1db53ddf080fe8) +--- + src/devices/adsl/nm-device-adsl.c | 4 ++-- + src/devices/bluetooth/nm-bluez5-dun.c | 4 ++-- + src/devices/tests/test-lldp.c | 4 ++-- + src/devices/wwan/nm-modem.c | 2 +- + src/dns-manager/nm-dns-manager.c | 4 ++-- + src/main-utils.c | 2 +- + src/nm-manager.c | 2 +- + src/platform/nm-linux-platform.c | 2 +- + src/platform/nm-platform-utils.c | 4 ++-- + src/platform/nmp-netns.c | 6 +++--- + src/platform/tests/test-common.c | 12 ++++++------ + src/platform/wifi/wifi-utils-wext.c | 4 ++-- + src/ppp-manager/nm-ppp-manager.c | 4 ++-- + src/settings/nm-inotify-helper.c | 2 +- + src/settings/plugins/ifcfg-rh/shvar.c | 6 +++--- + src/settings/plugins/ifupdown/interface_parser.c | 2 +- + src/tests/test-general-with-expect.c | 3 ++- + 17 files changed, 34 insertions(+), 33 deletions(-) + +diff --git a/src/devices/adsl/nm-device-adsl.c b/src/devices/adsl/nm-device-adsl.c +index 2ab67c9..77c6e11 100644 +--- a/src/devices/adsl/nm-device-adsl.c ++++ b/src/devices/adsl/nm-device-adsl.c +@@ -154,7 +154,7 @@ br2684_assign_vcc (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) + g_return_val_if_fail (priv->brfd == -1, FALSE); + g_return_val_if_fail (priv->nas_ifname != NULL, FALSE); + +- priv->brfd = socket (PF_ATMPVC, SOCK_DGRAM, ATM_AAL5); ++ priv->brfd = socket (PF_ATMPVC, SOCK_DGRAM | SOCK_CLOEXEC, ATM_AAL5); + if (priv->brfd < 0) { + errsv = errno; + _LOGE (LOGD_ADSL, "failed to open ATM control socket (%d)", errsv); +@@ -338,7 +338,7 @@ br2684_create_iface (NMDeviceAdsl *self, + nm_clear_g_source (&priv->nas_update_id); + } + +- fd = socket (PF_ATMPVC, SOCK_DGRAM, ATM_AAL5); ++ fd = socket (PF_ATMPVC, SOCK_DGRAM | SOCK_CLOEXEC, ATM_AAL5); + if (fd < 0) { + errsv = errno; + _LOGE (LOGD_ADSL, "failed to open ATM control socket (%d)", errsv); +diff --git a/src/devices/bluetooth/nm-bluez5-dun.c b/src/devices/bluetooth/nm-bluez5-dun.c +index 4c93feb..aba3a0d 100644 +--- a/src/devices/bluetooth/nm-bluez5-dun.c ++++ b/src/devices/bluetooth/nm-bluez5-dun.c +@@ -64,7 +64,7 @@ dun_connect (NMBluez5DunContext *context) + .channel = context->rfcomm_channel + }; + +- context->rfcomm_fd = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); ++ context->rfcomm_fd = socket (AF_BLUETOOTH, SOCK_STREAM | SOCK_CLOEXEC, BTPROTO_RFCOMM); + if (context->rfcomm_fd < 0) { + int errsv = errno; + error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, +@@ -112,7 +112,7 @@ dun_connect (NMBluez5DunContext *context) + context->rfcomm_id = devid; + + snprintf (tty, ttylen, "/dev/rfcomm%d", devid); +- while ((context->rfcomm_tty_fd = open (tty, O_RDONLY | O_NOCTTY)) < 0 && try--) { ++ while ((context->rfcomm_tty_fd = open (tty, O_RDONLY | O_NOCTTY | O_CLOEXEC)) < 0 && try--) { + if (try) { + g_usleep (100 * 1000); + continue; +diff --git a/src/devices/tests/test-lldp.c b/src/devices/tests/test-lldp.c +index bff85e6..5af76ad 100644 +--- a/src/devices/tests/test-lldp.c ++++ b/src/devices/tests/test-lldp.c +@@ -352,7 +352,7 @@ _test_recv_fixture_setup (TestRecvFixture *fixture, gconstpointer user_data) + struct ifreq ifr = { }; + int fd, s; + +- fd = open ("/dev/net/tun", O_RDWR); ++ fd = open ("/dev/net/tun", O_RDWR | O_CLOEXEC); + g_assert (fd >= 0); + + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; +@@ -360,7 +360,7 @@ _test_recv_fixture_setup (TestRecvFixture *fixture, gconstpointer user_data) + g_assert (ioctl (fd, TUNSETIFF, &ifr) >= 0); + + /* Bring the interface up */ +- s = socket (AF_INET, SOCK_DGRAM, 0); ++ s = socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + g_assert (s >= 0); + ifr.ifr_flags |= IFF_UP; + g_assert (ioctl (s, SIOCSIFFLAGS, &ifr) >= 0); +diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c +index 2d7ee69..347dc12 100644 +--- a/src/devices/wwan/nm-modem.c ++++ b/src/devices/wwan/nm-modem.c +@@ -499,7 +499,7 @@ port_speed_is_zero (const char *port) + struct termios options; + nm_auto_close int fd = -1; + +- fd = open (port, O_RDWR | O_NONBLOCK | O_NOCTTY); ++ fd = open (port, O_RDWR | O_NONBLOCK | O_NOCTTY | O_CLOEXEC); + if (fd < 0) + return FALSE; + +diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c +index 135a7a9..2d0e515 100644 +--- a/src/dns-manager/nm-dns-manager.c ++++ b/src/dns-manager/nm-dns-manager.c +@@ -722,7 +722,7 @@ update_resolv_conf (NMDnsManager *self, + } + } + +- if ((f = fopen (MY_RESOLV_CONF_TMP, "w")) == NULL) { ++ if ((f = fopen (MY_RESOLV_CONF_TMP, "we")) == NULL) { + errsv = errno; + g_set_error (error, + NM_MANAGER_ERROR, +@@ -1591,7 +1591,7 @@ _check_resconf_immutable (NMDnsManagerResolvConfManager rc_manager) + } + } + +- fd = open (_PATH_RESCONF, O_RDONLY); ++ fd = open (_PATH_RESCONF, O_RDONLY | O_CLOEXEC); + if (fd != -1) { + if (ioctl (fd, FS_IOC_GETFLAGS, &flags) != -1) + immutable = NM_FLAGS_HAS (flags, FS_IMMUTABLE_FL); +diff --git a/src/main-utils.c b/src/main-utils.c +index 8624280..02fbe19 100644 +--- a/src/main-utils.c ++++ b/src/main-utils.c +@@ -95,7 +95,7 @@ nm_main_utils_write_pidfile (const char *pidfile) + int fd; + gboolean success = FALSE; + +- if ((fd = open (pidfile, O_CREAT|O_WRONLY|O_TRUNC, 00644)) < 0) { ++ if ((fd = open (pidfile, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 00644)) < 0) { + fprintf (stderr, _("Opening %s failed: %s\n"), pidfile, strerror (errno)); + return FALSE; + } +diff --git a/src/nm-manager.c b/src/nm-manager.c +index 6a09966..3c650f7 100644 +--- a/src/nm-manager.c ++++ b/src/nm-manager.c +@@ -5323,7 +5323,7 @@ rfkill_change (NMManager *self, const char *desc, RfKillType rtype, gboolean ena + g_return_if_fail (rtype == RFKILL_TYPE_WLAN || rtype == RFKILL_TYPE_WWAN); + + errno = 0; +- fd = open ("/dev/rfkill", O_RDWR); ++ fd = open ("/dev/rfkill", O_RDWR | O_CLOEXEC); + if (fd < 0) { + if (errno == EACCES) + _LOGW (LOGD_RFKILL, "(%s): failed to open killswitch device", desc); +diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c +index 94fad20..d3bd9e3 100644 +--- a/src/platform/nm-linux-platform.c ++++ b/src/platform/nm-linux-platform.c +@@ -5013,7 +5013,7 @@ tun_add (NMPlatform *platform, const char *name, gboolean tap, + _LOGD ("link: add %s '%s' owner %" G_GINT64_FORMAT " group %" G_GINT64_FORMAT, + tap ? "tap" : "tun", name, owner, group); + +- fd = open ("/dev/net/tun", O_RDWR); ++ fd = open ("/dev/net/tun", O_RDWR | O_CLOEXEC); + if (fd < 0) + return FALSE; + +diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c +index d274a55..1aaea53 100644 +--- a/src/platform/nm-platform-utils.c ++++ b/src/platform/nm-platform-utils.c +@@ -63,7 +63,7 @@ ethtool_get (const char *name, gpointer edata) + nm_utils_ifname_cpy (ifr.ifr_name, name); + ifr.ifr_data = edata; + +- fd = socket (PF_INET, SOCK_DGRAM, 0); ++ fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (fd < 0) { + nm_log_err (LOGD_PLATFORM, "ethtool: Could not open socket."); + return FALSE; +@@ -341,7 +341,7 @@ nmp_utils_mii_supports_carrier_detect (const char *ifname) + if (!nmp_utils_device_exists (ifname)) + return FALSE; + +- fd = socket (PF_INET, SOCK_DGRAM, 0); ++ fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (fd < 0) { + nm_log_err (LOGD_PLATFORM, "mii: couldn't open control socket (%s)", ifname); + return FALSE; +diff --git a/src/platform/nmp-netns.c b/src/platform/nmp-netns.c +index 2629585..07e134c 100644 +--- a/src/platform/nmp-netns.c ++++ b/src/platform/nmp-netns.c +@@ -277,7 +277,7 @@ _netns_new (GError **error) + int fd_net, fd_mnt; + int errsv; + +- fd_net = open (PROC_SELF_NS_NET, O_RDONLY); ++ fd_net = open (PROC_SELF_NS_NET, O_RDONLY | O_CLOEXEC); + if (fd_net == -1) { + errsv = errno; + g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, +@@ -286,7 +286,7 @@ _netns_new (GError **error) + return NULL; + } + +- fd_mnt = open (PROC_SELF_NS_MNT, O_RDONLY); ++ fd_mnt = open (PROC_SELF_NS_MNT, O_RDONLY | O_CLOEXEC); + if (fd_mnt == -1) { + errsv = errno; + g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, +@@ -623,7 +623,7 @@ nmp_netns_bind_to_path (NMPNetns *self, const char *filename, int *out_fd) + } + + if (out_fd) { +- if ((fd = open (filename, O_RDONLY)) == -1) { ++ if ((fd = open (filename, O_RDONLY | O_CLOEXEC)) == -1) { + errsv = errno; + _LOGE (self, "bind: failed to open %s: %s", filename, g_strerror (errsv)); + umount2 (filename, MNT_DETACH); +diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c +index b1947a6..d636ebe 100644 +--- a/src/platform/tests/test-common.c ++++ b/src/platform/tests/test-common.c +@@ -1398,7 +1398,7 @@ nmtstp_namespace_create (int unshare_flags, GError **error) + int pipefd_p2c[2]; + ssize_t r; + +- e = pipe (pipefd_c2p); ++ e = pipe2 (pipefd_c2p, O_CLOEXEC); + if (e != 0) { + errsv = errno; + g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, +@@ -1406,7 +1406,7 @@ nmtstp_namespace_create (int unshare_flags, GError **error) + return FALSE; + } + +- e = pipe (pipefd_p2c); ++ e = pipe2 (pipefd_p2c, O_CLOEXEC); + if (e != 0) { + errsv = errno; + g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, +@@ -1540,7 +1540,7 @@ nmtstp_namespace_get_fd_for_process (pid_t pid, const char *ns_name) + + nm_sprintf_buf (p, "/proc/%lu/ns/%s", (long unsigned) pid, ns_name); + +- return open(p, O_RDONLY); ++ return open(p, O_RDONLY | O_CLOEXEC); + } + + /*****************************************************************************/ +@@ -1564,21 +1564,21 @@ unshare_user (void) + + /* Since Linux 3.19 we have to disable setgroups() in order to map users. + * Just proceed if the file is not there. */ +- f = fopen ("/proc/self/setgroups", "w"); ++ f = fopen ("/proc/self/setgroups", "we"); + if (f) { + fprintf (f, "deny"); + fclose (f); + } + + /* Map current UID to root in NS to be created. */ +- f = fopen ("/proc/self/uid_map", "w"); ++ f = fopen ("/proc/self/uid_map", "we"); + if (!f) + return FALSE; + fprintf (f, "0 %d 1", uid); + fclose (f); + + /* Map current GID to root in NS to be created. */ +- f = fopen ("/proc/self/gid_map", "w"); ++ f = fopen ("/proc/self/gid_map", "we"); + if (!f) + return FALSE; + fprintf (f, "0 %d 1", gid); +diff --git a/src/platform/wifi/wifi-utils-wext.c b/src/platform/wifi/wifi-utils-wext.c +index af285b4..11e510f 100644 +--- a/src/platform/wifi/wifi-utils-wext.c ++++ b/src/platform/wifi/wifi-utils-wext.c +@@ -577,7 +577,7 @@ wifi_wext_init (const char *iface, int ifindex, gboolean check_scan) + wext->parent.set_mesh_channel = wifi_wext_set_mesh_channel; + wext->parent.set_mesh_ssid = wifi_wext_set_mesh_ssid; + +- wext->fd = socket (PF_INET, SOCK_DGRAM, 0); ++ wext->fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (wext->fd < 0) + goto error; + +@@ -665,7 +665,7 @@ wifi_wext_is_wifi (const char *iface) + if (!nmp_utils_device_exists (iface)) + return FALSE; + +- fd = socket (PF_INET, SOCK_DGRAM, 0); ++ fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (fd >= 0) { + nm_utils_ifname_cpy (iwr.ifr_ifrn.ifrn_name, iface); + if (ioctl (fd, SIOCGIWNAME, &iwr) == 0) +diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c +index fe81eb2..a524b22 100644 +--- a/src/ppp-manager/nm-ppp-manager.c ++++ b/src/ppp-manager/nm-ppp-manager.c +@@ -197,7 +197,7 @@ monitor_cb (gpointer user_data) + if (errno != ENODEV) + _LOGW ("could not read ppp stats: %s", strerror (errno)); + } else { +- g_signal_emit (manager, signals[STATS], 0, ++ g_signal_emit (manager, signals[STATS], 0, + stats.p.ppp_ibytes, + stats.p.ppp_obytes); + } +@@ -214,7 +214,7 @@ monitor_stats (NMPPPManager *manager) + if (priv->monitor_fd >= 0) + return; + +- priv->monitor_fd = socket (AF_INET, SOCK_DGRAM, 0); ++ priv->monitor_fd = socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (priv->monitor_fd >= 0) { + g_warn_if_fail (priv->monitor_id == 0); + if (priv->monitor_id) +diff --git a/src/settings/nm-inotify-helper.c b/src/settings/nm-inotify-helper.c +index ce15246..4611264 100644 +--- a/src/settings/nm-inotify-helper.c ++++ b/src/settings/nm-inotify-helper.c +@@ -128,7 +128,7 @@ init_inotify (NMInotifyHelper *self) + GIOChannel *channel; + guint source_id; + +- priv->ifd = inotify_init (); ++ priv->ifd = inotify_init1 (IN_CLOEXEC); + if (priv->ifd == -1) { + int errsv = errno; + +diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c +index 4e75634..ff19102 100644 +--- a/src/settings/plugins/ifcfg-rh/shvar.c ++++ b/src/settings/plugins/ifcfg-rh/shvar.c +@@ -55,11 +55,11 @@ svOpenFileInternal (const char *name, gboolean create, GError **error) + + s->fd = -1; + if (create) +- s->fd = open (name, O_RDWR); /* NOT O_CREAT */ ++ s->fd = open (name, O_RDWR | O_CLOEXEC); /* NOT O_CREAT */ + + if (!create || s->fd == -1) { + /* try read-only */ +- s->fd = open (name, O_RDONLY); /* NOT O_CREAT */ ++ s->fd = open (name, O_RDONLY | O_CLOEXEC); /* NOT O_CREAT */ + if (s->fd == -1) + errsv = errno; + else +@@ -467,7 +467,7 @@ svWriteFile (shvarFile *s, int mode, GError **error) + + if (s->modified) { + if (s->fd == -1) +- s->fd = open (s->fileName, O_WRONLY | O_CREAT, mode); ++ s->fd = open (s->fileName, O_WRONLY | O_CREAT | O_CLOEXEC, mode); + if (s->fd == -1) { + int errsv = errno; + +diff --git a/src/settings/plugins/ifupdown/interface_parser.c b/src/settings/plugins/ifupdown/interface_parser.c +index 7ad902d..cb60dbc 100644 +--- a/src/settings/plugins/ifupdown/interface_parser.c ++++ b/src/settings/plugins/ifupdown/interface_parser.c +@@ -117,7 +117,7 @@ _recursive_ifparser (const char *eni_file, int quiet) + nm_log_warn (LOGD_SETTINGS, "interfaces file %s doesn't exist\n", eni_file); + return; + } +- inp = fopen (eni_file, "r"); ++ inp = fopen (eni_file, "re"); + if (inp == NULL) { + if (!quiet) + nm_log_warn (LOGD_SETTINGS, "Can't open %s\n", eni_file); +diff --git a/src/tests/test-general-with-expect.c b/src/tests/test-general-with-expect.c +index 64b47bd..4c88689 100644 +--- a/src/tests/test-general-with-expect.c ++++ b/src/tests/test-general-with-expect.c +@@ -26,6 +26,7 @@ + #include <netinet/ether.h> + #include <sys/types.h> + #include <sys/wait.h> ++#include <fcntl.h> + + #include "NetworkManagerUtils.h" + #include "nm-multi-index.h" +@@ -173,7 +174,7 @@ test_nm_utils_kill_child_create_and_join_pgroup (void) + int pipefd[2]; + pid_t pgid; + +- err = pipe (pipefd); ++ err = pipe2 (pipefd, O_CLOEXEC); + g_assert (err == 0); + + pgid = fork(); diff --git a/debian/patches/core-add-utils-for-file-handling.patch b/debian/patches/core-add-utils-for-file-handling.patch new file mode 100644 index 0000000..1f8ae91 --- /dev/null +++ b/debian/patches/core-add-utils-for-file-handling.patch @@ -0,0 +1,163 @@ +From: Thomas Haller <thaller@redhat.com> +Date: Fri, 3 Jun 2016 13:56:18 +0200 +Subject: core: add utils for file handling + +Copied and adjusted from systemd code. +--- + src/nm-core-utils.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + src/nm-core-utils.h | 6 +++ + 2 files changed, 124 insertions(+) + +diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c +index 28e4f99..38ecd0b 100644 +--- a/src/nm-core-utils.c ++++ b/src/nm-core-utils.c +@@ -26,6 +26,7 @@ + #include <errno.h> + #include <fcntl.h> + #include <string.h> ++#include <poll.h> + #include <unistd.h> + #include <stdlib.h> + #include <resolv.h> +@@ -2663,6 +2664,123 @@ nm_utils_machine_id_read (void) + + /*****************************************************************************/ + ++/* taken from systemd's fd_wait_for_event(). Note that the timeout ++ * is here in nano-seconds, not micro-seconds. */ ++int ++nm_utils_fd_wait_for_event (int fd, int event, gint64 timeout_ns) ++{ ++ struct pollfd pollfd = { ++ .fd = fd, ++ .events = event, ++ }; ++ struct timespec ts, *pts; ++ int r; ++ ++ if (timeout_ns < 0) ++ pts = NULL; ++ else { ++ ts.tv_sec = (time_t) (timeout_ns / NM_UTILS_NS_PER_SECOND); ++ ts.tv_nsec = (long int) (timeout_ns % NM_UTILS_NS_PER_SECOND); ++ pts = &ts; ++ } ++ ++ r = ppoll (&pollfd, 1, pts, NULL); ++ if (r < 0) ++ return -errno; ++ if (r == 0) ++ return 0; ++ return pollfd.revents; ++} ++ ++/* taken from systemd's loop_read() */ ++ssize_t ++nm_utils_fd_read_loop (int fd, void *buf, size_t nbytes, bool do_poll) ++{ ++ uint8_t *p = buf; ++ ssize_t n = 0; ++ ++ g_return_val_if_fail (fd >= 0, -EINVAL); ++ g_return_val_if_fail (buf, -EINVAL); ++ ++ /* If called with nbytes == 0, let's call read() at least ++ * once, to validate the operation */ ++ ++ if (nbytes > (size_t) SSIZE_MAX) ++ return -EINVAL; ++ ++ do { ++ ssize_t k; ++ ++ k = read (fd, p, nbytes); ++ if (k < 0) { ++ if (errno == EINTR) ++ continue; ++ ++ if (errno == EAGAIN && do_poll) { ++ ++ /* We knowingly ignore any return value here, ++ * and expect that any error/EOF is reported ++ * via read() */ ++ ++ (void) nm_utils_fd_wait_for_event (fd, POLLIN, -1); ++ continue; ++ } ++ ++ return n > 0 ? n : -errno; ++ } ++ ++ if (k == 0) ++ return n; ++ ++ g_assert ((size_t) k <= nbytes); ++ ++ p += k; ++ nbytes -= k; ++ n += k; ++ } while (nbytes > 0); ++ ++ return n; ++} ++ ++/* taken from systemd's loop_read_exact() */ ++int ++nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll) ++{ ++ ssize_t n; ++ ++ n = nm_utils_fd_read_loop (fd, buf, nbytes, do_poll); ++ if (n < 0) ++ return (int) n; ++ if ((size_t) n != nbytes) ++ return -EIO; ++ ++ return 0; ++} ++ ++/* taken from systemd's dev_urandom(). */ ++int ++nm_utils_read_urandom (void *p, size_t nbytes) ++{ ++ int fd = -1; ++ int r; ++ ++again: ++ fd = open ("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); ++ if (fd < 0) { ++ r = errno; ++ if (r == EINTR) ++ goto again; ++ return r == ENOENT ? -ENOSYS : -r; ++ } ++ ++ r = nm_utils_fd_read_loop_exact (fd, p, nbytes, TRUE); ++ close (fd); ++ ++ return r; ++} ++ ++/*****************************************************************************/ ++ + guint8 * + nm_utils_secret_key_read (gsize *out_key_len, GError **error) + { +diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h +index a1213d2..312b611 100644 +--- a/src/nm-core-utils.h ++++ b/src/nm-core-utils.h +@@ -308,6 +308,12 @@ const char *nm_utils_ip4_property_path (const char *ifname, const char *property + + gboolean nm_utils_is_specific_hostname (const char *name); + ++int nm_utils_fd_wait_for_event (int fd, int event, gint64 timeout_ns); ++ssize_t nm_utils_fd_read_loop (int fd, void *buf, size_t nbytes, bool do_poll); ++int nm_utils_fd_read_loop_exact (int fd, void *buf, size_t nbytes, bool do_poll); ++ ++int nm_utils_read_urandom (void *p, size_t n); ++ + char *nm_utils_machine_id_read (void); + gboolean nm_utils_machine_id_parse (const char *id_str, /*uuid_t*/ guchar *out_uuid); + diff --git a/debian/patches/device-wwan-use-nm_auto_close-instead-of-gs_fd_close.patch b/debian/patches/device-wwan-use-nm_auto_close-instead-of-gs_fd_close.patch new file mode 100644 index 0000000..6c7e957 --- /dev/null +++ b/debian/patches/device-wwan-use-nm_auto_close-instead-of-gs_fd_close.patch @@ -0,0 +1,40 @@ +From: Thomas Haller <thaller@redhat.com> +Date: Fri, 9 Dec 2016 09:27:02 +0100 +Subject: device/wwan: use nm_auto_close instead of gs_fd_close + +(cherry picked from commit ed299cc8605a8291a61b3a514f8dc20390b18c77) +--- + src/devices/wwan/nm-modem.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c +index 9d562be..2d7ee69 100644 +--- a/src/devices/wwan/nm-modem.c ++++ b/src/devices/wwan/nm-modem.c +@@ -496,18 +496,18 @@ ppp_stats (NMPPPManager *ppp_manager, + static gboolean + port_speed_is_zero (const char *port) + { +- struct termios options; +- gs_fd_close int fd = -1; ++ struct termios options; ++ nm_auto_close int fd = -1; + +- fd = open (port, O_RDWR | O_NONBLOCK | O_NOCTTY); +- if (fd < 0) ++ fd = open (port, O_RDWR | O_NONBLOCK | O_NOCTTY); ++ if (fd < 0) + return FALSE; + +- memset (&options, 0, sizeof (struct termios)); +- if (tcgetattr (fd, &options) != 0) +- return FALSE; ++ memset (&options, 0, sizeof (struct termios)); ++ if (tcgetattr (fd, &options) != 0) ++ return FALSE; + +- return cfgetospeed (&options) == B0; ++ return cfgetospeed (&options) == B0; + } + + static NMActStageReturn diff --git a/debian/patches/platform-add-a-new-function-nmp_utils_open_sysctl.patch b/debian/patches/platform-add-a-new-function-nmp_utils_open_sysctl.patch new file mode 100644 index 0000000..603c4ed --- /dev/null +++ b/debian/patches/platform-add-a-new-function-nmp_utils_open_sysctl.patch @@ -0,0 +1,103 @@ +From: Kai-Heng Feng <kai.heng.feng@canonical.com> +Date: Wed, 7 Dec 2016 18:15:13 +0800 +Subject: platform: add a new function nmp_utils_open_sysctl() + +A race condition may happen when NetworkManager opens sysfs and udev +renames interface name at the same time. Thomas Haller provides a new +function [1] which can avoid the race condition when opening sysfs. + +This patch is a direct copy from [1]. + +[1] https://mail.gnome.org/archives/networkmanager-list/2016-December/msg00004.html + +Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> +(cherry picked from commit 713c74f6e4a88f874cf3e9908b3fb153f2ea5b83) +--- + src/platform/nm-platform-utils.c | 51 ++++++++++++++++++++++++++++++++++++++++ + src/platform/nm-platform-utils.h | 2 ++ + 2 files changed, 53 insertions(+) + +diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c +index b4542ad..85b3ded 100644 +--- a/src/platform/nm-platform-utils.c ++++ b/src/platform/nm-platform-utils.c +@@ -31,6 +31,7 @@ + #include <linux/mii.h> + #include <linux/version.h> + #include <linux/rtnetlink.h> ++#include <fcntl.h> + + #include "nm-utils.h" + #include "nm-setting-wired.h" +@@ -41,6 +42,8 @@ + * ethtool + ******************************************************************/ + ++extern char *if_indextoname (unsigned int __ifindex, char *__ifname); ++ + static gboolean + ethtool_get (const char *name, gpointer edata) + { +@@ -472,3 +475,51 @@ nmp_utils_ip_config_source_from_rtprot (guint rtprot) + } + } + ++int ++nmp_utils_open_sysctl(int ifindex, const char *ifname) ++{ ++ #define SYS_CLASS_NET "/sys/class/net/" ++ char ifname_buf[IFNAMSIZ]; ++ guint try_count = 0; ++ char sysdir[NM_STRLEN (SYS_CLASS_NET) + IFNAMSIZ + 1] = SYS_CLASS_NET; ++ char fd_buf[256]; ++ int fd; ++ int fd_ifindex; ++ ssize_t nn; ++ ++ while (++try_count < 4) { ++ if (!ifname) { ++ ifname = if_indextoname (ifindex, ifname_buf); ++ if (!ifname) ++ return -1; ++ } ++ ++ nm_utils_ifname_cpy (&sysdir[NM_STRLEN (SYS_CLASS_NET)], ifname); ++ fd = open (sysdir, O_DIRECTORY); ++ if (fd < 0) ++ goto next; ++ fd_ifindex = openat (fd, "ifindex", 0); ++ if (fd_ifindex < 0) { ++ close (fd); ++ goto next; ++ } ++ /* read ifindex file, and compare it to @ifindex. If match, return fd. */ ++ nn = nm_utils_fd_read_loop (fd_ifindex, fd_buf, sizeof (fd_buf) - 1, FALSE); ++ if (nn < 0) { ++ close (fd); ++ close (fd_ifindex); ++ goto next; ++ } ++ fd_buf[sizeof (fd_buf) - 1] = '\0'; ++ ++ if (ifindex != _nm_utils_ascii_str_to_int64 (fd_buf, 10, 1, G_MAXINT, -1)) { ++ close (fd); ++ close (fd_ifindex); ++ goto next; ++ } ++ return fd; ++next: ++ ifname = NULL; ++ } ++ return -1; ++} +diff --git a/src/platform/nm-platform-utils.h b/src/platform/nm-platform-utils.h +index f259474..6b5869e 100644 +--- a/src/platform/nm-platform-utils.h ++++ b/src/platform/nm-platform-utils.h +@@ -57,4 +57,6 @@ gboolean nmp_utils_device_exists (const char *name); + guint nmp_utils_ip_config_source_to_rtprot (NMIPConfigSource source); + NMIPConfigSource nmp_utils_ip_config_source_from_rtprot (guint rtprot); + ++int nmp_utils_open_sysctl(int ifindex, const char *ifname); ++ + #endif /* __NM_PLATFORM_UTILS_H__ */ diff --git a/debian/patches/platform-refactor-nmp_utils_sysctl_open_netdir.patch b/debian/patches/platform-refactor-nmp_utils_sysctl_open_netdir.patch new file mode 100644 index 0000000..12ac72a --- /dev/null +++ b/debian/patches/platform-refactor-nmp_utils_sysctl_open_netdir.patch @@ -0,0 +1,206 @@ +From: Thomas Haller <thaller@redhat.com> +Date: Thu, 8 Dec 2016 13:55:17 +0100 +Subject: platform: refactor nmp_utils_sysctl_open_netdir() + +- use nm_auto_close cleanup attribute +- optionally, return the found ifname +- don't stat "phy80211". If such an entity can be opened, + just assume it's a directory. + +(cherry picked from commit 76876e896c242fd82d048743ffcf2c0481442dc5) +--- + src/platform/nm-platform-utils.c | 94 +++++++++++++++++++++++++++------------- + src/platform/nm-platform-utils.h | 4 +- + src/platform/wifi/wifi-utils.c | 23 +++++----- + 3 files changed, 76 insertions(+), 45 deletions(-) + +diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c +index 85b3ded..d274a55 100644 +--- a/src/platform/nm-platform-utils.c ++++ b/src/platform/nm-platform-utils.c +@@ -38,12 +38,12 @@ + + #include "nm-core-utils.h" + ++extern char *if_indextoname (unsigned int __ifindex, char *__ifname); ++ + /****************************************************************** + * ethtool + ******************************************************************/ + +-extern char *if_indextoname (unsigned int __ifindex, char *__ifname); +- + static gboolean + ethtool_get (const char *name, gpointer edata) + { +@@ -475,51 +475,83 @@ nmp_utils_ip_config_source_from_rtprot (guint rtprot) + } + } + ++/** ++ * nmp_utils_sysctl_open_netdir: ++ * @ifindex: the ifindex for which to open "/sys/class/net/%s" ++ * @ifname_guess: (allow-none): optional argument, if present used as initial ++ * guess as the current name for @ifindex. If guessed right, ++ * it saves an addtional if_indextoname() call. ++ * @out_ifname: (allow-none): if present, must be at least IFNAMSIZ ++ * characters. On success, this will contain the actual ifname ++ * found while opening the directory. ++ * ++ * Returns: a negative value on failure, on success returns the open fd ++ * to the "/sys/class/net/%s" directory for @ifindex. ++ */ + int +-nmp_utils_open_sysctl(int ifindex, const char *ifname) ++nmp_utils_sysctl_open_netdir (int ifindex, ++ const char *ifname_guess, ++ char *out_ifname) + { + #define SYS_CLASS_NET "/sys/class/net/" ++ const char *ifname = ifname_guess; ++ char ifname_buf_last_try[IFNAMSIZ]; + char ifname_buf[IFNAMSIZ]; + guint try_count = 0; +- char sysdir[NM_STRLEN (SYS_CLASS_NET) + IFNAMSIZ + 1] = SYS_CLASS_NET; ++ char sysdir[NM_STRLEN (SYS_CLASS_NET) + IFNAMSIZ] = SYS_CLASS_NET; + char fd_buf[256]; +- int fd; +- int fd_ifindex; + ssize_t nn; + +- while (++try_count < 4) { ++ g_return_val_if_fail (ifindex >= 0, -1); ++ ++ ifname_buf_last_try[0] = '\0'; ++ ++ for (try_count = 0; try_count < 10; try_count++, ifname = NULL) { ++ nm_auto_close int fd_dir = -1; ++ nm_auto_close int fd_ifindex = -1; ++ int fd; ++ + if (!ifname) { + ifname = if_indextoname (ifindex, ifname_buf); + if (!ifname) + return -1; + } + +- nm_utils_ifname_cpy (&sysdir[NM_STRLEN (SYS_CLASS_NET)], ifname); +- fd = open (sysdir, O_DIRECTORY); +- if (fd < 0) +- goto next; +- fd_ifindex = openat (fd, "ifindex", 0); +- if (fd_ifindex < 0) { +- close (fd); +- goto next; +- } +- /* read ifindex file, and compare it to @ifindex. If match, return fd. */ +- nn = nm_utils_fd_read_loop (fd_ifindex, fd_buf, sizeof (fd_buf) - 1, FALSE); +- if (nn < 0) { +- close (fd); +- close (fd_ifindex); +- goto next; +- } +- fd_buf[sizeof (fd_buf) - 1] = '\0'; ++ nm_assert (nm_utils_iface_valid_name (ifname)); + +- if (ifindex != _nm_utils_ascii_str_to_int64 (fd_buf, 10, 1, G_MAXINT, -1)) { +- close (fd); +- close (fd_ifindex); +- goto next; +- } ++ if (g_strlcpy (&sysdir[NM_STRLEN (SYS_CLASS_NET)], ifname, IFNAMSIZ) >= IFNAMSIZ) ++ g_return_val_if_reached (-1); ++ ++ /* we only retry, if the name changed since previous attempt. ++ * Hence, it is extremely unlikely that this loop runes until the ++ * end of the @try_count. */ ++ if (nm_streq (ifname, ifname_buf_last_try)) ++ return -1; ++ strcpy (ifname_buf_last_try, ifname); ++ ++ fd_dir = open (sysdir, O_DIRECTORY | O_CLOEXEC); ++ if (fd_dir < 0) ++ continue; ++ ++ fd_ifindex = openat (fd_dir, "ifindex", O_CLOEXEC); ++ if (fd_ifindex < 0) ++ continue; ++ ++ nn = nm_utils_fd_read_loop (fd_ifindex, fd_buf, sizeof (fd_buf) - 2, FALSE); ++ if (nn <= 0) ++ continue; ++ fd_buf[nn] = '\0'; ++ ++ if (ifindex != _nm_utils_ascii_str_to_int64 (fd_buf, 10, 1, G_MAXINT, -1)) ++ continue; ++ ++ if (out_ifname) ++ strcpy (out_ifname, ifname); ++ ++ fd = fd_dir; ++ fd_dir = -1; + return fd; +-next: +- ifname = NULL; + } ++ + return -1; + } +diff --git a/src/platform/nm-platform-utils.h b/src/platform/nm-platform-utils.h +index 6b5869e..9bd82df 100644 +--- a/src/platform/nm-platform-utils.h ++++ b/src/platform/nm-platform-utils.h +@@ -57,6 +57,8 @@ gboolean nmp_utils_device_exists (const char *name); + guint nmp_utils_ip_config_source_to_rtprot (NMIPConfigSource source); + NMIPConfigSource nmp_utils_ip_config_source_from_rtprot (guint rtprot); + +-int nmp_utils_open_sysctl(int ifindex, const char *ifname); ++int nmp_utils_sysctl_open_netdir (int ifindex, ++ const char *ifname_guess, ++ char *out_ifname); + + #endif /* __NM_PLATFORM_UTILS_H__ */ +diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c +index 96c2be4..2ce6eb7 100644 +--- a/src/platform/wifi/wifi-utils.c ++++ b/src/platform/wifi/wifi-utils.c +@@ -187,29 +187,26 @@ wifi_utils_is_wifi (int ifindex, const char *ifname) + { + int fd_sysnet; + int fd_phy80211; +- struct stat s; ++ char ifname_verified[IFNAMSIZ]; + +- g_return_val_if_fail (ifname != NULL, FALSE); ++ g_return_val_if_fail (ifindex > 0, FALSE); + +- fd_sysnet = nmp_utils_open_sysctl (ifindex, ifname); ++ fd_sysnet = nmp_utils_sysctl_open_netdir (ifindex, ifname, ifname_verified); + if (fd_sysnet < 0) + return FALSE; + +- fd_phy80211 = openat (fd_sysnet, "phy80211", 0); +- if (fd_phy80211 < 0) { +- close (fd_sysnet); +- return FALSE; +- } ++ /* there might have been a race and ifname might be wrong. Below for checking ++ * wext, use the possibly improved name that we just verified. */ ++ ifname = ifname_verified; ++ ++ fd_phy80211 = openat (fd_sysnet, "phy80211", O_CLOEXEC); ++ close (fd_sysnet); + +- if ((fstat (fd_phy80211, &s) == 0 && (s.st_mode & S_IFDIR))) { +- close (fd_sysnet); ++ if (fd_phy80211 >= 0) { + close (fd_phy80211); + return TRUE; + } + +- close (fd_sysnet); +- close (fd_phy80211); +- + #if HAVE_WEXT + if (wifi_wext_is_wifi (ifname)) + return TRUE; diff --git a/debian/patches/platform-refactor-wifi_utils_is_wifi-not-to-pass-sys.patch b/debian/patches/platform-refactor-wifi_utils_is_wifi-not-to-pass-sys.patch new file mode 100644 index 0000000..eafb543 --- /dev/null +++ b/debian/patches/platform-refactor-wifi_utils_is_wifi-not-to-pass-sys.patch @@ -0,0 +1,93 @@ +From: Thomas Haller <thaller@redhat.com> +Date: Thu, 21 Apr 2016 14:25:38 +0200 +Subject: platform: refactor wifi_utils_is_wifi() not to pass sysfs_path + +wifi_utils_is_wifi() only has one caller, so it's very clear +what the passed in @sysfs_path contains. Instead of accepting +a redundant argument, compute the sysfs path internally based +on @iface alone. +--- + src/platform/nm-linux-platform.c | 2 +- + src/platform/wifi/wifi-utils.c | 21 ++++++++++++--------- + src/platform/wifi/wifi-utils.h | 2 +- + 3 files changed, 14 insertions(+), 11 deletions(-) + +diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c +index f6f7be8..25feb71 100644 +--- a/src/platform/nm-linux-platform.c ++++ b/src/platform/nm-linux-platform.c +@@ -729,7 +729,7 @@ _linktype_get_type (NMPlatform *platform, + } + + /* Fallback for drivers that don't call SET_NETDEV_DEVTYPE() */ +- if (wifi_utils_is_wifi (ifname, sysfs_path)) ++ if (wifi_utils_is_wifi (ifname)) + return NM_LINK_TYPE_WIFI; + + if (arptype == ARPHRD_ETHER) { +diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c +index 4f04041..b7fe86b 100644 +--- a/src/platform/wifi/wifi-utils.c ++++ b/src/platform/wifi/wifi-utils.c +@@ -21,16 +21,18 @@ + + #include "nm-default.h" + ++#include "wifi-utils.h" ++ + #include <sys/stat.h> + #include <stdio.h> + #include <string.h> + +-#include "wifi-utils.h" + #include "wifi-utils-private.h" + #include "wifi-utils-nl80211.h" + #if HAVE_WEXT + #include "wifi-utils-wext.h" + #endif ++#include "nm-core-utils.h" + + gpointer + wifi_data_new (const char *iface, int ifindex, gsize len) +@@ -178,19 +180,20 @@ wifi_utils_deinit (WifiData *data) + } + + gboolean +-wifi_utils_is_wifi (const char *iface, const char *sysfs_path) ++wifi_utils_is_wifi (const char *iface) + { +- char phy80211_path[255]; ++ char phy80211_path[NM_STRLEN ("/sys/class/net/123456789012345/phy80211\0") + 100 /*safety*/]; + struct stat s; + + g_return_val_if_fail (iface != NULL, FALSE); + +- if (sysfs_path) { +- /* Check for nl80211 sysfs paths */ +- g_snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", sysfs_path); +- if ((stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR))) +- return TRUE; +- } ++ nm_sprintf_buf (phy80211_path, ++ "/sys/class/net/%s/phy80211", ++ NM_ASSERT_VALID_PATH_COMPONENT (iface)); ++ nm_assert (strlen (phy80211_path) < sizeof (phy80211_path) - 1); ++ ++ if ((stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR))) ++ return TRUE; + + #if HAVE_WEXT + if (wifi_wext_is_wifi (iface)) +diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h +index 9555bbe..3a4f996 100644 +--- a/src/platform/wifi/wifi-utils.h ++++ b/src/platform/wifi/wifi-utils.h +@@ -29,7 +29,7 @@ + + typedef struct WifiData WifiData; + +-gboolean wifi_utils_is_wifi (const char *iface, const char *sysfs_path); ++gboolean wifi_utils_is_wifi (const char *iface); + + WifiData *wifi_utils_init (const char *iface, int ifindex, gboolean check_scan); + diff --git a/debian/patches/platform-wifi-use-nmp_utils_open_sysctl-to-check-if-.patch b/debian/patches/platform-wifi-use-nmp_utils_open_sysctl-to-check-if-.patch new file mode 100644 index 0000000..135cc77 --- /dev/null +++ b/debian/patches/platform-wifi-use-nmp_utils_open_sysctl-to-check-if-.patch @@ -0,0 +1,110 @@ +From: Kai-Heng Feng <kai.heng.feng@canonical.com> +Date: Wed, 7 Dec 2016 18:40:09 +0800 +Subject: platform: wifi: use nmp_utils_open_sysctl() to check if device is + wifi + +Since function nmp_utils_open_sysctl() can avoid race condition, use it +in wifi_utils_is_wifi() to open sysfs and correctly check if it's a wifi +device. + +https://bugzilla.gnome.org/show_bug.cgi?id=775613 +Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> +(cherry picked from commit b95556eb781a18ee1c96470f40b9e1e162b0ee60) +--- + src/platform/nm-linux-platform.c | 2 +- + src/platform/wifi/wifi-utils.c | 33 ++++++++++++++++++++++++--------- + src/platform/wifi/wifi-utils.h | 2 +- + 3 files changed, 26 insertions(+), 11 deletions(-) + +diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c +index 25feb71..94fad20 100644 +--- a/src/platform/nm-linux-platform.c ++++ b/src/platform/nm-linux-platform.c +@@ -729,7 +729,7 @@ _linktype_get_type (NMPlatform *platform, + } + + /* Fallback for drivers that don't call SET_NETDEV_DEVTYPE() */ +- if (wifi_utils_is_wifi (ifname)) ++ if (wifi_utils_is_wifi (ifindex, ifname)) + return NM_LINK_TYPE_WIFI; + + if (arptype == ARPHRD_ETHER) { +diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c +index b7fe86b..96c2be4 100644 +--- a/src/platform/wifi/wifi-utils.c ++++ b/src/platform/wifi/wifi-utils.c +@@ -26,6 +26,7 @@ + #include <sys/stat.h> + #include <stdio.h> + #include <string.h> ++#include <fcntl.h> + + #include "wifi-utils-private.h" + #include "wifi-utils-nl80211.h" +@@ -34,6 +35,8 @@ + #endif + #include "nm-core-utils.h" + ++#include "platform/nm-platform-utils.h" ++ + gpointer + wifi_data_new (const char *iface, int ifindex, gsize len) + { +@@ -180,23 +183,35 @@ wifi_utils_deinit (WifiData *data) + } + + gboolean +-wifi_utils_is_wifi (const char *iface) ++wifi_utils_is_wifi (int ifindex, const char *ifname) + { +- char phy80211_path[NM_STRLEN ("/sys/class/net/123456789012345/phy80211\0") + 100 /*safety*/]; ++ int fd_sysnet; ++ int fd_phy80211; + struct stat s; + +- g_return_val_if_fail (iface != NULL, FALSE); ++ g_return_val_if_fail (ifname != NULL, FALSE); + +- nm_sprintf_buf (phy80211_path, +- "/sys/class/net/%s/phy80211", +- NM_ASSERT_VALID_PATH_COMPONENT (iface)); +- nm_assert (strlen (phy80211_path) < sizeof (phy80211_path) - 1); ++ fd_sysnet = nmp_utils_open_sysctl (ifindex, ifname); ++ if (fd_sysnet < 0) ++ return FALSE; + +- if ((stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR))) ++ fd_phy80211 = openat (fd_sysnet, "phy80211", 0); ++ if (fd_phy80211 < 0) { ++ close (fd_sysnet); ++ return FALSE; ++ } ++ ++ if ((fstat (fd_phy80211, &s) == 0 && (s.st_mode & S_IFDIR))) { ++ close (fd_sysnet); ++ close (fd_phy80211); + return TRUE; ++ } ++ ++ close (fd_sysnet); ++ close (fd_phy80211); + + #if HAVE_WEXT +- if (wifi_wext_is_wifi (iface)) ++ if (wifi_wext_is_wifi (ifname)) + return TRUE; + #endif + +diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h +index 3a4f996..f84c12a 100644 +--- a/src/platform/wifi/wifi-utils.h ++++ b/src/platform/wifi/wifi-utils.h +@@ -29,7 +29,7 @@ + + typedef struct WifiData WifiData; + +-gboolean wifi_utils_is_wifi (const char *iface); ++gboolean wifi_utils_is_wifi (int ifindex, const char *ifname); + + WifiData *wifi_utils_init (const char *iface, int ifindex, gboolean check_scan); + diff --git a/debian/patches/series b/debian/patches/series index 8732e76..bb8b707 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -45,3 +45,13 @@ disable_general_with_expect_test.patch libnm-Check-self-still-NMManager-or-not.patch dns-manager-don-t-merge-split-DNS-search-domains.patch #manager-fix-state-transition-on-resuming-from-sleep.patch + +# for LP: #1647283 +shared-add-nm_auto_close-and-nm_auto_fclose.patch +device-wwan-use-nm_auto_close-instead-of-gs_fd_close.patch +core-add-utils-for-file-handling.patch +platform-add-a-new-function-nmp_utils_open_sysctl.patch +platform-refactor-wifi_utils_is_wifi-not-to-pass-sys.patch +platform-wifi-use-nmp_utils_open_sysctl-to-check-if-.patch +platform-refactor-nmp_utils_sysctl_open_netdir.patch +all-use-O_CLOEXEC-for-file-descriptors.patch diff --git a/debian/patches/shared-add-nm_auto_close-and-nm_auto_fclose.patch b/debian/patches/shared-add-nm_auto_close-and-nm_auto_fclose.patch new file mode 100644 index 0000000..3cb1cfa --- /dev/null +++ b/debian/patches/shared-add-nm_auto_close-and-nm_auto_fclose.patch @@ -0,0 +1,62 @@ +From: Thomas Haller <thaller@redhat.com> +Date: Fri, 9 Dec 2016 09:22:29 +0100 +Subject: shared: add nm_auto_close and nm_auto_fclose + +We already have gs_fd_close, which however doesn't preserve +errno and only checks for fd != -1. Add our own define. + +Downside is, we have to include stdio.h and errno.h, +which effectively ends up to be included *everywhere*. + +(cherry picked from commit 312cea870dfbc363da44074bd6f56ccd283c5420) +--- + shared/nm-macros-internal.h | 28 +++++++++++++++++++++++++++- + 1 file changed, 27 insertions(+), 1 deletion(-) + +diff --git a/shared/nm-macros-internal.h b/shared/nm-macros-internal.h +index fe27b76..a361a55 100644 +--- a/shared/nm-macros-internal.h ++++ b/shared/nm-macros-internal.h +@@ -22,7 +22,9 @@ + #ifndef __NM_MACROS_INTERNAL_H__ + #define __NM_MACROS_INTERNAL_H__ + ++#include <stdio.h> + #include <stdlib.h> ++#include <errno.h> + + /********************************************************/ + +@@ -54,7 +56,31 @@ _nm_auto_free_gstring_impl (GString **str) + } + #define nm_auto_free_gstring nm_auto(_nm_auto_free_gstring_impl) + +-/********************************************************/ ++static inline void ++_nm_auto_close_impl (int *pfd) ++{ ++ if (*pfd >= 0) { ++ int errsv = errno; ++ ++ (void) close (*pfd); ++ errno = errsv; ++ } ++} ++#define nm_auto_close nm_auto(_nm_auto_close_impl) ++ ++static inline void ++_nm_auto_fclose_impl (FILE **pfd) ++{ ++ if (*pfd) { ++ int errsv = errno; ++ ++ (void) fclose (*pfd); ++ errno = errsv; ++ } ++} ++#define nm_auto_fclose nm_auto(_nm_auto_fclose_impl) ++ ++/*****************************************************************************/ + + /* http://stackoverflow.com/a/11172679 */ + #define _NM_UTILS_MACRO_FIRST(...) __NM_UTILS_MACRO_FIRST_HELPER(__VA_ARGS__, throwaway) |
