diff --git a/src/devices/adsl/nm-atm-manager.c b/src/devices/adsl/nm-atm-manager.c index 2ff2fc184..b04e9fe71 100644 --- a/src/devices/adsl/nm-atm-manager.c +++ b/src/devices/adsl/nm-atm-manager.c @@ -137,7 +137,7 @@ adsl_add (NMAtmManager *self, GUdevDevice *udev_device) atm_index_path = g_strdup_printf ("/sys/class/atm/%s/atmindex", NM_ASSERT_VALID_PATH_COMPONENT (ifname)); atm_index = (int) nm_platform_sysctl_get_int_checked (NM_PLATFORM_GET, - atm_index_path, + NMP_SYSCTL_PATHID_ABSOLUTE (atm_index_path), 10, 0, G_MAXINT, -1); if (atm_index < 0) { diff --git a/src/devices/adsl/nm-device-adsl.c b/src/devices/adsl/nm-device-adsl.c index 6cf808e68..8f8037c25 100644 --- a/src/devices/adsl/nm-device-adsl.c +++ b/src/devices/adsl/nm-device-adsl.c @@ -547,7 +547,7 @@ carrier_update_cb (gpointer user_data) path = g_strdup_printf ("/sys/class/atm/%s/carrier", NM_ASSERT_VALID_PATH_COMPONENT (nm_device_get_iface (NM_DEVICE (self)))); - carrier = (int) nm_platform_sysctl_get_int_checked (NM_PLATFORM_GET, path, 10, 0, 1, -1); + carrier = (int) nm_platform_sysctl_get_int_checked (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (path), 10, 0, 1, -1); g_free (path); if (carrier != -1) diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index 43084d49b..5496bd9a5 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -208,7 +208,7 @@ _update_s390_subchannels (NMDeviceEthernet *self) gs_free char *path = NULL, *value = NULL; path = g_strdup_printf ("%s/%s", parent_path, item); - value = nm_platform_sysctl_get (NM_PLATFORM_GET, path); + value = nm_platform_sysctl_get (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (path)); if ( !strcmp (item, "portname") && !g_strcmp0 (value, "no portname required")) { diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index 47c2a0165..adcd07304 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -109,7 +109,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason) /* With some drivers the interface must be down to set transport mode */ nm_device_take_down (dev, TRUE); - ok = nm_platform_sysctl_set (NM_PLATFORM_GET, mode_path, transport_mode); + ok = nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (mode_path), transport_mode); g_free (mode_path); nm_device_bring_up (dev, TRUE, &no_firmware); diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 2785a1a89..af201d8ce 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -629,13 +629,13 @@ init_ip6_config_dns_priority (NMDevice *self, NMIP6Config *config) gboolean nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value) { - return nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (nm_device_get_ip_iface (self), property), value); + return nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (nm_device_get_ip_iface (self), property)), value); } static guint32 nm_device_ipv6_sysctl_get_int32 (NMDevice *self, const char *property, gint32 fallback) { - return nm_platform_sysctl_get_int32 (NM_PLATFORM_GET, nm_utils_ip6_property_path (nm_device_get_ip_iface (self), property), fallback); + return nm_platform_sysctl_get_int32 (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (nm_device_get_ip_iface (self), property)), fallback); } gboolean @@ -6771,7 +6771,7 @@ save_ip6_properties (NMDevice *self) g_hash_table_remove_all (priv->ip6_saved_properties); for (i = 0; i < G_N_ELEMENTS (ip6_properties_to_save); i++) { - value = nm_platform_sysctl_get (NM_PLATFORM_GET, nm_utils_ip6_property_path (ifname, ip6_properties_to_save[i])); + value = nm_platform_sysctl_get (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (ifname, ip6_properties_to_save[i]))); if (value) { g_hash_table_insert (priv->ip6_saved_properties, (char *) ip6_properties_to_save[i], @@ -6832,7 +6832,7 @@ set_nm_ipv6ll (NMDevice *self, gboolean enable) if (enable) { /* Bounce IPv6 to ensure the kernel stops IPv6LL address generation */ value = nm_platform_sysctl_get (NM_PLATFORM_GET, - nm_utils_ip6_property_path (nm_device_get_ip_iface (self), "disable_ipv6")); + NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (nm_device_get_ip_iface (self), "disable_ipv6"))); if (g_strcmp0 (value, "0") == 0) nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1"); g_free (value); @@ -6898,7 +6898,7 @@ _ip6_privacy_get (NMDevice *self) * Instead of reading static config files in /etc, just read the current sysctl value. * This works as NM only writes to "/proc/sys/net/ipv6/conf/IFNAME/use_tempaddr", but leaves * the "default" entry untouched. */ - ip6_privacy = nm_platform_sysctl_get_int32 (NM_PLATFORM_GET, "/proc/sys/net/ipv6/conf/default/use_tempaddr", NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + ip6_privacy = nm_platform_sysctl_get_int32 (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE ("/proc/sys/net/ipv6/conf/default/use_tempaddr"), NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); return _ip6_privacy_clamp (ip6_privacy); } @@ -7406,14 +7406,14 @@ share_init (void) char **iter; int errsv; - if (!nm_platform_sysctl_set (NM_PLATFORM_GET, "/proc/sys/net/ipv4/ip_forward", "1")) { + if (!nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE ("/proc/sys/net/ipv4/ip_forward"), "1")) { errsv = errno; nm_log_err (LOGD_SHARING, "share: error enabling IPv4 forwarding: (%d) %s", errsv, strerror (errsv)); return FALSE; } - if (!nm_platform_sysctl_set (NM_PLATFORM_GET, "/proc/sys/net/ipv4/ip_dynaddr", "1")) { + if (!nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE ("/proc/sys/net/ipv4/ip_dynaddr"), "1")) { errsv = errno; nm_log_err (LOGD_SHARING, "share: error enabling dynamic addresses: (%d) %s", errsv, strerror (errsv)); @@ -7754,7 +7754,7 @@ activate_stage5_ip6_config_commit (NMDevice *self) method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_SHARED) == 0) { - if (!nm_platform_sysctl_set (NM_PLATFORM_GET, "/proc/sys/net/ipv6/conf/all/forwarding", "1")) { + if (!nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE ("/proc/sys/net/ipv6/conf/all/forwarding"), "1")) { errsv = errno; _LOGE (LOGD_SHARING, "share: error enabling IPv6 forwarding: (%d) %s", errsv, strerror (errsv)); nm_device_ip_method_failed (self, AF_INET6, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); diff --git a/src/ndisc/nm-lndp-ndisc.c b/src/ndisc/nm-lndp-ndisc.c index 6378c9003..9e5cdaa05 100644 --- a/src/ndisc/nm-lndp-ndisc.c +++ b/src/ndisc/nm-lndp-ndisc.c @@ -521,7 +521,7 @@ static inline int ipv6_sysctl_get (NMPlatform *platform, const char *ifname, const char *property, int min, int max, int defval) { return (int) nm_platform_sysctl_get_int_checked (platform, - nm_utils_ip6_property_path (ifname, property), + NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (ifname, property)), 10, min, max, diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index aa14b085f..393e8acc5 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -246,7 +246,7 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in char val[16]; g_snprintf (val, sizeof (val), "%d", rdata->mtu); - nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (global_opt.ifname, "mtu"), val); + nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (global_opt.ifname, "mtu")), val); } nm_ip6_config_merge (existing, ndisc_config, NM_IP_CONFIG_MERGE_DEFAULT); @@ -465,7 +465,7 @@ main (int argc, char *argv[]) } if (global_opt.dhcp4_address) { - nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip4_property_path (global_opt.ifname, "promote_secondaries"), "1"); + nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip4_property_path (global_opt.ifname, "promote_secondaries")), "1"); dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (), global_opt.ifname, @@ -512,10 +512,10 @@ main (int argc, char *argv[]) if (iid) nm_ndisc_set_iid (ndisc, *iid); - nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (global_opt.ifname, "accept_ra"), "1"); - nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_defrtr"), "0"); - nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_pinfo"), "0"); - nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_rtr_pref"), "0"); + nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra")), "1"); + nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_defrtr")), "0"); + nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_pinfo")), "0"); + nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_ABSOLUTE (nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_rtr_pref")), "0"); g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 0f34b8453..b92f56ce2 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -118,21 +118,43 @@ _ip4_address_equal_peer_net (in_addr_t peer1, in_addr_t peer2, guint8 plen) /*****************************************************************************/ +#define ASSERT_SYSCTL_ARGS(pathid, dirfd, path) \ + G_STMT_START { \ + const char *const _pathid = (pathid); \ + const int _dirfd = (dirfd); \ + const char *const _path = (path); \ + \ + g_assert (_path && _path[0]); \ + g_assert (!strstr (_path, "/../")); \ + if (_dirfd < 0) { \ + g_assert (!_pathid); \ + g_assert (_path[0] == '/'); \ + g_assert ( g_str_has_prefix (_path, "/proc/sys/") \ + || g_str_has_prefix (_path, "/sys/")); \ + } else { \ + g_assert_not_reached (); \ + } \ + } G_STMT_END + static gboolean -sysctl_set (NMPlatform *platform, const char *path, const char *value) +sysctl_set (NMPlatform *platform, const char *pathid, int dirfd, const char *path, const char *value) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform); + ASSERT_SYSCTL_ARGS (pathid, dirfd, path); + g_hash_table_insert (priv->options, g_strdup (path), g_strdup (value)); return TRUE; } static char * -sysctl_get (NMPlatform *platform, const char *path) +sysctl_get (NMPlatform *platform, const char *pathid, int dirfd, const char *path) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE ((NMFakePlatform *) platform); + ASSERT_SYSCTL_ARGS (pathid, dirfd, path); + return g_strdup (g_hash_table_lookup (priv->options, path)); } diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 98f6cc070..6e7f4ccf6 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -2490,6 +2490,25 @@ ASSERT_NETNS_CURRENT (NMPlatform *platform) /*****************************************************************************/ +#define ASSERT_SYSCTL_ARGS(pathid, dirfd, path) \ + G_STMT_START { \ + const char *const _pathid = (pathid); \ + const int _dirfd = (dirfd); \ + const char *const _path = (path); \ + \ + nm_assert (_path && _path[0]); \ + g_assert (!strstr (_path, "/../")); \ + if (_dirfd < 0) { \ + nm_assert (!_pathid); \ + nm_assert (_path[0] == '/'); \ + nm_assert ( g_str_has_prefix (_path, "/proc/sys/") \ + || g_str_has_prefix (_path, "/sys/")); \ + } else { \ + nm_assert (_pathid && _pathid[0] && _pathid[0] != '/'); \ + nm_assert (_path[0] != '/'); \ + } \ + } G_STMT_END + static void _log_dbg_sysctl_set_impl (NMPlatform *platform, const char *path, const char *value) { @@ -2521,7 +2540,7 @@ _log_dbg_sysctl_set_impl (NMPlatform *platform, const char *path, const char *va } G_STMT_END static gboolean -sysctl_set (NMPlatform *platform, const char *path, const char *value) +sysctl_set (NMPlatform *platform, const char *pathid, int dirfd, const char *path, const char *value) { nm_auto_pop_netns NMPNetns *netns = NULL; int fd, tries; @@ -2534,11 +2553,7 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value) g_return_val_if_fail (path != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); - /* Don't write outside known locations */ - g_assert (g_str_has_prefix (path, "/proc/sys/") - || g_str_has_prefix (path, "/sys/")); - /* Don't write to suspicious locations */ - g_assert (!strstr (path, "/../")); + ASSERT_SYSCTL_ARGS (pathid, dirfd, path); if (!nm_platform_netns_push (platform, &netns)) { errno = ENETDOWN; @@ -2676,17 +2691,13 @@ _log_dbg_sysctl_get_impl (NMPlatform *platform, const char *path, const char *co } G_STMT_END static char * -sysctl_get (NMPlatform *platform, const char *path) +sysctl_get (NMPlatform *platform, const char *pathid, int dirfd, const char *path) { nm_auto_pop_netns NMPNetns *netns = NULL; GError *error = NULL; char *contents; - /* Don't write outside known locations */ - g_assert (g_str_has_prefix (path, "/proc/sys/") - || g_str_has_prefix (path, "/sys/")); - /* Don't write to suspicious locations */ - g_assert (!strstr (path, "/../")); + ASSERT_SYSCTL_ARGS (pathid, dirfd, path); if (!nm_platform_netns_push (platform, &netns)) return NULL; @@ -4561,7 +4572,7 @@ link_get_physical_port_id (NMPlatform *platform, int ifindex) ifname = NM_ASSERT_VALID_PATH_COMPONENT (ifname); path = g_strdup_printf ("/sys/class/net/%s/phys_port_id", ifname); - id = sysctl_get (platform, path); + id = sysctl_get (platform, NMP_SYSCTL_PATHID_ABSOLUTE (path)); g_free (path); return id; @@ -4581,7 +4592,7 @@ link_get_dev_id (NMPlatform *platform, int ifindex) ifname = NM_ASSERT_VALID_PATH_COMPONENT (ifname); path = g_strdup_printf ("/sys/class/net/%s/dev_id", ifname); - id = sysctl_get (platform, path); + id = sysctl_get (platform, NMP_SYSCTL_PATHID_ABSOLUTE (path)); if (!id || !*id) return 0; @@ -5269,7 +5280,7 @@ _infiniband_partition_action (NMPlatform *platform, ? "create_child" : "delete_child")); nm_sprintf_buf (id, "0x%04x", p_key); - success = nm_platform_sysctl_set (platform, path, id); + success = nm_platform_sysctl_set (platform, NMP_SYSCTL_PATHID_ABSOLUTE (path), id); if (!success) { if ( action == INFINIBAND_ACTION_DELETE_CHILD && errno == ENODEV) diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index af574a355..57f69c988 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -268,6 +268,9 @@ nm_platform_process_events (NMPlatform *self) /** * nm_platform_sysctl_set: * @self: platform instance + * @pathid: if @dirfd is present, this must be the full path that is looked up. + * It is required for logging. + * @dirfd: optional file descriptor for parent directory for openat() * @path: Absolute option path * @value: Value to write * @@ -278,14 +281,14 @@ nm_platform_process_events (NMPlatform *self) * Returns: %TRUE on success. */ gboolean -nm_platform_sysctl_set (NMPlatform *self, const char *path, const char *value) +nm_platform_sysctl_set (NMPlatform *self, const char *pathid, int dirfd, const char *path, const char *value) { _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (path, FALSE); g_return_val_if_fail (value, FALSE); - return klass->sysctl_set (self, path, value); + return klass->sysctl_set (self, pathid, dirfd, path, value); } gboolean @@ -305,7 +308,7 @@ nm_platform_sysctl_set_ip6_hop_limit_safe (NMPlatform *self, const char *iface, return FALSE; path = nm_utils_ip6_property_path (iface, "hop_limit"); - cur = nm_platform_sysctl_get_int_checked (self, path, 10, 1, G_MAXINT32, -1); + cur = nm_platform_sysctl_get_int_checked (self, NMP_SYSCTL_PATHID_ABSOLUTE (path), 10, 1, G_MAXINT32, -1); /* only allow increasing the hop-limit to avoid DOS by an attacker * setting a low hop-limit (CVE-2015-2924, rh#1209902) */ @@ -316,7 +319,7 @@ nm_platform_sysctl_set_ip6_hop_limit_safe (NMPlatform *self, const char *iface, char svalue[20]; sprintf (svalue, "%d", value); - nm_platform_sysctl_set (self, path, svalue); + nm_platform_sysctl_set (self, NMP_SYSCTL_PATHID_ABSOLUTE (path), svalue); } return TRUE; @@ -325,23 +328,29 @@ nm_platform_sysctl_set_ip6_hop_limit_safe (NMPlatform *self, const char *iface, /** * nm_platform_sysctl_get: * @self: platform instance + * @dirfd: if non-negative, used to lookup the path via openat(). + * @pathid: if @dirfd is present, this must be the full path that is looked up. + * It is required for logging. * @path: Absolute path to sysctl * * Returns: (transfer full): Contents of the virtual sysctl file. */ char * -nm_platform_sysctl_get (NMPlatform *self, const char *path) +nm_platform_sysctl_get (NMPlatform *self, const char *pathid, int dirfd, const char *path) { _CHECK_SELF (self, klass, NULL); g_return_val_if_fail (path, NULL); - return klass->sysctl_get (self, path); + return klass->sysctl_get (self, pathid, dirfd, path); } /** * nm_platform_sysctl_get_int32: * @self: platform instance + * @pathid: if @dirfd is present, this must be the full path that is looked up. + * It is required for logging. + * @dirfd: if non-negative, used to lookup the path via openat(). * @path: Absolute path to sysctl * @fallback: default value, if the content of path could not be read * as decimal integer. @@ -351,14 +360,17 @@ nm_platform_sysctl_get (NMPlatform *self, const char *path) * value, on success %errno will be set to zero. */ gint32 -nm_platform_sysctl_get_int32 (NMPlatform *self, const char *path, gint32 fallback) +nm_platform_sysctl_get_int32 (NMPlatform *self, const char *pathid, int dirfd, const char *path, gint32 fallback) { - return nm_platform_sysctl_get_int_checked (self, path, 10, G_MININT32, G_MAXINT32, fallback); + return nm_platform_sysctl_get_int_checked (self, pathid, dirfd, path, 10, G_MININT32, G_MAXINT32, fallback); } /** * nm_platform_sysctl_get_int_checked: * @self: platform instance + * @pathid: if @dirfd is present, this must be the full path that is looked up. + * It is required for logging. + * @dirfd: if non-negative, used to lookup the path via openat(). * @path: Absolute path to sysctl * @base: base of numeric conversion * @min: minimal value that is still valid @@ -373,7 +385,7 @@ nm_platform_sysctl_get_int32 (NMPlatform *self, const char *path, gint32 fallbac * (inclusive) or @fallback. */ gint64 -nm_platform_sysctl_get_int_checked (NMPlatform *self, const char *path, guint base, gint64 min, gint64 max, gint64 fallback) +nm_platform_sysctl_get_int_checked (NMPlatform *self, const char *pathid, int dirfd, const char *path, guint base, gint64 min, gint64 max, gint64 fallback) { char *value = NULL; gint32 ret; @@ -383,7 +395,7 @@ nm_platform_sysctl_get_int_checked (NMPlatform *self, const char *path, guint ba g_return_val_if_fail (path, fallback); if (path) - value = nm_platform_sysctl_get (self, path); + value = nm_platform_sysctl_get (self, pathid, dirfd, path); if (!value) { errno = EINVAL; @@ -1687,7 +1699,7 @@ link_set_option (NMPlatform *self, int master, const char *category, const char { gs_free char *path = link_option_path (self, master, category, option); - return path && nm_platform_sysctl_set (self, path, value); + return path && nm_platform_sysctl_set (self, NMP_SYSCTL_PATHID_ABSOLUTE (path), value); } static char * @@ -1695,7 +1707,7 @@ link_get_option (NMPlatform *self, int master, const char *category, const char { gs_free char *path = link_option_path (self, master, category, option); - return path ? nm_platform_sysctl_get (self, path) : NULL; + return path ? nm_platform_sysctl_get (self, NMP_SYSCTL_PATHID_ABSOLUTE (path)) : NULL; } static const char * @@ -2004,7 +2016,7 @@ nm_platform_link_infiniband_get_properties (NMPlatform *self, /* Fall back to reading sysfs */ path = g_strdup_printf ("/sys/class/net/%s/mode", iface); - contents = nm_platform_sysctl_get (self, path); + contents = nm_platform_sysctl_get (self, NMP_SYSCTL_PATHID_ABSOLUTE (path)); g_free (path); if (!contents) return FALSE; @@ -2018,7 +2030,7 @@ nm_platform_link_infiniband_get_properties (NMPlatform *self, g_free (contents); path = g_strdup_printf ("/sys/class/net/%s/pkey", iface); - contents = nm_platform_sysctl_get (self, path); + contents = nm_platform_sysctl_get (self, NMP_SYSCTL_PATHID_ABSOLUTE (path)); g_free (path); if (!contents) return FALSE; @@ -2244,7 +2256,7 @@ nm_platform_link_tun_get_properties_ifname (NMPlatform *self, const char *ifname return FALSE; nm_sprintf_buf (path, "/sys/class/net/%s/owner", ifname); - val = nm_platform_sysctl_get (self, path); + val = nm_platform_sysctl_get (self, NMP_SYSCTL_PATHID_ABSOLUTE (path)); if (val) { props->owner = _nm_utils_ascii_str_to_int64 (val, 10, -1, G_MAXINT64, -1); if (errno) @@ -2254,7 +2266,7 @@ nm_platform_link_tun_get_properties_ifname (NMPlatform *self, const char *ifname success = FALSE; nm_sprintf_buf (path, "/sys/class/net/%s/group", ifname); - val = nm_platform_sysctl_get (self, path); + val = nm_platform_sysctl_get (self, NMP_SYSCTL_PATHID_ABSOLUTE (path)); if (val) { props->group = _nm_utils_ascii_str_to_int64 (val, 10, -1, G_MAXINT64, -1); if (errno) @@ -2264,7 +2276,7 @@ nm_platform_link_tun_get_properties_ifname (NMPlatform *self, const char *ifname success = FALSE; nm_sprintf_buf (path, "/sys/class/net/%s/tun_flags", ifname); - val = nm_platform_sysctl_get (self, path); + val = nm_platform_sysctl_get (self, NMP_SYSCTL_PATHID_ABSOLUTE (path)); if (val) { gint64 flags; diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index a546e4eae..5ed978e46 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -500,8 +500,8 @@ struct _NMPlatform { typedef struct { GObjectClass parent; - gboolean (*sysctl_set) (NMPlatform *, const char *path, const char *value); - char * (*sysctl_get) (NMPlatform *, const char *path); + gboolean (*sysctl_set) (NMPlatform *, const char *pathid, int dirfd, const char *path, const char *value); + char * (*sysctl_get) (NMPlatform *, const char *pathid, int dirfd, const char *path); const NMPlatformLink *(*link_get) (NMPlatform *platform, int ifindex); const NMPlatformLink *(*link_get_by_ifname) (NMPlatform *platform, const char *ifname); @@ -717,10 +717,13 @@ const char *nm_link_type_to_string (NMLinkType link_type); const char *_nm_platform_error_to_string (NMPlatformError error); #define nm_platform_error_to_string(error) NM_UTILS_LOOKUP_STR (_nm_platform_error_to_string, error) -gboolean nm_platform_sysctl_set (NMPlatform *self, const char *path, const char *value); -char *nm_platform_sysctl_get (NMPlatform *self, const char *path); -gint32 nm_platform_sysctl_get_int32 (NMPlatform *self, const char *path, gint32 fallback); -gint64 nm_platform_sysctl_get_int_checked (NMPlatform *self, const char *path, guint base, gint64 min, gint64 max, gint64 fallback); +#define NMP_SYSCTL_PATHID_ABSOLUTE(path) \ + ((const char *) NULL), -1, (path) + +gboolean nm_platform_sysctl_set (NMPlatform *self, const char *pathid, int dirfd, const char *path, const char *value); +char *nm_platform_sysctl_get (NMPlatform *self, const char *pathid, int dirfd, const char *path); +gint32 nm_platform_sysctl_get_int32 (NMPlatform *self, const char *pathid, int dirfd, const char *path, gint32 fallback); +gint64 nm_platform_sysctl_get_int_checked (NMPlatform *self, const char *pathid, int dirfd, const char *path, guint base, gint64 min, gint64 max, gint64 fallback); gboolean nm_platform_sysctl_set_ip6_hop_limit_safe (NMPlatform *self, const char *iface, int value); diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index e3b55e73c..ebeea1b30 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -1941,7 +1941,7 @@ _test_netns_check_skip (void) G_STMT_START { \ gs_free char *_val = NULL; \ \ - _val = nm_platform_sysctl_get (plat, path); \ + _val = nm_platform_sysctl_get (plat, NMP_SYSCTL_PATHID_ABSOLUTE (path)); \ g_assert_cmpstr (_val, ==, value); \ } G_STMT_END @@ -2013,7 +2013,7 @@ test_netns_general (gpointer fixture, gconstpointer test_data) else path = "/proc/sys/net/ipv6/conf/dummy2b/disable_ipv6"; } - g_assert (nm_platform_sysctl_set (pl, path, nm_sprintf_buf (sbuf, "%d", j))); + g_assert (nm_platform_sysctl_set (pl, NMP_SYSCTL_PATHID_ABSOLUTE (path), nm_sprintf_buf (sbuf, "%d", j))); _sysctl_assert_eq (pl, path, nm_sprintf_buf (sbuf, "%d", j)); } @@ -2187,7 +2187,7 @@ test_netns_push (gpointer fixture, gconstpointer test_data) _ADD_DUMMY (pl[i].platform, pl[i].device_name); - g_assert (nm_platform_sysctl_set (pl[i].platform, pl[i].sysctl_path, pl[i].sysctl_value)); + g_assert (nm_platform_sysctl_set (pl[i].platform, NMP_SYSCTL_PATHID_ABSOLUTE (pl[i].sysctl_path), pl[i].sysctl_value)); tmp = _get_current_namespace_id (CLONE_NEWNET); g_ptr_array_add (device_names, tmp);