lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed,  7 Feb 2018 08:30:56 +0200
From:   Serhey Popovych <serhe.popovych@...il.com>
To:     netdev@...r.kernel.org
Subject: [PATCH iproute2-next v2 6/6] tuntap: Use netlink to walk through tuntap list

It seems bad idea to depend on sysfs being mounted and reflected to the
current network namespace. Same applies to procfs.

Instead netlink should be used to talk to the kernel and get list of
specific network devices among with their parameters.

Support for kernel netlink message filtering by passing IFLA_INFO_KIND
in RTM_GETLINK request: if kernel does not support filtering by the kind
we will check it in reply anyway. Check for ifi->ifi_type to be either
ARPHRD_NONE or ARPHRD_ETHER to seed up things a bit without kernel level
filtering.

Unfortunately tun driver does not implement dumping it's configuration
via netlink and we still need to use read_prop() which depends on sysfs
to get additional tun device information.

Signed-off-by: Serhey Popovych <serhe.popovych@...il.com>
---
 ip/iptuntap.c |  121 +++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 91 insertions(+), 30 deletions(-)

diff --git a/ip/iptuntap.c b/ip/iptuntap.c
index 09f2be2..4628db2 100644
--- a/ip/iptuntap.c
+++ b/ip/iptuntap.c
@@ -20,6 +20,7 @@
 #include <sys/ioctl.h>
 #include <linux/if.h>
 #include <linux/if_tun.h>
+#include <linux/if_arp.h>
 #include <pwd.h>
 #include <grp.h>
 #include <fcntl.h>
@@ -31,6 +32,8 @@
 #include "utils.h"
 #include "ip_common.h"
 
+static const char drv_name[] = "tun";
+
 #define TUNDEV "/dev/net/tun"
 
 static void usage(void) __attribute__((noreturn));
@@ -348,43 +351,101 @@ next:
 	globfree(&globbuf);
 }
 
+static int tuntap_filter_req(struct nlmsghdr *nlh, int reqlen)
+{
+	struct rtattr *linkinfo;
+	int err;
 
-static int do_show(int argc, char **argv)
+	linkinfo = addattr_nest(nlh, reqlen, IFLA_LINKINFO);
+
+	err = addattr_l(nlh, reqlen, IFLA_INFO_KIND,
+			drv_name, sizeof(drv_name) - 1);
+	if (err)
+		return err;
+
+	addattr_nest_end(nlh, linkinfo);
+
+	return 0;
+}
+
+static int print_tuntap(const struct sockaddr_nl *who,
+			struct nlmsghdr *n, void *arg)
 {
-	DIR *dir;
-	struct dirent *d;
+	struct ifinfomsg *ifi = NLMSG_DATA(n);
+	struct rtattr *tb[IFLA_MAX+1];
+	struct rtattr *linkinfo[IFLA_INFO_MAX+1];
+	const char *name, *kind;
 	long flags, owner = -1, group = -1;
 
-	dir = opendir("/sys/class/net");
-	if (!dir) {
-		perror("opendir");
+	if (n->nlmsg_type != RTM_NEWLINK && n->nlmsg_type != RTM_DELLINK)
+		return 0;
+
+	if (n->nlmsg_len < NLMSG_LENGTH(sizeof(*ifi)))
 		return -1;
+
+	switch (ifi->ifi_type) {
+	case ARPHRD_NONE:
+	case ARPHRD_ETHER:
+		break;
+	default:
+		return 0;
 	}
-	while ((d = readdir(dir))) {
-		if (d->d_name[0] == '.' &&
-		    (d->d_name[1] == 0 || d->d_name[1] == '.'))
-			continue;
-
-		if (read_prop(d->d_name, "tun_flags", &flags))
-			continue;
-
-		read_prop(d->d_name, "owner", &owner);
-		read_prop(d->d_name, "group", &group);
-
-		printf("%s:", d->d_name);
-		print_flags(flags);
-		if (owner != -1)
-			printf(" user %ld", owner);
-		if (group != -1)
-			printf(" group %ld", group);
-		printf("\n");
-		if (show_details) {
-			printf("\tAttached to processes:");
-			show_processes(d->d_name);
-			printf("\n");
-		}
+
+	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n));
+
+	if (!tb[IFLA_IFNAME])
+		return 0;
+
+	if (!tb[IFLA_LINKINFO])
+		return 0;
+
+	parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
+
+	if (!linkinfo[IFLA_INFO_KIND])
+		return 0;
+
+	kind = rta_getattr_str(linkinfo[IFLA_INFO_KIND]);
+	if (strcmp(kind, drv_name))
+		return 0;
+
+	name = rta_getattr_str(tb[IFLA_IFNAME]);
+
+	if (read_prop(name, "tun_flags", &flags))
+		return 0;
+	if (read_prop(name, "owner", &owner))
+		return 0;
+	if (read_prop(name, "group", &group))
+		return 0;
+
+	printf("%s:", name);
+	print_flags(flags);
+	if (owner != -1)
+		printf(" user %ld", owner);
+	if (group != -1)
+		printf(" group %ld", group);
+	fputc('\n', stdout);
+	if (show_details) {
+		printf("\tAttached to processes:");
+		show_processes(name);
+		fputc('\n', stdout);
 	}
-	closedir(dir);
+
+	return 0;
+}
+
+static int do_show(int argc, char **argv)
+{
+	if (rtnl_wilddump_req_filter_fn(&rth, AF_UNSPEC, RTM_GETLINK,
+					tuntap_filter_req) < 0) {
+		perror("Cannot send dump request\n");
+		return -1;
+	}
+
+	if (rtnl_dump_filter(&rth, print_tuntap, NULL) < 0) {
+		fprintf(stderr, "Dump terminated\n");
+		return -1;
+	}
+
 	return 0;
 }
 
-- 
1.7.10.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ