platform: add optional dirfd argument to sysctl functions

Still unused.
This commit is contained in:
Thomas Haller
2016-12-08 14:29:00 +01:00
parent 1d9bdad1df
commit d8cefd57fb
12 changed files with 110 additions and 62 deletions

View File

@@ -137,7 +137,7 @@ adsl_add (NMAtmManager *self, GUdevDevice *udev_device)
atm_index_path = g_strdup_printf ("/sys/class/atm/%s/atmindex", atm_index_path = g_strdup_printf ("/sys/class/atm/%s/atmindex",
NM_ASSERT_VALID_PATH_COMPONENT (ifname)); NM_ASSERT_VALID_PATH_COMPONENT (ifname));
atm_index = (int) nm_platform_sysctl_get_int_checked (NM_PLATFORM_GET, 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, 10, 0, G_MAXINT,
-1); -1);
if (atm_index < 0) { if (atm_index < 0) {

View File

@@ -547,7 +547,7 @@ carrier_update_cb (gpointer user_data)
path = g_strdup_printf ("/sys/class/atm/%s/carrier", path = g_strdup_printf ("/sys/class/atm/%s/carrier",
NM_ASSERT_VALID_PATH_COMPONENT (nm_device_get_iface (NM_DEVICE (self)))); 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); g_free (path);
if (carrier != -1) if (carrier != -1)

View File

@@ -208,7 +208,7 @@ _update_s390_subchannels (NMDeviceEthernet *self)
gs_free char *path = NULL, *value = NULL; gs_free char *path = NULL, *value = NULL;
path = g_strdup_printf ("%s/%s", parent_path, item); 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") if ( !strcmp (item, "portname")
&& !g_strcmp0 (value, "no portname required")) { && !g_strcmp0 (value, "no portname required")) {

View File

@@ -109,7 +109,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
/* With some drivers the interface must be down to set transport mode */ /* With some drivers the interface must be down to set transport mode */
nm_device_take_down (dev, TRUE); 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); g_free (mode_path);
nm_device_bring_up (dev, TRUE, &no_firmware); nm_device_bring_up (dev, TRUE, &no_firmware);

View File

@@ -629,13 +629,13 @@ init_ip6_config_dns_priority (NMDevice *self, NMIP6Config *config)
gboolean gboolean
nm_device_ipv6_sysctl_set (NMDevice *self, const char *property, const char *value) 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 static guint32
nm_device_ipv6_sysctl_get_int32 (NMDevice *self, const char *property, gint32 fallback) 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 gboolean
@@ -6771,7 +6771,7 @@ save_ip6_properties (NMDevice *self)
g_hash_table_remove_all (priv->ip6_saved_properties); g_hash_table_remove_all (priv->ip6_saved_properties);
for (i = 0; i < G_N_ELEMENTS (ip6_properties_to_save); i++) { 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) { if (value) {
g_hash_table_insert (priv->ip6_saved_properties, g_hash_table_insert (priv->ip6_saved_properties,
(char *) ip6_properties_to_save[i], (char *) ip6_properties_to_save[i],
@@ -6832,7 +6832,7 @@ set_nm_ipv6ll (NMDevice *self, gboolean enable)
if (enable) { if (enable) {
/* Bounce IPv6 to ensure the kernel stops IPv6LL address generation */ /* Bounce IPv6 to ensure the kernel stops IPv6LL address generation */
value = nm_platform_sysctl_get (NM_PLATFORM_GET, 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) if (g_strcmp0 (value, "0") == 0)
nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1"); nm_device_ipv6_sysctl_set (self, "disable_ipv6", "1");
g_free (value); 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. * 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 * This works as NM only writes to "/proc/sys/net/ipv6/conf/IFNAME/use_tempaddr", but leaves
* the "default" entry untouched. */ * 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); return _ip6_privacy_clamp (ip6_privacy);
} }
@@ -7406,14 +7406,14 @@ share_init (void)
char **iter; char **iter;
int errsv; 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; errsv = errno;
nm_log_err (LOGD_SHARING, "share: error enabling IPv4 forwarding: (%d) %s", nm_log_err (LOGD_SHARING, "share: error enabling IPv4 forwarding: (%d) %s",
errsv, strerror (errsv)); errsv, strerror (errsv));
return FALSE; 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; errsv = errno;
nm_log_err (LOGD_SHARING, "share: error enabling dynamic addresses: (%d) %s", nm_log_err (LOGD_SHARING, "share: error enabling dynamic addresses: (%d) %s",
errsv, strerror (errsv)); 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); method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG);
if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_SHARED) == 0) { 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; errsv = errno;
_LOGE (LOGD_SHARING, "share: error enabling IPv6 forwarding: (%d) %s", errsv, strerror (errsv)); _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); nm_device_ip_method_failed (self, AF_INET6, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);

View File

@@ -521,7 +521,7 @@ static inline int
ipv6_sysctl_get (NMPlatform *platform, const char *ifname, const char *property, int min, int max, int defval) 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, 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, 10,
min, min,
max, max,

View File

@@ -246,7 +246,7 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
char val[16]; char val[16];
g_snprintf (val, sizeof (val), "%d", rdata->mtu); 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); 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) { 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 (), dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (),
global_opt.ifname, global_opt.ifname,
@@ -512,10 +512,10 @@ main (int argc, char *argv[])
if (iid) if (iid)
nm_ndisc_set_iid (ndisc, *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, NMP_SYSCTL_PATHID_ABSOLUTE (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, NMP_SYSCTL_PATHID_ABSOLUTE (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, NMP_SYSCTL_PATHID_ABSOLUTE (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_rtr_pref")), "0");
g_signal_connect (NM_PLATFORM_GET, g_signal_connect (NM_PLATFORM_GET,
NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED,

View File

@@ -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 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); 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)); g_hash_table_insert (priv->options, g_strdup (path), g_strdup (value));
return TRUE; return TRUE;
} }
static char * 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); 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)); return g_strdup (g_hash_table_lookup (priv->options, path));
} }

View File

@@ -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 static void
_log_dbg_sysctl_set_impl (NMPlatform *platform, const char *path, const char *value) _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 } G_STMT_END
static gboolean 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; nm_auto_pop_netns NMPNetns *netns = NULL;
int fd, tries; 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 (path != NULL, FALSE);
g_return_val_if_fail (value != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE);
/* Don't write outside known locations */ ASSERT_SYSCTL_ARGS (pathid, dirfd, path);
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, "/../"));
if (!nm_platform_netns_push (platform, &netns)) { if (!nm_platform_netns_push (platform, &netns)) {
errno = ENETDOWN; errno = ENETDOWN;
@@ -2676,17 +2691,13 @@ _log_dbg_sysctl_get_impl (NMPlatform *platform, const char *path, const char *co
} G_STMT_END } G_STMT_END
static char * 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; nm_auto_pop_netns NMPNetns *netns = NULL;
GError *error = NULL; GError *error = NULL;
char *contents; char *contents;
/* Don't write outside known locations */ ASSERT_SYSCTL_ARGS (pathid, dirfd, path);
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, "/../"));
if (!nm_platform_netns_push (platform, &netns)) if (!nm_platform_netns_push (platform, &netns))
return NULL; return NULL;
@@ -4561,7 +4572,7 @@ link_get_physical_port_id (NMPlatform *platform, int ifindex)
ifname = NM_ASSERT_VALID_PATH_COMPONENT (ifname); ifname = NM_ASSERT_VALID_PATH_COMPONENT (ifname);
path = g_strdup_printf ("/sys/class/net/%s/phys_port_id", 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); g_free (path);
return id; return id;
@@ -4581,7 +4592,7 @@ link_get_dev_id (NMPlatform *platform, int ifindex)
ifname = NM_ASSERT_VALID_PATH_COMPONENT (ifname); ifname = NM_ASSERT_VALID_PATH_COMPONENT (ifname);
path = g_strdup_printf ("/sys/class/net/%s/dev_id", 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) if (!id || !*id)
return 0; return 0;
@@ -5269,7 +5280,7 @@ _infiniband_partition_action (NMPlatform *platform,
? "create_child" ? "create_child"
: "delete_child")); : "delete_child"));
nm_sprintf_buf (id, "0x%04x", p_key); 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 (!success) {
if ( action == INFINIBAND_ACTION_DELETE_CHILD if ( action == INFINIBAND_ACTION_DELETE_CHILD
&& errno == ENODEV) && errno == ENODEV)

View File

@@ -268,6 +268,9 @@ nm_platform_process_events (NMPlatform *self)
/** /**
* nm_platform_sysctl_set: * nm_platform_sysctl_set:
* @self: platform instance * @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 * @path: Absolute option path
* @value: Value to write * @value: Value to write
* *
@@ -278,14 +281,14 @@ nm_platform_process_events (NMPlatform *self)
* Returns: %TRUE on success. * Returns: %TRUE on success.
*/ */
gboolean 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); _CHECK_SELF (self, klass, FALSE);
g_return_val_if_fail (path, FALSE); g_return_val_if_fail (path, FALSE);
g_return_val_if_fail (value, 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 gboolean
@@ -305,7 +308,7 @@ nm_platform_sysctl_set_ip6_hop_limit_safe (NMPlatform *self, const char *iface,
return FALSE; return FALSE;
path = nm_utils_ip6_property_path (iface, "hop_limit"); 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 /* only allow increasing the hop-limit to avoid DOS by an attacker
* setting a low hop-limit (CVE-2015-2924, rh#1209902) */ * 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]; char svalue[20];
sprintf (svalue, "%d", value); sprintf (svalue, "%d", value);
nm_platform_sysctl_set (self, path, svalue); nm_platform_sysctl_set (self, NMP_SYSCTL_PATHID_ABSOLUTE (path), svalue);
} }
return TRUE; return TRUE;
@@ -325,23 +328,29 @@ nm_platform_sysctl_set_ip6_hop_limit_safe (NMPlatform *self, const char *iface,
/** /**
* nm_platform_sysctl_get: * nm_platform_sysctl_get:
* @self: platform instance * @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 * @path: Absolute path to sysctl
* *
* Returns: (transfer full): Contents of the virtual sysctl file. * Returns: (transfer full): Contents of the virtual sysctl file.
*/ */
char * 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); _CHECK_SELF (self, klass, NULL);
g_return_val_if_fail (path, 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: * nm_platform_sysctl_get_int32:
* @self: platform instance * @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 * @path: Absolute path to sysctl
* @fallback: default value, if the content of path could not be read * @fallback: default value, if the content of path could not be read
* as decimal integer. * 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. * value, on success %errno will be set to zero.
*/ */
gint32 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: * nm_platform_sysctl_get_int_checked:
* @self: platform instance * @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 * @path: Absolute path to sysctl
* @base: base of numeric conversion * @base: base of numeric conversion
* @min: minimal value that is still valid * @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. * (inclusive) or @fallback.
*/ */
gint64 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; char *value = NULL;
gint32 ret; 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); g_return_val_if_fail (path, fallback);
if (path) if (path)
value = nm_platform_sysctl_get (self, path); value = nm_platform_sysctl_get (self, pathid, dirfd, path);
if (!value) { if (!value) {
errno = EINVAL; 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); 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 * 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); 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 * static const char *
@@ -2004,7 +2016,7 @@ nm_platform_link_infiniband_get_properties (NMPlatform *self,
/* Fall back to reading sysfs */ /* Fall back to reading sysfs */
path = g_strdup_printf ("/sys/class/net/%s/mode", iface); 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); g_free (path);
if (!contents) if (!contents)
return FALSE; return FALSE;
@@ -2018,7 +2030,7 @@ nm_platform_link_infiniband_get_properties (NMPlatform *self,
g_free (contents); g_free (contents);
path = g_strdup_printf ("/sys/class/net/%s/pkey", iface); 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); g_free (path);
if (!contents) if (!contents)
return FALSE; return FALSE;
@@ -2244,7 +2256,7 @@ nm_platform_link_tun_get_properties_ifname (NMPlatform *self, const char *ifname
return FALSE; return FALSE;
nm_sprintf_buf (path, "/sys/class/net/%s/owner", ifname); 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) { if (val) {
props->owner = _nm_utils_ascii_str_to_int64 (val, 10, -1, G_MAXINT64, -1); props->owner = _nm_utils_ascii_str_to_int64 (val, 10, -1, G_MAXINT64, -1);
if (errno) if (errno)
@@ -2254,7 +2266,7 @@ nm_platform_link_tun_get_properties_ifname (NMPlatform *self, const char *ifname
success = FALSE; success = FALSE;
nm_sprintf_buf (path, "/sys/class/net/%s/group", ifname); 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) { if (val) {
props->group = _nm_utils_ascii_str_to_int64 (val, 10, -1, G_MAXINT64, -1); props->group = _nm_utils_ascii_str_to_int64 (val, 10, -1, G_MAXINT64, -1);
if (errno) if (errno)
@@ -2264,7 +2276,7 @@ nm_platform_link_tun_get_properties_ifname (NMPlatform *self, const char *ifname
success = FALSE; success = FALSE;
nm_sprintf_buf (path, "/sys/class/net/%s/tun_flags", ifname); 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) { if (val) {
gint64 flags; gint64 flags;

View File

@@ -500,8 +500,8 @@ struct _NMPlatform {
typedef struct { typedef struct {
GObjectClass parent; GObjectClass parent;
gboolean (*sysctl_set) (NMPlatform *, const char *path, const char *value); gboolean (*sysctl_set) (NMPlatform *, const char *pathid, int dirfd, const char *path, const char *value);
char * (*sysctl_get) (NMPlatform *, const char *path); char * (*sysctl_get) (NMPlatform *, const char *pathid, int dirfd, const char *path);
const NMPlatformLink *(*link_get) (NMPlatform *platform, int ifindex); const NMPlatformLink *(*link_get) (NMPlatform *platform, int ifindex);
const NMPlatformLink *(*link_get_by_ifname) (NMPlatform *platform, const char *ifname); 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); 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) #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); #define NMP_SYSCTL_PATHID_ABSOLUTE(path) \
char *nm_platform_sysctl_get (NMPlatform *self, const char *path); ((const char *) NULL), -1, (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); 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); gboolean nm_platform_sysctl_set_ip6_hop_limit_safe (NMPlatform *self, const char *iface, int value);

View File

@@ -1941,7 +1941,7 @@ _test_netns_check_skip (void)
G_STMT_START { \ G_STMT_START { \
gs_free char *_val = NULL; \ 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_assert_cmpstr (_val, ==, value); \
} G_STMT_END } G_STMT_END
@@ -2013,7 +2013,7 @@ test_netns_general (gpointer fixture, gconstpointer test_data)
else else
path = "/proc/sys/net/ipv6/conf/dummy2b/disable_ipv6"; 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)); _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); _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); tmp = _get_current_namespace_id (CLONE_NEWNET);
g_ptr_array_add (device_names, tmp); g_ptr_array_add (device_names, tmp);