[lxc-devel] [lxc/master] lxc-user-nic: update

brauner on Github lxc-bot at linuxcontainers.org
Fri Apr 5 12:16:48 UTC 2019


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 364 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20190405/9adbb0ed/attachment.bin>
-------------- next part --------------
From e94104b058f3b463e6e2247af58acb9097629f1c Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Apr 2019 13:30:28 +0200
Subject: [PATCH 1/3] lxc-user-nic: small tweaks

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
Cc: Akihiro Suda <suda.akihiro at lab.ntt.co.jp>
---
 src/lxc/cmd/lxc_user_nic.c | 103 +++++++++++++++++--------------------
 1 file changed, 47 insertions(+), 56 deletions(-)

diff --git a/src/lxc/cmd/lxc_user_nic.c b/src/lxc/cmd/lxc_user_nic.c
index 27100d2481..61a0aec7cc 100644
--- a/src/lxc/cmd/lxc_user_nic.c
+++ b/src/lxc/cmd/lxc_user_nic.c
@@ -47,6 +47,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include "compiler.h"
 #include "config.h"
 #include "log.h"
 #include "memory_utils.h"
@@ -69,13 +70,17 @@
 
 #define usernic_error(format, ...) usernic_debug_stream(stderr, format, __VA_ARGS__)
 
-static void usage(char *me, bool fail)
+__noreturn static void usage(bool fail)
 {
-	fprintf(stderr, "Usage: %s create {lxcpath} {name} {pid} {type} "
-			"{bridge} {nicname}\n", me);
-	fprintf(stderr, "Usage: %s delete {lxcpath} {name} "
-			"{/proc/<pid>/ns/net} {type} {bridge} {nicname}\n", me);
-	fprintf(stderr, "{nicname} is the name to use inside the container\n");
+	fprintf(stderr, "Description:\n");
+	fprintf(stderr, "  Manage nics in another network namespace\n\n");
+
+	fprintf(stderr, "Usage:\n");
+	fprintf(stderr, "  lxc-user-nic [command]\n\n");
+
+	fprintf(stderr, "Available Commands:\n");
+	fprintf(stderr, "  create {lxcpath} {name} {pid} {type} {bridge} {container nicname}\n");
+	fprintf(stderr, "  delete {lxcpath} {name} {/proc/<pid>/ns/net} {type} {bridge} {container nicname}\n");
 
 	if (fail)
 		_exit(EXIT_FAILURE);
@@ -83,9 +88,10 @@ static void usage(char *me, bool fail)
 	_exit(EXIT_SUCCESS);
 }
 
-static int open_and_lock(char *path)
+static int open_and_lock(const char *path)
 {
-	int fd, ret;
+	__do_close_prot_errno int fd = -EBADF;
+	int ret;
 	struct flock lk;
 
 	fd = open(path, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR);
@@ -102,11 +108,10 @@ static int open_and_lock(char *path)
 	ret = fcntl(fd, F_SETLKW, &lk);
 	if (ret < 0) {
 		CMD_SYSERROR("Failed to lock \"%s\"\n", path);
-		close(fd);
 		return -1;
 	}
 
-	return fd;
+	return move_fd(fd);
 }
 
 static char *get_username(void)
@@ -881,16 +886,15 @@ static char *lxc_secure_rename_in_ns(int pid, char *oldname, char *newname,
 	close(fd);
 	fd = -1;
 	if (ret < 0) {
-		CMD_SYSERROR("Failed to setns() to the network namespace of "
-		             "the container with PID %d\n", pid);
+		CMD_SYSERROR("Failed to setns() to the network namespace of the container with PID %d\n",
+			     pid);
 		goto do_partial_cleanup;
 	}
 
 	ret = setresuid(ruid, ruid, 0);
 	if (ret < 0) {
-		CMD_SYSERROR("Failed to drop privilege by setting effective "
-		             "user id and real user id to %d, and saved user "
-		             "ID to 0\n", ruid);
+		CMD_SYSERROR("Failed to drop privilege by setting effective user id and real user id to %d, and saved user ID to 0\n",
+			     ruid);
 		/* It's ok to jump to do_full_cleanup here since setresuid()
 		 * will succeed when trying to set real, effective, and saved to
 		 * values they currently have.
@@ -936,18 +940,15 @@ static char *lxc_secure_rename_in_ns(int pid, char *oldname, char *newname,
 do_full_cleanup:
 	ret = setresuid(ruid, euid, suid);
 	if (ret < 0) {
-		CMD_SYSERROR("Failed to restore privilege by setting "
-		             "effective user id to %d, real user id to %d, "
-		             "and saved user ID to %d\n", ruid, euid, suid);
+		CMD_SYSERROR("Failed to restore privilege by setting effective user id to %d, real user id to %d, and saved user ID to %d\n",
+			     ruid, euid, suid);
 
 		string_ret = NULL;
 	}
 
 	ret = setns(ofd, CLONE_NEWNET);
 	if (ret < 0) {
-		CMD_SYSERROR("Failed to setns() to original network namespace "
-		             "of PID %d\n", ofd);
-
+		CMD_SYSERROR("Failed to setns() to original network namespace of PID %d\n", ofd);
 		string_ret = NULL;
 	}
 
@@ -981,9 +982,8 @@ static bool may_access_netns(int pid)
 
 	ret = setresuid(ruid, ruid, euid);
 	if (ret < 0) {
-		CMD_SYSERROR("Failed to drop privilege by setting effective "
-		             "user id and real user id to %d, and saved user "
-		             "ID to %d\n", ruid, euid);
+		CMD_SYSERROR("Failed to drop privilege by setting effective user id and real user id to %d, and saved user ID to %d\n",
+			     ruid, euid);
 		return false;
 	}
 
@@ -1000,8 +1000,8 @@ static bool may_access_netns(int pid)
 
 	ret = setresuid(ruid, euid, suid);
 	if (ret < 0) {
-		CMD_SYSERROR("Failed to restore user id to %d, real user id "
-		             "to %d, and saved user ID to %d\n", ruid, euid, suid);
+		CMD_SYSERROR("Failed to restore user id to %d, real user id to %d, and saved user ID to %d\n",
+			     ruid, euid, suid);
 		may_access = false;
 	}
 
@@ -1018,8 +1018,10 @@ struct user_nic_args {
 	char *veth_name;
 };
 
-#define LXC_USERNIC_CREATE 0
-#define LXC_USERNIC_DELETE 1
+enum lxc_user_nic_command {
+	LXC_USERNIC_CREATE = 0,
+	LXC_USERNIC_DELETE = 1,
+};
 
 static bool is_privileged_over_netns(int netns_fd)
 {
@@ -1050,9 +1052,8 @@ static bool is_privileged_over_netns(int netns_fd)
 
 	ret = setresuid(ruid, ruid, 0);
 	if (ret < 0) {
-		CMD_SYSERROR("Failed to drop privilege by setting effective "
-		             "user id and real user id to %d, and saved user "
-		             "ID to 0\n", ruid);
+		CMD_SYSERROR("Failed to drop privilege by setting effective user id and real user id to %d, and saved user ID to 0\n",
+			     ruid);
 		/* It's ok to jump to do_full_cleanup here since setresuid()
 		 * will succeed when trying to set real, effective, and saved to
 		 * values they currently have.
@@ -1072,16 +1073,15 @@ static bool is_privileged_over_netns(int netns_fd)
 do_full_cleanup:
 	ret = setresuid(ruid, euid, suid);
 	if (ret < 0) {
-		CMD_SYSERROR("Failed to restore privilege by setting "
-		             "effective user id to %d, real user id to %d, "
-		             "and saved user ID to %d\n", ruid, euid, suid);
+		CMD_SYSERROR("Failed to restore privilege by setting effective user id to %d, real user id to %d, and saved user ID to %d\n",
+			     ruid, euid, suid);
 		bret = false;
 	}
 
 	ret = setns(ofd, CLONE_NEWNET);
 	if (ret < 0) {
-		CMD_SYSERROR("Failed to setns() to original network namespace "
-		             "of PID %d\n", ofd);
+		CMD_SYSERROR("Failed to setns() to original network namespace of PID %d\n",
+			     ofd);
 		bret = false;
 	}
 
@@ -1099,10 +1099,8 @@ int main(int argc, char *argv[])
 	char *cnic = NULL;
 	struct alloted_s *alloted = NULL;
 
-	if (argc < 7 || argc > 8) {
-		usage(argv[0], true);
-		_exit(EXIT_FAILURE);
-	}
+	if (argc < 7 || argc > 8)
+		usage(true);
 
 	memset(&args, 0, sizeof(struct user_nic_args));
 
@@ -1112,17 +1110,15 @@ int main(int argc, char *argv[])
 	args.pid = argv[4];
 	args.type = argv[5];
 	args.link = argv[6];
-	if (argc >= 8)
+	if (argc == 8)
 		args.veth_name = argv[7];
 
-	if (!strcmp(args.cmd, "create")) {
+	if (!strcmp(args.cmd, "create"))
 		request = LXC_USERNIC_CREATE;
-	} else if (!strcmp(args.cmd, "delete")) {
+	else if (!strcmp(args.cmd, "delete"))
 		request = LXC_USERNIC_DELETE;
-	} else {
-		usage(argv[0], true);
-		_exit(EXIT_FAILURE);
-	}
+	else
+		usage(true);
 
 	/* Set a sane env, because we are setuid-root. */
 	ret = clearenv();
@@ -1218,8 +1214,7 @@ int main(int argc, char *argv[])
 		has_priv = is_privileged_over_netns(netns_fd);
 		close(netns_fd);
 		if (!has_priv) {
-			usernic_error("%s", "Process is not privileged over "
-				      "network namespace\n");
+			usernic_error("%s", "Process is not privileged over network namespace\n");
 			_exit(EXIT_FAILURE);
 		}
 	}
@@ -1231,8 +1226,7 @@ int main(int argc, char *argv[])
 		bool found_nicname = false;
 
 		if (!is_ovs_bridge(args.link)) {
-			usernic_error("%s", "Deletion of non ovs type network "
-				      "devices not implemented\n");
+			usernic_error("%s", "Deletion of non ovs type network devices not implemented\n");
 			close(fd);
 			free_alloted(&alloted);
 			_exit(EXIT_FAILURE);
@@ -1251,16 +1245,13 @@ int main(int argc, char *argv[])
 		free_alloted(&alloted);
 
 		if (!found_nicname) {
-			usernic_error("Caller is not allowed to delete network "
-				      "device \"%s\"\n", args.veth_name);
+			usernic_error("Caller is not allowed to delete network device \"%s\"\n", args.veth_name);
 			_exit(EXIT_FAILURE);
 		}
 
 		ret = lxc_ovs_delete_port(args.link, args.veth_name);
 		if (ret < 0) {
-			usernic_error("Failed to remove port \"%s\" from "
-				      "openvswitch bridge \"%s\"",
-				      args.veth_name, args.link);
+			usernic_error("Failed to remove port \"%s\" from openvswitch bridge \"%s\"", args.veth_name, args.link);
 			_exit(EXIT_FAILURE);
 		}
 

From db74bbd0039656473eb7426d37ed3c541ea5e30b Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Apr 2019 14:01:12 +0200
Subject: [PATCH 2/3] doc: update lxc-user-nic manpage

Closes #1823.

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
Cc: Akihiro Suda <suda.akihiro at lab.ntt.co.jp>
---
 doc/lxc-user-nic.sgml.in | 65 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 59 insertions(+), 6 deletions(-)

diff --git a/doc/lxc-user-nic.sgml.in b/doc/lxc-user-nic.sgml.in
index ac8af64e81..18e9b22cc3 100644
--- a/doc/lxc-user-nic.sgml.in
+++ b/doc/lxc-user-nic.sgml.in
@@ -42,17 +42,31 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     <refname>lxc-user-nic</refname>
 
     <refpurpose>
-      Create and attach a nic to another network namespace.
+      Manage nics in another network namespace
     </refpurpose>
   </refnamediv>
 
   <refsynopsisdiv>
     <cmdsynopsis>
       <command>lxc-user-nic</command>
+      <command>create</command>
+      <arg choice="req"><replaceable>lxcpath</replaceable></arg>
+      <arg choice="req"><replaceable>name</replaceable></arg>
       <arg choice="req"><replaceable>pid</replaceable></arg>
       <arg choice="req"><replaceable>type</replaceable></arg>
       <arg choice="req"><replaceable>bridge</replaceable></arg>
-      <arg choice="opt"><replaceable>nicname</replaceable></arg>
+      <arg choice="req"><replaceable>container nicname</replaceable></arg>
+    </cmdsynopsis>
+
+    <cmdsynopsis>
+      <command>lxc-user-nic</command>
+      <command>delete</command>
+      <arg choice="req"><replaceable>lxcpath</replaceable></arg>
+      <arg choice="req"><replaceable>name</replaceable></arg>
+      <arg choice="req"><replaceable>path to network namespace</replaceable></arg>
+      <arg choice="req"><replaceable>type</replaceable></arg>
+      <arg choice="req"><replaceable>bridge</replaceable></arg>
+      <arg choice="req"><replaceable>container nicname</replaceable></arg>
     </cmdsynopsis>
   </refsynopsisdiv>
 
@@ -61,7 +75,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
     <para>
       <command>lxc-user-nic</command> is a setuid-root program with which
-      unprivileged users may create network interfaces for use by a lxc container.
+      unprivileged users may manage network interfaces for use by a
+      lxc container.
     </para>
     <para>
       It will consult the configuration file <filename>@LXC_USERNIC_CONF@</filename>
@@ -71,6 +86,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
       <filename>@LXC_USERNIC_DB@</filename>.  It ensures that the calling
       user is privileged over the network namespace to which the interface
       will be attached.
+      <command>lxc-user-nic</command> also allows to delete network devices.
+      Currently only ovs ports can be deleted.
     </para>
 
   </refsect1>
@@ -80,6 +97,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     <title>Options</title>
 
     <variablelist>
+      <varlistentry>
+	<term>
+	  <option><replaceable>lxcpath</replaceable></option>
+	</term>
+	<listitem>
+	  <para>
+	  The path of the container. This is currently not used.
+	  </para>
+	</listitem>
+      </varlistentry>
+
+      <varlistentry>
+	<term>
+	  <option><replaceable>name</replaceable></option>
+	</term>
+	<listitem>
+	  <para>
+	  The name of the container. This is currently not used.
+	  </para>
+	</listitem>
+      </varlistentry>
 
       <varlistentry>
 	<term>
@@ -99,7 +137,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 	</term>
 	<listitem>
 	  <para>
-	  The network interface type to attach.  Currently only veth is
+	  The network interface type to attach. Currently only veth is
 	  supported.  With this type, two interfaces representing each
 	  tunnel endpoint are created.  One endpoint will be attached
 	  to the specified bridge, while the other will be passed into
@@ -122,16 +160,29 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
       <varlistentry>
 	<term>
-	  <option><replaceable>nicname</replaceable></option>
+	  <option><replaceable>container nicname</replaceable></option>
 	</term>
 	<listitem>
 	  <para>
-	  The desired interface name in the container.  This will be
+	  The desired interface name in the container. This will be
 	  <filename>eth0</filename> if unspecified.
 	  </para>
 	</listitem>
       </varlistentry>
 
+      <varlistentry>
+	<term>
+	  <option><replaceable>path to network namespace</replaceable></option>
+	</term>
+	<listitem>
+	  <para>
+	  A path to open to get a file descriptor for the target
+	  network namespace.
+	  This is only relevant when an veth device is deleted.
+	  </para>
+	</listitem>
+      </varlistentry>
+
     </variablelist>
 
   </refsect1>
@@ -159,6 +210,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
   <refsect1>
     <title>Author</title>
+    <para>Christian Brauner <email>christian at brauner.io</email></para>
+    <para>Serge Hallyn <email>serge at hallyn.com</email></para>
     <para>Daniel Lezcano <email>daniel.lezcano at free.fr</email></para>
   </refsect1>
 

From ff63fd780d0e080ee38bc2b9b7e73789e9e24ad4 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Fri, 5 Apr 2019 14:11:43 +0200
Subject: [PATCH 3/3] lxc-user-nic: validate request

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
Cc: Akihiro Suda <suda.akihiro at lab.ntt.co.jp>
---
 src/lxc/cmd/lxc_user_nic.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/lxc/cmd/lxc_user_nic.c b/src/lxc/cmd/lxc_user_nic.c
index 61a0aec7cc..284b22ed22 100644
--- a/src/lxc/cmd/lxc_user_nic.c
+++ b/src/lxc/cmd/lxc_user_nic.c
@@ -1090,6 +1090,18 @@ static bool is_privileged_over_netns(int netns_fd)
 	return bret;
 }
 
+static inline int validate_args(const struct user_nic_args *args, int argc)
+{
+	int request = -EINVAL;
+
+	if (!strcmp(args->cmd, "create"))
+		request = LXC_USERNIC_CREATE;
+	else if (!strcmp(args->cmd, "delete"))
+		request = LXC_USERNIC_DELETE;
+
+	return request;
+}
+
 int main(int argc, char *argv[])
 {
 	__do_free char *me = NULL, *newname = NULL, *nicname = NULL;
@@ -1113,11 +1125,8 @@ int main(int argc, char *argv[])
 	if (argc == 8)
 		args.veth_name = argv[7];
 
-	if (!strcmp(args.cmd, "create"))
-		request = LXC_USERNIC_CREATE;
-	else if (!strcmp(args.cmd, "delete"))
-		request = LXC_USERNIC_DELETE;
-	else
+	request = validate_args(&args, argc);
+	if (request < 0)
 		usage(true);
 
 	/* Set a sane env, because we are setuid-root. */


More information about the lxc-devel mailing list